[PATCH 10/33] xsk: support virtio DMA map
From: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
Date: 2023-02-02 11:01:42
Also in:
bpf, netdev
Subsystem:
networking [general], the rest, xdp sockets (af_xdp) · Maintainers:
"David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds, Magnus Karlsson, Maciej Fijalkowski
When device is a virtio device, use virtio's DMA interface. Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com> --- net/xdp/xsk_buff_pool.c | 59 +++++++++++++++++++++++++++++++---------- 1 file changed, 45 insertions(+), 14 deletions(-)
diff --git a/net/xdp/xsk_buff_pool.c b/net/xdp/xsk_buff_pool.c
index 78e325e195fa..e2785aca8396 100644
--- a/net/xdp/xsk_buff_pool.c
+++ b/net/xdp/xsk_buff_pool.c@@ -3,6 +3,7 @@ #include <net/xsk_buff_pool.h> #include <net/xdp_sock.h> #include <net/xdp_sock_drv.h> +#include <linux/virtio.h> #include "xsk_queue.h" #include "xdp_umem.h"
@@ -334,8 +335,12 @@ static void __xp_dma_unmap(struct xsk_dma_map *dma_map, unsigned long attrs) dma = &dma_map->dma_pages[i]; if (*dma) { *dma &= ~XSK_NEXT_PG_CONTIG_MASK; - dma_unmap_page_attrs(dma_map->dev, *dma, PAGE_SIZE, - DMA_BIDIRECTIONAL, attrs); + if (is_virtio_device(dma_map->dev)) + virtio_dma_unmap(dma_map->dev, *dma, PAGE_SIZE, + DMA_BIDIRECTIONAL); + else + dma_unmap_page_attrs(dma_map->dev, *dma, PAGE_SIZE, + DMA_BIDIRECTIONAL, attrs); *dma = 0; } }
@@ -435,22 +440,40 @@ int xp_dma_map(struct xsk_buff_pool *pool, struct device *dev, return 0; } - pool->dma_sync_for_cpu = dma_sync_for_cpu; - pool->dma_sync_for_device = dma_sync_for_device; + if (is_virtio_device(dev)) { + pool->dma_sync_for_cpu = virtio_dma_sync_signle_range_for_cpu; + pool->dma_sync_for_device = virtio_dma_sync_signle_range_for_device; + + } else { + pool->dma_sync_for_cpu = dma_sync_for_cpu; + pool->dma_sync_for_device = dma_sync_for_device; + } dma_map = xp_create_dma_map(dev, pool->netdev, nr_pages, pool->umem); if (!dma_map) return -ENOMEM; for (i = 0; i < dma_map->dma_pages_cnt; i++) { - dma = dma_map_page_attrs(dev, pages[i], 0, PAGE_SIZE, - DMA_BIDIRECTIONAL, attrs); - if (dma_mapping_error(dev, dma)) { - __xp_dma_unmap(dma_map, attrs); - return -ENOMEM; + if (is_virtio_device(dev)) { + dma = virtio_dma_map_page(dev, pages[i], 0, PAGE_SIZE, + DMA_BIDIRECTIONAL); + + if (virtio_dma_mapping_error(dev, dma)) + goto err; + + if (virtio_dma_need_sync(dev, dma)) + dma_map->dma_need_sync = true; + + } else { + dma = dma_map_page_attrs(dev, pages[i], 0, PAGE_SIZE, + DMA_BIDIRECTIONAL, attrs); + + if (dma_mapping_error(dev, dma)) + goto err; + + if (dma_need_sync(dev, dma)) + dma_map->dma_need_sync = true; } - if (dma_need_sync(dev, dma)) - dma_map->dma_need_sync = true; dma_map->dma_pages[i] = dma; }
@@ -464,6 +487,9 @@ int xp_dma_map(struct xsk_buff_pool *pool, struct device *dev, } return 0; +err: + __xp_dma_unmap(dma_map, attrs); + return -ENOMEM; } EXPORT_SYMBOL(xp_dma_map);
@@ -546,9 +572,14 @@ struct xdp_buff *xp_alloc(struct xsk_buff_pool *pool) xskb->xdp.data_meta = xskb->xdp.data; if (pool->dma_need_sync) { - dma_sync_single_range_for_device(pool->dev, xskb->dma, 0, - pool->frame_len, - DMA_BIDIRECTIONAL); + if (is_virtio_device(pool->dev)) + virtio_dma_sync_signle_range_for_device(pool->dev, xskb->dma, 0, + pool->frame_len, + DMA_BIDIRECTIONAL); + else + dma_sync_single_range_for_device(pool->dev, xskb->dma, 0, + pool->frame_len, + DMA_BIDIRECTIONAL); } return &xskb->xdp; }
--
2.32.0.3.g01195cf9f
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization