From 51c52c0adc9bf79ca6508ee1327d3b972e80b5c6 Mon Sep 17 00:00:00 2001 From: Damjan Marion Date: Fri, 9 Mar 2018 16:05:56 +0100 Subject: dpdk: move DPDK vfio hack to dpdk plugin Change-Id: I806cbf8c6c49643fe6c317bcceab93c1b9d441ab Signed-off-by: Damjan Marion --- src/plugins/dpdk/buffer.c | 69 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 2 deletions(-) (limited to 'src/plugins/dpdk/buffer.c') diff --git a/src/plugins/dpdk/buffer.c b/src/plugins/dpdk/buffer.c index f6379a1da4a..47d66484b3d 100644 --- a/src/plugins/dpdk/buffer.c +++ b/src/plugins/dpdk/buffer.c @@ -43,6 +43,10 @@ * Allocate/free network buffers. */ +#include +#include +#include + #include #include @@ -71,11 +75,13 @@ #include #include +#include +#include +#include #include #include #include - STATIC_ASSERT (VLIB_BUFFER_PRE_DATA_SIZE == RTE_PKTMBUF_HEADROOM, "VLIB_BUFFER_PRE_DATA_SIZE must be equal to RTE_PKTMBUF_HEADROOM"); @@ -91,6 +97,7 @@ typedef struct typedef struct { + int vfio_container_fd; dpdk_buffer_per_thread_data *ptd; } dpdk_buffer_main_t; @@ -459,11 +466,38 @@ 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; vlib_physmem_region_t *pr; clib_error_t *error = 0; @@ -501,6 +535,33 @@ dpdk_pool_create (vlib_main_t * vm, u8 * pool_name, u32 elt_size, _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) + (i << pr->log2_page_size); + dm.size = 1 << 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 && rv != EINVAL) + clib_unix_warning ("ioctl(VFIO_IOMMU_MAP_DMA) pool '%s'", pool_name); + } + return 0; } @@ -665,8 +726,12 @@ dpdk_buffer_init (vlib_main_t * vm) { dpdk_buffer_main_t *dbm = &dpdk_buffer_main; vlib_thread_main_t *tm = vlib_get_thread_main (); + vec_validate_aligned (dbm->ptd, tm->n_vlib_mains - 1, CLIB_CACHE_LINE_BYTES); + + dbm->vfio_container_fd = -1; + return 0; } -- cgit 1.2.3-korg