From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 7E9A6A04B5; Thu, 10 Sep 2020 08:52:27 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 50C3C1C0D2; Thu, 10 Sep 2020 08:52:27 +0200 (CEST) Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by dpdk.org (Postfix) with ESMTP id E4EF21C0D0 for ; Thu, 10 Sep 2020 08:52:24 +0200 (CEST) IronPort-SDR: AZv0p4b0XWJJgCTAC9wzO7+Nt6472nVjMsBS1Qphm/7nWR8qKi06JQGBBzcPghPVQKlEVDXUw5 OqIMUJzEuuVQ== X-IronPort-AV: E=McAfee;i="6000,8403,9739"; a="155878248" X-IronPort-AV: E=Sophos;i="5.76,412,1592895600"; d="scan'208";a="155878248" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 09 Sep 2020 23:52:23 -0700 IronPort-SDR: vS9xjReY0fxNE8ICVBE7UMrmdGNe3ZHsCU/xbMBApzUuzKRlAiqnflPr3JcMzbDN6L/bVJZL53 iPM/uIZ/1BBQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.76,412,1592895600"; d="scan'208";a="480771969" Received: from dpdk_jiangcheng.sh.intel.com ([10.67.119.112]) by orsmga005.jf.intel.com with ESMTP; 09 Sep 2020 23:52:21 -0700 From: Cheng Jiang To: maxime.coquelin@redhat.com, chenbo.xia@intel.com, zhihong.wang@intel.com, john.mcnamara@intel.com, marko.kovacevic@intel.com Cc: dev@dpdk.org, patrick.fu@intel.com, Cheng Jiang Date: Thu, 10 Sep 2020 06:43:49 +0000 Message-Id: <20200910064351.35513-3-Cheng1.jiang@intel.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200910064351.35513-1-Cheng1.jiang@intel.com> References: <20200910064351.35513-1-Cheng1.jiang@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: [dpdk-dev] [PATCH v1 2/4] example/vhost: add support for vhost async data path X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" This patch is to implement vhost DMA operation callbacks for CBDMA PMD and add vhost async data-path in vhost sample. With providing callback implementation for CBDMA, vhost sample can leverage CBDMA to accelerate vhost async data-path. Signed-off-by: Cheng Jiang --- examples/vhost/main.c | 129 ++++++++++++++++++++++++++++++++++++++++-- examples/vhost/main.h | 1 + 2 files changed, 124 insertions(+), 6 deletions(-) diff --git a/examples/vhost/main.c b/examples/vhost/main.c index 011e3da21..b2a4e4370 100644 --- a/examples/vhost/main.c +++ b/examples/vhost/main.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -31,7 +32,7 @@ #include "main.h" #ifndef MAX_QUEUES -#define MAX_QUEUES 128 +#define MAX_QUEUES 512 #endif /* the maximum number of external ports supported */ @@ -165,6 +166,62 @@ static struct rte_eth_conf vmdq_conf_default = { }, }; +static uint32_t +ioat_transfer_data_cb(int vid, uint16_t queue_id, + struct rte_vhost_async_desc *descs, + struct rte_vhost_async_status *opaque_data, uint16_t count) +{ + int ret; + uint32_t i_desc; + + struct rte_vhost_iov_iter *src = NULL; + struct rte_vhost_iov_iter *dst = NULL; + unsigned long i_seg; + + int dev_id = dma_bind[vid].dmas[queue_id * 2 + VIRTIO_RXQ].dev_id; + if (likely(!opaque_data)) { + for (i_desc = 0; i_desc < count; i_desc++) { + src = descs[i_desc].src; + dst = descs[i_desc].dst; + i_seg = 0; + while (i_seg < src->nr_segs) { + ret = rte_ioat_enqueue_copy(dev_id, + (uintptr_t)(src->iov[i_seg].iov_base) + + src->offset, + (uintptr_t)(dst->iov[i_seg].iov_base) + + dst->offset, + src->iov[i_seg].iov_len, + 0, + 0, + 0); + if (ret != 1) + break; + i_seg++; + } + } + } else { + /* Opaque data is not supported */ + return -1; + } + /* ring the doorbell */ + rte_ioat_do_copies(dev_id); + return i_desc; +} + +static uint32_t +ioat_check_completed_copies_cb(int vid, uint16_t queue_id, + struct rte_vhost_async_status *opaque_data, + uint16_t max_packets __rte_unused) +{ + if (!opaque_data) { + uintptr_t dump[255]; + return rte_ioat_completed_copies(dma_bind[vid].dmas[queue_id * 2 + + VIRTIO_RXQ].dev_id, 255, dump, dump); + } else { + /* Opaque data is not supported */ + return -1; + } +} static unsigned lcore_ids[RTE_MAX_LCORE]; static uint16_t ports[RTE_MAX_ETHPORTS]; @@ -206,6 +263,11 @@ struct mbuf_table lcore_tx_queue[RTE_MAX_LCORE]; / US_PER_S * BURST_TX_DRAIN_US) #define VLAN_HLEN 4 +/* + * Builds up the correct configuration for VMDQ VLAN pool map + * according to the pool & queue limits. + */ + static inline int open_dma(const char *value, void *dma_bind_info) { @@ -297,10 +359,6 @@ open_dma(const char *value, void *dma_bind_info) return ret; } -/* - * Builds up the correct configuration for VMDQ VLAN pool map - * according to the pool & queue limits. - */ static inline int get_eth_conf(struct rte_eth_conf *eth_conf, uint32_t num_devices) { @@ -911,9 +969,26 @@ virtio_xmit(struct vhost_dev *dst_vdev, struct vhost_dev *src_vdev, struct rte_mbuf *m) { uint16_t ret; + struct rte_mbuf *m_cpl[1]; if (builtin_net_driver) { ret = vs_enqueue_pkts(dst_vdev, VIRTIO_RXQ, &m, 1); + } else if (async_vhost_driver) { + ret = rte_vhost_submit_enqueue_burst(dst_vdev->vid, VIRTIO_RXQ, + &m, 1); + + if (likely(ret)) { + dst_vdev->nr_async_pkts++; + rte_mbuf_refcnt_update(m, 1); + } + + while (likely(dst_vdev->nr_async_pkts)) { + if (rte_vhost_poll_enqueue_completed(dst_vdev->vid, + VIRTIO_RXQ, m_cpl, 1)) { + dst_vdev->nr_async_pkts--; + rte_pktmbuf_free(*m_cpl); + } + } } else { ret = rte_vhost_enqueue_burst(dst_vdev->vid, VIRTIO_RXQ, &m, 1); } @@ -1162,6 +1237,19 @@ drain_mbuf_table(struct mbuf_table *tx_q) } } +static __rte_always_inline void +complete_async_pkts(struct vhost_dev *vdev, uint16_t qid) +{ + struct rte_mbuf *p_cpl[MAX_PKT_BURST]; + uint16_t complete_count; + + complete_count = rte_vhost_poll_enqueue_completed(vdev->vid, + qid, p_cpl, MAX_PKT_BURST); + vdev->nr_async_pkts -= complete_count; + if (complete_count) + free_pkts(p_cpl, complete_count); +} + static __rte_always_inline void drain_eth_rx(struct vhost_dev *vdev) { @@ -1170,6 +1258,10 @@ drain_eth_rx(struct vhost_dev *vdev) rx_count = rte_eth_rx_burst(ports[0], vdev->vmdq_rx_q, pkts, MAX_PKT_BURST); + + while (likely(vdev->nr_async_pkts)) + complete_async_pkts(vdev, VIRTIO_RXQ); + if (!rx_count) return; @@ -1194,16 +1286,22 @@ drain_eth_rx(struct vhost_dev *vdev) if (builtin_net_driver) { enqueue_count = vs_enqueue_pkts(vdev, VIRTIO_RXQ, pkts, rx_count); + } else if (async_vhost_driver) { + enqueue_count = rte_vhost_submit_enqueue_burst(vdev->vid, + VIRTIO_RXQ, pkts, rx_count); + vdev->nr_async_pkts += enqueue_count; } else { enqueue_count = rte_vhost_enqueue_burst(vdev->vid, VIRTIO_RXQ, pkts, rx_count); } + if (enable_stats) { rte_atomic64_add(&vdev->stats.rx_total_atomic, rx_count); rte_atomic64_add(&vdev->stats.rx_atomic, enqueue_count); } - free_pkts(pkts, rx_count); + if (!async_vhost_driver) + free_pkts(pkts, rx_count); } static __rte_always_inline void @@ -1350,6 +1448,9 @@ destroy_device(int vid) "(%d) device has been removed from data core\n", vdev->vid); + if (async_vhost_driver) + rte_vhost_async_channel_unregister(vid, VIRTIO_RXQ); + rte_free(vdev); } @@ -1364,6 +1465,12 @@ new_device(int vid) uint32_t device_num_min = num_devices; struct vhost_dev *vdev; + struct rte_vhost_async_channel_ops channel_ops = { + .transfer_data = ioat_transfer_data_cb, + .check_completed_copies = ioat_check_completed_copies_cb + }; + struct rte_vhost_async_features f; + vdev = rte_zmalloc("vhost device", sizeof(*vdev), RTE_CACHE_LINE_SIZE); if (vdev == NULL) { RTE_LOG(INFO, VHOST_DATA, @@ -1404,6 +1511,13 @@ new_device(int vid) "(%d) device has been added to data core %d\n", vid, vdev->coreid); + if (async_vhost_driver) { + f.async_inorder = 1; + f.async_threshold = 256; + return rte_vhost_async_channel_register(vid, VIRTIO_RXQ, + f.intval, &channel_ops); + } + return 0; } @@ -1645,6 +1759,9 @@ main(int argc, char *argv[]) /* Register vhost user driver to handle vhost messages. */ for (i = 0; i < nb_sockets; i++) { char *file = socket_files + i * PATH_MAX; + if (async_vhost_driver) + flags = flags | RTE_VHOST_USER_ASYNC_COPY; + ret = rte_vhost_driver_register(file, flags); if (ret != 0) { unregister_drivers(i); diff --git a/examples/vhost/main.h b/examples/vhost/main.h index 7cba0edbf..4317b6ae8 100644 --- a/examples/vhost/main.h +++ b/examples/vhost/main.h @@ -51,6 +51,7 @@ struct vhost_dev { uint64_t features; size_t hdr_len; uint16_t nr_vrings; + uint16_t nr_async_pkts; struct rte_vhost_memory *mem; struct device_statistics stats; TAILQ_ENTRY(vhost_dev) global_vdev_entry; -- 2.27.0