From: Damjan Marion Date: Sat, 20 Oct 2018 21:26:46 +0000 (+0200) Subject: dpdk: use rte_vfio_dma_map API instead of digging for vfio fd X-Git-Tag: v19.04-rc0~580 X-Git-Url: https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commitdiff_plain;h=b9ffffd61967ba9bc9453c93348be1ea5412c638 dpdk: use rte_vfio_dma_map API instead of digging for vfio fd This is new API introduced in DPDK 18.08. Change-Id: I66d49fe54a6abf2af621b597e8d4535e29cecec4 Signed-off-by: Damjan Marion --- diff --git a/src/plugins/dpdk/buffer.c b/src/plugins/dpdk/buffer.c index bb177fc6772..cc7eed059f0 100644 --- a/src/plugins/dpdk/buffer.c +++ b/src/plugins/dpdk/buffer.c @@ -44,8 +44,6 @@ */ #include -#include -#include #include @@ -64,7 +62,7 @@ #include #include #include -#include +#include #include #include #include @@ -76,8 +74,6 @@ #include #include -#include -#include #include #include #include @@ -394,43 +390,18 @@ dpdk_packet_template_init (vlib_main_t * vm, vlib_worker_thread_barrier_release (vm); } -static clib_error_t * -scan_vfio_fd (void *arg, u8 * path_name, u8 * file_name) -{ - dpdk_buffer_main_t *dbm = &dpdk_buffer_main; - linux_vfio_main_t *lvm = &vfio_main; - const char fn[] = "/dev/vfio/vfio"; - char buff[sizeof (fn)] = { 0 }; - int fd; - u8 *path = format (0, "%v%c", path_name, 0); - - if (readlink ((char *) path, buff, sizeof (fn)) + 1 != sizeof (fn)) - goto done; - - if (strncmp (fn, buff, sizeof (fn))) - goto done; - - fd = atoi ((char *) file_name); - if (fd != lvm->container_fd) - dbm->vfio_container_fd = fd; - -done: - vec_free (path); - return 0; -} - clib_error_t * dpdk_pool_create (vlib_main_t * vm, u8 * pool_name, u32 elt_size, u32 num_elts, u32 pool_priv_size, u16 cache_size, u8 numa, - struct rte_mempool ** _mp, - vlib_physmem_region_index_t * pri) + struct rte_mempool **_mp, vlib_physmem_region_index_t * pri) { - dpdk_buffer_main_t *dbm = &dpdk_buffer_main; struct rte_mempool *mp; + enum rte_iova_mode iova_mode; vlib_physmem_region_t *pr; dpdk_mempool_private_t priv; clib_error_t *error = 0; size_t min_chunk_size, align; + int map_dma = 1; u32 size; i32 ret; uword i; @@ -463,47 +434,30 @@ dpdk_pool_create (vlib_main_t * vm, u8 * pool_name, u32 elt_size, priv.mbp_priv.mbuf_priv_size = VLIB_BUFFER_HDR_SIZE; rte_pktmbuf_pool_init (mp, &priv); + if (rte_eth_dev_count_avail () == 0) + map_dma = 0; + + iova_mode = rte_eal_iova_mode (); for (i = 0; i < pr->n_pages; i++) { - size_t page_size = 1ull << pr->log2_page_size; - ret = rte_mempool_populate_iova (mp, ((char *) pr->mem) + i * page_size, - pr->page_table[i], page_size, 0, 0); + size_t page_sz = 1ull << pr->log2_page_size; + char *va = ((char *) pr->mem) + i * page_sz; + uword pa = iova_mode == RTE_IOVA_VA ? + pointer_to_uword (va) : pr->page_table[i]; + ret = rte_mempool_populate_iova (mp, va, pa, page_sz, 0, 0); if (ret < 0) { rte_mempool_free (mp); return clib_error_return (0, "failed to populate %s", pool_name); } + /* -1 likely means there is no PCI devices assigned to vfio + container or noiommu mode is used so we stop trying */ + if (map_dma && rte_vfio_dma_map (pointer_to_uword (va), pa, page_sz)) + map_dma = 0; } _mp[0] = mp; - /* DPDK currently doesn't provide API to map DMA memory for empty mempool - so we are using this hack, will be nice to have at least API to get - VFIO container FD */ - if (dbm->vfio_container_fd == -1) - foreach_directory_file ("/proc/self/fd", scan_vfio_fd, 0, 0); - - if (dbm->vfio_container_fd != -1) - { - struct vfio_iommu_type1_dma_map dm = { 0 }; - int i, rv = 0; - dm.argsz = sizeof (struct vfio_iommu_type1_dma_map); - dm.flags = VFIO_DMA_MAP_FLAG_READ | VFIO_DMA_MAP_FLAG_WRITE; - - /* *INDENT-OFF* */ - vec_foreach_index (i, pr->page_table) - { - dm.vaddr = pointer_to_uword (pr->mem) + ((u64)i << pr->log2_page_size); - dm.size = 1ull << pr->log2_page_size; - dm.iova = pr->page_table[i]; - if ((rv = ioctl (dbm->vfio_container_fd, VFIO_IOMMU_MAP_DMA, &dm))) - break; - } - /* *INDENT-ON* */ - if (rv != 0 && errno != EINVAL) - clib_unix_warning ("ioctl(VFIO_IOMMU_MAP_DMA) pool '%s'", pool_name); - } - return 0; }