Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

queue_api: add support for fetching per queue DMA dev

For zerocopy (io_uring, devmem), there is an assumption that the
parent device can do DMA. However that is not always the case:
- Scalable Function netdevs [1] have the DMA device in the grandparent.
- For Multi-PF netdevs [2] queues can be associated to different DMA
devices.

This patch introduces the a queue based interface for allowing drivers
to expose a different DMA device for zerocopy.

[1] Documentation/networking/device_drivers/ethernet/mellanox/mlx5/switchdev.rst
[2] Documentation/networking/multi-pf-netdev.rst

Signed-off-by: Dragos Tatulea <dtatulea@nvidia.com>
Reviewed-by: Pavel Begunkov <asml.silence@gmail.com>
Reviewed-by: Mina Almasry <almasrymina@google.com>
Link: https://patch.msgid.link/20250827144017.1529208-3-dtatulea@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Dragos Tatulea and committed by
Jakub Kicinski
13d8e05a 14cd01c2

+35
+7
include/net/netdev_queues.h
··· 127 127 * @ndo_queue_stop: Stop the RX queue at the specified index. The stopped 128 128 * queue's memory is written at the specified address. 129 129 * 130 + * @ndo_queue_get_dma_dev: Get dma device for zero-copy operations to be used 131 + * for this queue. Return NULL on error. 132 + * 130 133 * Note that @ndo_queue_mem_alloc and @ndo_queue_mem_free may be called while 131 134 * the interface is closed. @ndo_queue_start and @ndo_queue_stop will only 132 135 * be called for an interface which is open. ··· 147 144 int (*ndo_queue_stop)(struct net_device *dev, 148 145 void *per_queue_mem, 149 146 int idx); 147 + struct device * (*ndo_queue_get_dma_dev)(struct net_device *dev, 148 + int idx); 150 149 }; 151 150 152 151 /** ··· 325 320 netif_txq_completed_wake(_txq, pkts, bytes, \ 326 321 get_desc, start_thrs); \ 327 322 }) 323 + 324 + struct device *netdev_queue_get_dma_dev(struct net_device *dev, int idx); 328 325 329 326 #endif
+1
net/core/Makefile
··· 20 20 obj-y += net-sysfs.o 21 21 obj-y += hotdata.o 22 22 obj-y += netdev_rx_queue.o 23 + obj-y += netdev_queues.o 23 24 obj-$(CONFIG_PAGE_POOL) += page_pool.o page_pool_user.o 24 25 obj-$(CONFIG_PROC_FS) += net-procfs.o 25 26 obj-$(CONFIG_NET_PKTGEN) += pktgen.o
+27
net/core/netdev_queues.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + 3 + #include <net/netdev_queues.h> 4 + 5 + /** 6 + * netdev_queue_get_dma_dev() - get dma device for zero-copy operations 7 + * @dev: net_device 8 + * @idx: queue index 9 + * 10 + * Get dma device for zero-copy operations to be used for this queue. 11 + * When such device is not available or valid, the function will return NULL. 12 + * 13 + * Return: Device or NULL on error 14 + */ 15 + struct device *netdev_queue_get_dma_dev(struct net_device *dev, int idx) 16 + { 17 + const struct netdev_queue_mgmt_ops *queue_ops = dev->queue_mgmt_ops; 18 + struct device *dma_dev; 19 + 20 + if (queue_ops && queue_ops->ndo_queue_get_dma_dev) 21 + dma_dev = queue_ops->ndo_queue_get_dma_dev(dev, idx); 22 + else 23 + dma_dev = dev->dev.parent; 24 + 25 + return dma_dev && dma_dev->dma_mask ? dma_dev : NULL; 26 + } 27 +