[dpdk-dev] [PATCH 2/5] net/virtio: setup Rx fastpath interrupts

Jianfeng Tan jianfeng.tan at intel.com
Sun Dec 4 01:18:19 CET 2016


In virtio, each rx queue has one exclusive interrupt (corresponding
to irqfd in the qemu/kvm) to get notified when packets are available
in that queue. That is to say, queues cannot share interrupt. So we
have 1:1 mapping between queues and interrupts.

This patch creates eventfds for each Rx queue and configures the info
into kernel.

Signed-off-by: Jianfeng Tan <jianfeng.tan at intel.com>
---
 drivers/net/virtio/virtio_ethdev.c | 42 +++++++++++++++++++++++++++++++++++---
 1 file changed, 39 insertions(+), 3 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 681a86b..886524c 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1474,6 +1474,9 @@ virtio_dev_start(struct rte_eth_dev *dev)
 	struct virtnet_rx *rxvq;
 	struct virtnet_tx *txvq __rte_unused;
 	struct virtio_hw *hw = dev->data->dev_private;
+	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+
+	rte_intr_disable(intr_handle);
 
 	/* check if lsc interrupt feature is enabled */
 	if (dev->data->dev_conf.intr_conf.lsc) {
@@ -1482,9 +1485,37 @@ virtio_dev_start(struct rte_eth_dev *dev)
 			return -ENOTSUP;
 		}
 
-		if (rte_intr_enable(&dev->pci_dev->intr_handle) < 0) {
-			PMD_DRV_LOG(ERR, "interrupt enable failed");
-			return -EIO;
+	}
+
+	if (dev->data->dev_conf.intr_conf.rxq) {
+		/*
+		 * 1. uio, igb_uio, vfio (type1): lsc and rxq interrupt share
+		 * one interrupt.
+		 * 2. vfio (noiommu): .
+		 */
+		uint32_t intr_vector;
+
+		if (!rte_intr_cap_multiple(intr_handle)) {
+			PMD_INIT_LOG(ERR, "Multiple intr vector not supported");
+			return -1;
+		}
+
+		intr_vector = dev->data->nb_rx_queues;
+		if (rte_intr_efd_enable(intr_handle, intr_vector)) {
+			PMD_INIT_LOG(ERR, "Fail to create eventfd");
+			return -1;
+		}
+	}
+
+	if (rte_intr_dp_is_en(intr_handle) && !intr_handle->intr_vec) {
+		intr_handle->intr_vec =
+			rte_zmalloc("intr_vec",
+				    dev->data->nb_rx_queues * sizeof(int),
+				    0);
+		if (!intr_handle->intr_vec) {
+			PMD_INIT_LOG(ERR, "Failed to allocate %d rx_queues"
+				     " intr_vec\n", dev->data->nb_rx_queues);
+			return -ENOMEM;
 		}
 	}
 
@@ -1520,6 +1551,11 @@ virtio_dev_start(struct rte_eth_dev *dev)
 		VIRTQUEUE_DUMP(txvq->vq);
 	}
 
+	if (rte_intr_enable(intr_handle) < 0) {
+		PMD_DRV_LOG(ERR, "interrupt enable failed");
+		return -EIO;
+	}
+
 	return 0;
 }
 
-- 
2.7.4



More information about the dev mailing list