]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
net: Proxy netdev_queue_get_dma_dev for leased queues
authorDavid Wei <dw@davidwei.uk>
Thu, 15 Jan 2026 08:25:53 +0000 (09:25 +0100)
committerPaolo Abeni <pabeni@redhat.com>
Tue, 20 Jan 2026 10:58:49 +0000 (11:58 +0100)
Extend netdev_queue_get_dma_dev to return the physical device of the
real rxq for DMA in case the queue was leased. This allows memory
providers like io_uring zero-copy or devmem to bind to the physically
leased rxq via virtual devices such as netkit.

Signed-off-by: David Wei <dw@davidwei.uk>
Co-developed-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Stanislav Fomichev <sdf@fomichev.me>
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
Link: https://patch.msgid.link/20260115082603.219152-7-daniel@iogearbox.net
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
net/core/netdev_queues.c

index fae92ee090c40e968f9b759441bd96c025938ea5..97acf6440829295bccbececbbac60308f62f01c4 100644 (file)
@@ -9,16 +9,29 @@
  * @dev:       net_device
  * @idx:       queue index
  *
- * Get dma device for zero-copy operations to be used for this queue.
+ * Get dma device for zero-copy operations to be used for this queue. If the
+ * queue is leased to a physical queue, we retrieve the latter's dma device.
  * When such device is not available or valid, the function will return NULL.
  *
  * Return: Device or NULL on error
  */
 struct device *netdev_queue_get_dma_dev(struct net_device *dev, int idx)
 {
-       const struct netdev_queue_mgmt_ops *queue_ops = dev->queue_mgmt_ops;
+       const struct netdev_queue_mgmt_ops *queue_ops;
        struct device *dma_dev;
 
+       if (idx < dev->real_num_rx_queues) {
+               struct netdev_rx_queue *rxq = __netif_get_rx_queue(dev, idx);
+
+               if (rxq->lease) {
+                       rxq = rxq->lease;
+                       dev = rxq->dev;
+                       idx = get_netdev_rx_queue_index(rxq);
+               }
+       }
+
+       queue_ops = dev->queue_mgmt_ops;
+
        if (queue_ops && queue_ops->ndo_queue_get_dma_dev)
                dma_dev = queue_ops->ndo_queue_get_dma_dev(dev, idx);
        else