From patchwork Mon Jul 5 08:40:25 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Ding, Xuan" X-Patchwork-Id: 95278 X-Patchwork-Delegate: maxime.coquelin@redhat.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 3A356A0A0C; Mon, 5 Jul 2021 10:47:30 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 10FA841172; Mon, 5 Jul 2021 10:47:27 +0200 (CEST) Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by mails.dpdk.org (Postfix) with ESMTP id 335984003C for ; Mon, 5 Jul 2021 10:47:23 +0200 (CEST) X-IronPort-AV: E=McAfee;i="6200,9189,10035"; a="270069219" X-IronPort-AV: E=Sophos;i="5.83,325,1616482800"; d="scan'208";a="270069219" Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jul 2021 01:47:21 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.83,325,1616482800"; d="scan'208";a="496049967" Received: from dpdk-xuanding-dev2.sh.intel.com ([10.67.119.115]) by fmsmga002.fm.intel.com with ESMTP; 05 Jul 2021 01:47:11 -0700 From: Xuan Ding To: maxime.coquelin@redhat.com, chenbo.xia@intel.com Cc: dev@dpdk.org, jiayu.hu@intel.com, sunil.pai.g@intel.com, bruce.richardson@intel.com, harry.van.haaren@intel.com, yong.liu@intel.com, wenwux.ma@intel.com, Xuan Ding Date: Mon, 5 Jul 2021 08:40:25 +0000 Message-Id: <20210705084026.99898-2-xuan.ding@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210705084026.99898-1-xuan.ding@intel.com> References: <20210531150629.35020-1-xuan.ding@intel.com> <20210705084026.99898-1-xuan.ding@intel.com> Subject: [dpdk-dev] [PATCH v5 1/2] vhost: enable IOMMU for async vhost X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 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" The use of IOMMU has many advantages, such as isolation and address translation. This patch extends the capbility of DMA engine to use IOMMU if the DMA device is bound to vfio. When set memory table, the guest memory will be mapped into the default container of DPDK. Signed-off-by: Xuan Ding --- doc/guides/prog_guide/vhost_lib.rst | 9 ++++++ lib/vhost/rte_vhost.h | 1 + lib/vhost/socket.c | 9 ++++++ lib/vhost/vhost.h | 1 + lib/vhost/vhost_user.c | 46 ++++++++++++++++++++++++++++- 5 files changed, 65 insertions(+), 1 deletion(-) diff --git a/doc/guides/prog_guide/vhost_lib.rst b/doc/guides/prog_guide/vhost_lib.rst index 05c42c9b11..c3beda23d9 100644 --- a/doc/guides/prog_guide/vhost_lib.rst +++ b/doc/guides/prog_guide/vhost_lib.rst @@ -118,6 +118,15 @@ The following is an overview of some key Vhost API functions: It is disabled by default. + - ``RTE_VHOST_USER_ASYNC_USE_VFIO`` + + In asynchronous data path, vhost liarary is not aware of which driver + (igb_uio/vfio) the DMA device is bound to. Application should pass + this flag to tell vhost library whether IOMMU should be programmed + for guest memory. + + It is disabled by default. + - ``RTE_VHOST_USER_NET_COMPLIANT_OL_FLAGS`` Since v16.04, the vhost library forwards checksum and gso requests for diff --git a/lib/vhost/rte_vhost.h b/lib/vhost/rte_vhost.h index 8d875e9322..a766ea7b6b 100644 --- a/lib/vhost/rte_vhost.h +++ b/lib/vhost/rte_vhost.h @@ -37,6 +37,7 @@ extern "C" { #define RTE_VHOST_USER_LINEARBUF_SUPPORT (1ULL << 6) #define RTE_VHOST_USER_ASYNC_COPY (1ULL << 7) #define RTE_VHOST_USER_NET_COMPLIANT_OL_FLAGS (1ULL << 8) +#define RTE_VHOST_USER_ASYNC_USE_VFIO (1ULL << 9) /* Features. */ #ifndef VIRTIO_NET_F_GUEST_ANNOUNCE diff --git a/lib/vhost/socket.c b/lib/vhost/socket.c index 5d0d728d52..77c722c86b 100644 --- a/lib/vhost/socket.c +++ b/lib/vhost/socket.c @@ -42,6 +42,7 @@ struct vhost_user_socket { bool extbuf; bool linearbuf; bool async_copy; + bool async_use_vfio; bool net_compliant_ol_flags; /* @@ -243,6 +244,13 @@ vhost_user_add_connection(int fd, struct vhost_user_socket *vsocket) dev->async_copy = 1; } + if (vsocket->async_use_vfio) { + dev = get_device(vid); + + if (dev) + dev->async_use_vfio = 1; + } + VHOST_LOG_CONFIG(INFO, "new device, handle is %d\n", vid); if (vsocket->notify_ops->new_connection) { @@ -879,6 +887,7 @@ rte_vhost_driver_register(const char *path, uint64_t flags) vsocket->extbuf = flags & RTE_VHOST_USER_EXTBUF_SUPPORT; vsocket->linearbuf = flags & RTE_VHOST_USER_LINEARBUF_SUPPORT; vsocket->async_copy = flags & RTE_VHOST_USER_ASYNC_COPY; + vsocket->async_use_vfio = flags & RTE_VHOST_USER_ASYNC_USE_VFIO; vsocket->net_compliant_ol_flags = flags & RTE_VHOST_USER_NET_COMPLIANT_OL_FLAGS; if (vsocket->async_copy && diff --git a/lib/vhost/vhost.h b/lib/vhost/vhost.h index 8078ddff79..fb775ce4ed 100644 --- a/lib/vhost/vhost.h +++ b/lib/vhost/vhost.h @@ -370,6 +370,7 @@ struct virtio_net { int16_t broadcast_rarp; uint32_t nr_vring; int async_copy; + int async_use_vfio; int extbuf; int linearbuf; struct vhost_virtqueue *virtqueue[VHOST_MAX_QUEUE_PAIRS * 2]; diff --git a/lib/vhost/vhost_user.c b/lib/vhost/vhost_user.c index 8f0eba6412..f3703f2e72 100644 --- a/lib/vhost/vhost_user.c +++ b/lib/vhost/vhost_user.c @@ -45,6 +45,7 @@ #include #include #include +#include #include "iotlb.h" #include "vhost.h" @@ -141,6 +142,36 @@ get_blk_size(int fd) return ret == -1 ? (uint64_t)-1 : (uint64_t)stat.st_blksize; } +static int +async_dma_map(struct rte_vhost_mem_region *region, bool do_map) +{ + int ret = 0; + uint64_t host_iova; + host_iova = rte_mem_virt2iova((void *)(uintptr_t)region->host_user_addr); + if (do_map) { + /* Add mapped region into the default container of DPDK. */ + ret = rte_vfio_container_dma_map(RTE_VFIO_DEFAULT_CONTAINER_FD, + region->host_user_addr, + host_iova, + region->size); + if (ret) { + VHOST_LOG_CONFIG(ERR, "DMA engine map failed\n"); + return ret; + } + } else { + /* Remove mapped region from the default container of DPDK. */ + ret = rte_vfio_container_dma_unmap(RTE_VFIO_DEFAULT_CONTAINER_FD, + region->host_user_addr, + host_iova, + region->size); + if (ret) { + VHOST_LOG_CONFIG(ERR, "DMA engine unmap failed\n"); + return ret; + } + } + return ret; +} + static void free_mem_region(struct virtio_net *dev) { @@ -153,6 +184,9 @@ free_mem_region(struct virtio_net *dev) for (i = 0; i < dev->mem->nregions; i++) { reg = &dev->mem->regions[i]; if (reg->host_user_addr) { + if (dev->async_copy && dev->async_use_vfio) + async_dma_map(reg, false); + munmap(reg->mmap_addr, reg->mmap_size); close(reg->fd); } @@ -1105,6 +1139,7 @@ vhost_user_mmap_region(struct virtio_net *dev, uint64_t mmap_size; uint64_t alignment; int populate; + int ret; /* Check for memory_size + mmap_offset overflow */ if (mmap_offset >= -region->size) { @@ -1158,13 +1193,22 @@ vhost_user_mmap_region(struct virtio_net *dev, region->mmap_size = mmap_size; region->host_user_addr = (uint64_t)(uintptr_t)mmap_addr + mmap_offset; - if (dev->async_copy) + if (dev->async_copy) { if (add_guest_pages(dev, region, alignment) < 0) { VHOST_LOG_CONFIG(ERR, "adding guest pages to region failed.\n"); return -1; } + if (dev->async_use_vfio) { + ret = async_dma_map(region, true); + if (ret) { + VHOST_LOG_CONFIG(ERR, "Configure IOMMU for DMA engine failed\n"); + return -1; + } + } + } + VHOST_LOG_CONFIG(INFO, "guest memory region size: 0x%" PRIx64 "\n" "\t guest physical addr: 0x%" PRIx64 "\n" From patchwork Mon Jul 5 08:40:26 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Ding, Xuan" X-Patchwork-Id: 95279 X-Patchwork-Delegate: maxime.coquelin@redhat.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 891F3A0A0C; Mon, 5 Jul 2021 10:47:35 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 3EC894117A; Mon, 5 Jul 2021 10:47:28 +0200 (CEST) Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by mails.dpdk.org (Postfix) with ESMTP id 610254116F for ; Mon, 5 Jul 2021 10:47:25 +0200 (CEST) X-IronPort-AV: E=McAfee;i="6200,9189,10035"; a="270069222" X-IronPort-AV: E=Sophos;i="5.83,325,1616482800"; d="scan'208";a="270069222" Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jul 2021 01:47:24 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.83,325,1616482800"; d="scan'208";a="496049987" Received: from dpdk-xuanding-dev2.sh.intel.com ([10.67.119.115]) by fmsmga002.fm.intel.com with ESMTP; 05 Jul 2021 01:47:22 -0700 From: Xuan Ding To: maxime.coquelin@redhat.com, chenbo.xia@intel.com Cc: dev@dpdk.org, jiayu.hu@intel.com, sunil.pai.g@intel.com, bruce.richardson@intel.com, harry.van.haaren@intel.com, yong.liu@intel.com, wenwux.ma@intel.com, Xuan Ding Date: Mon, 5 Jul 2021 08:40:26 +0000 Message-Id: <20210705084026.99898-3-xuan.ding@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210705084026.99898-1-xuan.ding@intel.com> References: <20210531150629.35020-1-xuan.ding@intel.com> <20210705084026.99898-1-xuan.ding@intel.com> Subject: [dpdk-dev] [PATCH v5 2/2] example/vhost: add dma vfio parsing X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 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 adds the dma-vfio argument parsing for async vhost driver. This argument can help to determine whether IOMMU needs to be programmed for guest memory. Signed-off-by: Xuan Ding --- doc/guides/sample_app_ug/vhost.rst | 7 +++++++ examples/vhost/main.c | 16 +++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/doc/guides/sample_app_ug/vhost.rst b/doc/guides/sample_app_ug/vhost.rst index 63dcf181e1..c54aebc504 100644 --- a/doc/guides/sample_app_ug/vhost.rst +++ b/doc/guides/sample_app_ug/vhost.rst @@ -176,6 +176,13 @@ operation. The index of the device corresponds to the socket file in order, that means vhost device 0 is created through the first socket file, vhost device 1 is created through the second socket file, and so on. +**--dma-vfio** +This parameter is used to specify whether the IOMMU needs to be programmed. +If the DMA device is bound to vfio, IOMMU dma mapping will be setup for +guest memory. If igb_uio is bound by DMA device, there is no need to do +IOMMU dma mapping. It is a supplementary parameter for async vhost-user +driver and it is disabled by default. + Common Issues ------------- diff --git a/examples/vhost/main.c b/examples/vhost/main.c index 81d7e4cbd3..53bb8cfe80 100644 --- a/examples/vhost/main.c +++ b/examples/vhost/main.c @@ -89,6 +89,8 @@ static uint32_t enable_tx_csum; /* Disable TSO offload */ static uint32_t enable_tso; +static uint32_t dma_use_vfio; + static int client_mode; static int builtin_net_driver; @@ -472,7 +474,8 @@ us_vhost_usage(const char *prgname) " --tso [0|1] disable/enable TCP segment offload.\n" " --client register a vhost-user socket as client mode.\n" " --dma-type register dma type for your vhost async driver. For example \"ioat\" for now.\n" - " --dmas register dma channel for specific vhost device.\n", + " --dmas register dma channel for specific vhost device.\n" + " --dma-vfio [0|1]: 0: DMA device uses igb_uio, 1: DMA device uses vfio\n", prgname); } @@ -503,6 +506,8 @@ enum { OPT_DMA_TYPE_NUM, #define OPT_DMAS "dmas" OPT_DMAS_NUM, +#define OPT_DMA_VFIO "dma-vfio" + OPT_DMA_VFIO_NUM, }; /* @@ -542,6 +547,8 @@ us_vhost_parse_args(int argc, char **argv) NULL, OPT_DMA_TYPE_NUM}, {OPT_DMAS, required_argument, NULL, OPT_DMAS_NUM}, + {OPT_DMA_VFIO, required_argument, + NULL, OPT_DMA_VFIO_NUM}, {NULL, 0, 0, 0}, }; @@ -679,6 +686,10 @@ us_vhost_parse_args(int argc, char **argv) } break; + case OPT_DMA_VFIO_NUM: + dma_use_vfio = 1; + break; + case OPT_CLIENT_NUM: client_mode = 1; break; @@ -1788,6 +1799,9 @@ main(int argc, char *argv[]) if (client_mode) flags |= RTE_VHOST_USER_CLIENT; + if (dma_use_vfio) + flags |= RTE_VHOST_USER_ASYNC_USE_VFIO; + /* Register vhost user driver to handle vhost messages. */ for (i = 0; i < nb_sockets; i++) { char *file = socket_files + i * PATH_MAX;