All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/5] Interrupt mode for virtio PMD
@ 2016-12-04  0:18 Jianfeng Tan
  2016-12-04  0:18 ` [PATCH 1/5] net/virtio: add Rx descriptor check Jianfeng Tan
                   ` (8 more replies)
  0 siblings, 9 replies; 63+ messages in thread
From: Jianfeng Tan @ 2016-12-04  0:18 UTC (permalink / raw)
  To: dev; +Cc: yuanhan.liu, stephen, Jianfeng Tan

First of all, interrupt mode here means per-queue Rx interrupt
support.

Historically, virtio PMD can only be binded to igb_uio or
uio_pci_generic, and not for vfio-pci. Besides, quote from
http://dpdk.org/doc/guides-16.11/rel_notes/release_2_1.html:
  "- Per queue RX interrupt events are only allowed in VFIO
     which supports multiple MSI-X vectors.
   - In UIO, the RX interrupt shares the same vector with other
     interrupts. When the RX interrupt and LSC interrupt are both
     enabled, only the former is available.
   - RX interrupt is only implemented for the linuxapp target"

As Linux starts to support vfio noiommu mode since 4.8.0, it's
a good chance to enable per queue RX interrupt for virtio PMD.
This patchset is an attempt to enable this.

Note: this patch set is still under developping, not ready for test.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>

Jianfeng Tan (5):
  net/virtio: add Rx descriptor check
  net/virtio: setup Rx fastpath interrupts
  net/virtio: remove Rx queue interrupts when stopping
  net/virtio: add Rx queue intr enable/disable functions
  examples/l3fwd: add parse-ptype option

 drivers/net/virtio/virtio_ethdev.c | 74 +++++++++++++++++++++++++++++++++++---
 drivers/net/virtio/virtio_ethdev.h |  3 ++
 drivers/net/virtio/virtio_rxtx.c   |  9 +++++
 drivers/net/virtio/virtqueue.c     | 11 ------
 drivers/net/virtio/virtqueue.h     | 26 +++++++++++++-
 examples/l3fwd-power/main.c        | 60 ++++++++++++++++++++++++++++++-
 6 files changed, 165 insertions(+), 18 deletions(-)

-- 
2.7.4

^ permalink raw reply	[flat|nested] 63+ messages in thread

* [PATCH 1/5] net/virtio: add Rx descriptor check
  2016-12-04  0:18 [PATCH 0/5] Interrupt mode for virtio PMD Jianfeng Tan
@ 2016-12-04  0:18 ` Jianfeng Tan
  2016-12-04  0:18 ` [PATCH 2/5] net/virtio: setup Rx fastpath interrupts Jianfeng Tan
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 63+ messages in thread
From: Jianfeng Tan @ 2016-12-04  0:18 UTC (permalink / raw)
  To: dev; +Cc: yuanhan.liu, stephen, Jianfeng Tan

Under interrupt mode, rx_descriptor_done is used as an indicator
for applications to check if some number of packets are ready to
be received.

This patch enables this by checking used ring's local consumed idx
with shared (with backend) idx.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/virtio/virtio_ethdev.c | 1 +
 drivers/net/virtio/virtio_ethdev.h | 3 +++
 drivers/net/virtio/virtio_rxtx.c   | 9 +++++++++
 3 files changed, 13 insertions(+)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 079fd6c..681a86b 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -737,6 +737,7 @@ static const struct eth_dev_ops virtio_eth_dev_ops = {
 	.link_update             = virtio_dev_link_update,
 	.rx_queue_setup          = virtio_dev_rx_queue_setup,
 	.rx_queue_release        = virtio_dev_queue_release,
+	.rx_descriptor_done      = virtio_dev_rx_queue_done,
 	.tx_queue_setup          = virtio_dev_tx_queue_setup,
 	.tx_queue_release        = virtio_dev_queue_release,
 	/* collect stats per queue */
diff --git a/drivers/net/virtio/virtio_ethdev.h b/drivers/net/virtio/virtio_ethdev.h
index 27d9a19..4ab81c6 100644
--- a/drivers/net/virtio/virtio_ethdev.h
+++ b/drivers/net/virtio/virtio_ethdev.h
@@ -78,6 +78,9 @@ void virtio_dev_cq_start(struct rte_eth_dev *dev);
 /*
  * RX/TX function prototypes
  */
+
+int virtio_dev_rx_queue_done(void *rxq, uint16_t offset);
+
 int  virtio_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t rx_queue_id,
 		uint16_t nb_rx_desc, unsigned int socket_id,
 		const struct rte_eth_rxconf *rx_conf,
diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c
index 22d97a4..aeea0db 100644
--- a/drivers/net/virtio/virtio_rxtx.c
+++ b/drivers/net/virtio/virtio_rxtx.c
@@ -72,6 +72,15 @@
 #define VIRTIO_SIMPLE_FLAGS ((uint32_t)ETH_TXQ_FLAGS_NOMULTSEGS | \
 	ETH_TXQ_FLAGS_NOOFFLOADS)
 
+int
+virtio_dev_rx_queue_done(void *rxq, uint16_t offset)
+{
+	struct virtnet_rx *rxvq = rxq;
+	struct virtqueue *vq = rxvq->vq;
+
+	return (VIRTQUEUE_NUSED(vq) >= offset);
+}
+
 static void
 vq_ring_free_chain(struct virtqueue *vq, uint16_t desc_idx)
 {
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 2/5] net/virtio: setup Rx fastpath interrupts
  2016-12-04  0:18 [PATCH 0/5] Interrupt mode for virtio PMD Jianfeng Tan
  2016-12-04  0:18 ` [PATCH 1/5] net/virtio: add Rx descriptor check Jianfeng Tan
@ 2016-12-04  0:18 ` Jianfeng Tan
  2016-12-04  0:18 ` [PATCH 3/5] net/virtio: remove Rx queue interrupts when stopping Jianfeng Tan
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 63+ messages in thread
From: Jianfeng Tan @ 2016-12-04  0:18 UTC (permalink / raw)
  To: dev; +Cc: yuanhan.liu, stephen, Jianfeng Tan

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@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

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 3/5] net/virtio: remove Rx queue interrupts when stopping
  2016-12-04  0:18 [PATCH 0/5] Interrupt mode for virtio PMD Jianfeng Tan
  2016-12-04  0:18 ` [PATCH 1/5] net/virtio: add Rx descriptor check Jianfeng Tan
  2016-12-04  0:18 ` [PATCH 2/5] net/virtio: setup Rx fastpath interrupts Jianfeng Tan
@ 2016-12-04  0:18 ` Jianfeng Tan
  2016-12-04  0:18 ` [PATCH 4/5] net/virtio: add Rx queue intr enable/disable functions Jianfeng Tan
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 63+ messages in thread
From: Jianfeng Tan @ 2016-12-04  0:18 UTC (permalink / raw)
  To: dev; +Cc: yuanhan.liu, stephen, Jianfeng Tan

This patch disables Rx queue interrupts, cleans the datapath event
and queue/vector map when stopping the device.

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

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 886524c..cc5750e 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1484,7 +1484,6 @@ virtio_dev_start(struct rte_eth_dev *dev)
 			PMD_DRV_LOG(ERR, "link status not supported by host");
 			return -ENOTSUP;
 		}
-
 	}
 
 	if (dev->data->dev_conf.intr_conf.rxq) {
@@ -1611,11 +1610,17 @@ static void
 virtio_dev_stop(struct rte_eth_dev *dev)
 {
 	struct rte_eth_link link;
+	struct rte_intr_conf *intr_conf = &dev->data->dev_conf.intr_conf;
+	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
 
 	PMD_INIT_LOG(DEBUG, "stop");
 
-	if (dev->data->dev_conf.intr_conf.lsc)
-		rte_intr_disable(&dev->pci_dev->intr_handle);
+	if (intr_conf->lsc || intr_conf->rxq) {
+		rte_intr_disable(intr_handle);
+		rte_intr_efd_disable(intr_handle);
+		rte_free(intr_handle->intr_vec);
+		intr_handle->intr_vec = NULL;
+	}
 
 	memset(&link, 0, sizeof(link));
 	virtio_dev_atomic_write_link_status(dev, &link);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 4/5] net/virtio: add Rx queue intr enable/disable functions
  2016-12-04  0:18 [PATCH 0/5] Interrupt mode for virtio PMD Jianfeng Tan
                   ` (2 preceding siblings ...)
  2016-12-04  0:18 ` [PATCH 3/5] net/virtio: remove Rx queue interrupts when stopping Jianfeng Tan
@ 2016-12-04  0:18 ` Jianfeng Tan
  2016-12-04  0:18 ` [PATCH 5/5] examples/l3fwd: add parse-ptype option Jianfeng Tan
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 63+ messages in thread
From: Jianfeng Tan @ 2016-12-04  0:18 UTC (permalink / raw)
  To: dev; +Cc: yuanhan.liu, stephen, Jianfeng Tan

This patch implements interrupt enable/disable functions for each
Rx queue. And we rely on flags of avail queue as the hint for virtio
device to interrupt virtio driver or not.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/virtio/virtio_ethdev.c | 22 ++++++++++++++++++++++
 drivers/net/virtio/virtqueue.c     | 11 -----------
 drivers/net/virtio/virtqueue.h     | 26 +++++++++++++++++++++++++-
 3 files changed, 47 insertions(+), 12 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index cc5750e..d7db698 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -715,6 +715,26 @@ virtio_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
 	return 0;
 }
 
+static int
+virtio_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
+{
+	struct virtnet_rx *rxvq = dev->data->rx_queues[queue_id];
+	struct virtqueue *vq = rxvq->vq;
+
+	virtqueue_enable_intr(vq);
+	return 0;
+}
+
+static int
+virtio_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id)
+{
+	struct virtnet_rx *rxvq = dev->data->rx_queues[queue_id];
+	struct virtqueue *vq = rxvq->vq;
+
+	virtqueue_disable_intr(vq);
+	return 0;
+}
+
 /*
  * dev_ops for virtio, bare necessities for basic operation
  */
@@ -736,6 +756,8 @@ static const struct eth_dev_ops virtio_eth_dev_ops = {
 	.xstats_reset            = virtio_dev_stats_reset,
 	.link_update             = virtio_dev_link_update,
 	.rx_queue_setup          = virtio_dev_rx_queue_setup,
+	.rx_queue_intr_enable    = virtio_dev_rx_queue_intr_enable,
+	.rx_queue_intr_disable   = virtio_dev_rx_queue_intr_disable,
 	.rx_queue_release        = virtio_dev_queue_release,
 	.rx_descriptor_done      = virtio_dev_rx_queue_done,
 	.tx_queue_setup          = virtio_dev_tx_queue_setup,
diff --git a/drivers/net/virtio/virtqueue.c b/drivers/net/virtio/virtqueue.c
index 7f60e3e..9ad77b8 100644
--- a/drivers/net/virtio/virtqueue.c
+++ b/drivers/net/virtio/virtqueue.c
@@ -38,17 +38,6 @@
 #include "virtio_logs.h"
 #include "virtio_pci.h"
 
-void
-virtqueue_disable_intr(struct virtqueue *vq)
-{
-	/*
-	 * Set VRING_AVAIL_F_NO_INTERRUPT to hint host
-	 * not to interrupt when it consumes packets
-	 * Note: this is only considered a hint to the host
-	 */
-	vq->vq_ring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT;
-}
-
 /*
  * Two types of mbuf to be cleaned:
  * 1) mbuf that has been consumed by backend but not used by virtio.
diff --git a/drivers/net/virtio/virtqueue.h b/drivers/net/virtio/virtqueue.h
index f0bb089..b9b6e58 100644
--- a/drivers/net/virtio/virtqueue.h
+++ b/drivers/net/virtio/virtqueue.h
@@ -274,7 +274,31 @@ vring_desc_init(struct vring_desc *dp, uint16_t n)
 /**
  * Tell the backend not to interrupt us.
  */
-void virtqueue_disable_intr(struct virtqueue *vq);
+static inline void
+virtqueue_disable_intr(struct virtqueue *vq)
+{
+	/*
+	 * Set VRING_AVAIL_F_NO_INTERRUPT to hint host
+	 * not to interrupt when it consumes packets
+	 * Note: this is only considered a hint to the host
+	 */
+	vq->vq_ring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT;
+}
+
+/**
+ * Tell the backend to interrupt us.
+ */
+static inline void
+virtqueue_enable_intr(struct virtqueue *vq)
+{
+	/*
+	 * Unset VRING_AVAIL_F_NO_INTERRUPT to hint host
+	 * to interrupt when it consumes packets
+	 * Note: this is only considered a hint to the host
+	 */
+	vq->vq_ring.avail->flags &= (~VRING_AVAIL_F_NO_INTERRUPT);
+}
+
 /**
  *  Dump virtqueue internal structures, for debug purpose only.
  */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 5/5] examples/l3fwd: add parse-ptype option
  2016-12-04  0:18 [PATCH 0/5] Interrupt mode for virtio PMD Jianfeng Tan
                   ` (3 preceding siblings ...)
  2016-12-04  0:18 ` [PATCH 4/5] net/virtio: add Rx queue intr enable/disable functions Jianfeng Tan
@ 2016-12-04  0:18 ` Jianfeng Tan
  2016-12-08  6:59   ` Yuanhan Liu
  2016-12-29  7:30 ` [PATCH v2 0/9] rxq interrupt mode for virtio PMD Jianfeng Tan
                   ` (3 subsequent siblings)
  8 siblings, 1 reply; 63+ messages in thread
From: Jianfeng Tan @ 2016-12-04  0:18 UTC (permalink / raw)
  To: dev; +Cc: yuanhan.liu, stephen, Jianfeng Tan

To support those devices that do not provide packet type info when
receiving packets, add a new option, --parse-ptype, to analyze
packet type in the Rx callback.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 examples/l3fwd-power/main.c | 60 ++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 59 insertions(+), 1 deletion(-)

diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c
index b65d683..46c37bf 100644
--- a/examples/l3fwd-power/main.c
+++ b/examples/l3fwd-power/main.c
@@ -164,6 +164,8 @@ static uint32_t enabled_port_mask = 0;
 static int promiscuous_on = 0;
 /* NUMA is enabled by default. */
 static int numa_on = 1;
+static int parse_ptype; /**< Parse packet type using rx callback, and */
+			/**< disabled by default */
 
 enum freq_scale_hint_t
 {
@@ -607,6 +609,48 @@ get_ipv4_dst_port(struct ipv4_hdr *ipv4_hdr, uint8_t portid,
 #endif
 
 static inline void
+parse_ptype_one(struct rte_mbuf *m)
+{
+	struct ether_hdr *eth_hdr;
+	uint32_t packet_type = RTE_PTYPE_UNKNOWN;
+	uint16_t ether_type;
+
+	eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
+	ether_type = eth_hdr->ether_type;
+	if (ether_type == rte_cpu_to_be_16(ETHER_TYPE_IPv4))
+		packet_type |= RTE_PTYPE_L3_IPV4_EXT_UNKNOWN;
+	else if (ether_type == rte_cpu_to_be_16(ETHER_TYPE_IPv6))
+		packet_type |= RTE_PTYPE_L3_IPV6_EXT_UNKNOWN;
+
+	m->packet_type = packet_type;
+}
+
+static uint16_t
+cb_parse_ptype(uint8_t port __rte_unused, uint16_t queue __rte_unused,
+	       struct rte_mbuf *pkts[], uint16_t nb_pkts,
+	       uint16_t max_pkts __rte_unused,
+	       void *user_param __rte_unused)
+{
+	unsigned i;
+
+	for (i = 0; i < nb_pkts; ++i)
+		parse_ptype_one(pkts[i]);
+
+	return nb_pkts;
+}
+
+static int
+add_cb_parse_ptype(uint8_t portid, uint16_t queueid)
+{
+	printf("Port %d: softly parse packet type info\n", portid);
+	if (rte_eth_add_rx_callback(portid, queueid, cb_parse_ptype, NULL))
+		return 0;
+
+	printf("Failed to add rx callback: port=%d\n", portid);
+	return -1;
+}
+
+static inline void
 l3fwd_simple_forward(struct rte_mbuf *m, uint8_t portid,
 				struct lcore_conf *qconf)
 {
@@ -1108,7 +1152,8 @@ print_usage(const char *prgname)
 		"  --config (port,queue,lcore): rx queues configuration\n"
 		"  --no-numa: optional, disable numa awareness\n"
 		"  --enable-jumbo: enable jumbo frame"
-		" which max packet len is PKTLEN in decimal (64-9600)\n",
+		" which max packet len is PKTLEN in decimal (64-9600)\n"
+		"  --parse-ptype: parse packet type by software\n",
 		prgname);
 }
 
@@ -1202,6 +1247,8 @@ parse_config(const char *q_arg)
 	return 0;
 }
 
+#define CMD_LINE_OPT_PARSE_PTYPE "parse-ptype"
+
 /* Parse the argument given in the command line of the application */
 static int
 parse_args(int argc, char **argv)
@@ -1214,6 +1261,7 @@ parse_args(int argc, char **argv)
 		{"config", 1, 0, 0},
 		{"no-numa", 0, 0, 0},
 		{"enable-jumbo", 0, 0, 0},
+		{CMD_LINE_OPT_PARSE_PTYPE, 0, 0, 0},
 		{NULL, 0, 0, 0}
 	};
 
@@ -1284,6 +1332,13 @@ parse_args(int argc, char **argv)
 				(unsigned int)port_conf.rxmode.max_rx_pkt_len);
 			}
 
+			if (!strncmp(lgopts[option_index].name,
+				     CMD_LINE_OPT_PARSE_PTYPE,
+				     sizeof(CMD_LINE_OPT_PARSE_PTYPE))) {
+				printf("soft parse-ptype is enabled\n");
+				parse_ptype = 1;
+			}
+
 			break;
 
 		default:
@@ -1716,6 +1771,9 @@ main(int argc, char **argv)
 				rte_exit(EXIT_FAILURE,
 					"rte_eth_rx_queue_setup: err=%d, "
 						"port=%d\n", ret, portid);
+
+			if (parse_ptype && add_cb_parse_ptype(portid, queueid))
+				rte_exit(EXIT_FAILURE, "Fail to add ptype cb\n");
 		}
 	}
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* Re: [PATCH 5/5] examples/l3fwd: add parse-ptype option
  2016-12-04  0:18 ` [PATCH 5/5] examples/l3fwd: add parse-ptype option Jianfeng Tan
@ 2016-12-08  6:59   ` Yuanhan Liu
  2016-12-08  7:40     ` Tan, Jianfeng
  0 siblings, 1 reply; 63+ messages in thread
From: Yuanhan Liu @ 2016-12-08  6:59 UTC (permalink / raw)
  To: Jianfeng Tan; +Cc: dev, stephen

On Sun, Dec 04, 2016 at 12:18:22AM +0000, Jianfeng Tan wrote:
> To support those devices that do not provide packet type info when
> receiving packets, add a new option, --parse-ptype, to analyze
> packet type in the Rx callback.

A quick question: does this patch have anything to do with the virtio
interrupt enabling?

	--yliu

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 5/5] examples/l3fwd: add parse-ptype option
  2016-12-08  6:59   ` Yuanhan Liu
@ 2016-12-08  7:40     ` Tan, Jianfeng
  0 siblings, 0 replies; 63+ messages in thread
From: Tan, Jianfeng @ 2016-12-08  7:40 UTC (permalink / raw)
  To: Yuanhan Liu; +Cc: dev, stephen


> -----Original Message-----
> From: Yuanhan Liu [mailto:yuanhan.liu@linux.intel.com]
> Sent: Thursday, December 8, 2016 2:59 PM
> To: Tan, Jianfeng
> Cc: dev@dpdk.org; stephen@networkplumber.org
> Subject: Re: [PATCH 5/5] examples/l3fwd: add parse-ptype option
> 
> On Sun, Dec 04, 2016 at 12:18:22AM +0000, Jianfeng Tan wrote:
> > To support those devices that do not provide packet type info when
> > receiving packets, add a new option, --parse-ptype, to analyze
> > packet type in the Rx callback.
> 
> A quick question: does this patch have anything to do with the virtio
> interrupt enabling?

Yes, it does as this example is used to test the functionality. But like l3fwd example, this example depends on the ptypes to forward packets. So we need to add software parser to parse ptypes like l3fwd example.

Thanks,
Jianfeng

> 
> 	--yliu

^ permalink raw reply	[flat|nested] 63+ messages in thread

* [PATCH v2 0/9] rxq interrupt mode for virtio PMD
  2016-12-04  0:18 [PATCH 0/5] Interrupt mode for virtio PMD Jianfeng Tan
                   ` (4 preceding siblings ...)
  2016-12-04  0:18 ` [PATCH 5/5] examples/l3fwd: add parse-ptype option Jianfeng Tan
@ 2016-12-29  7:30 ` Jianfeng Tan
  2016-12-29  7:30   ` [PATCH v2 1/9] net/virtio: fix rewriting LSC flag Jianfeng Tan
                     ` (10 more replies)
  2017-01-16 14:46 ` [PATCH v3 00/10] " Jianfeng Tan
                   ` (2 subsequent siblings)
  8 siblings, 11 replies; 63+ messages in thread
From: Jianfeng Tan @ 2016-12-29  7:30 UTC (permalink / raw)
  To: dev; +Cc: yuanhan.liu, stephen, Jianfeng Tan

v2:
  - Add PCI queue/irq config ops.
  - Move rxq interrupt settings before sending DRIVER OK.

Historically, virtio PMD can only be binded to igb_uio or
uio_pci_generic, and not for vfio-pci. Besides, quote from
http://dpdk.org/doc/guides-16.11/rel_notes/release_2_1.html:
  "Per queue RX interrupt events are only allowed in VFIO
   which supports multiple MSI-X vectors."

As Linux starts to support vfio noiommu mode since 4.8.0, it's
a good chance to enable rxq interrupt for virtio PMD.

How to test:

Step 1, prepare a VM image with kernel version >= 4.8.0.

Step 2, on the host, start a testpmd with a vhost port:
$ testpmd -c 0x7 -m 1024 --vdev 'eth_vhost0,iface=/tmp/sock0,queues=2' \
	--no-pci -- -i --rxq=2 --txq=2 --nb-cores=2

Step 3, boot the VM:
$ qemu ... -chardev socket,id=chr1,path=/tmp/sock0 \
	-netdev vhost-user,id=net1,chardev=chr1,vhostforce,queues=2 \
	-device virtio-net-pci,netdev=net1,mq=on,vectors=5 ...

Step 4, start l3fwd-power in VM:
$ l3fwd-power -c 0x3 -n 4 -- -p 1 -P --config="(0,0,1),(0,1,1)" --no-numa

Step 5, send packets from testpmd on the host:
$ start tx_first

Then l3fwd-power outputs:
L3FWD_POWER: lcore 1 is waked up from rx interrupt on port 0 queue 0
L3FWD_POWER: lcore 1 is waked up from rx interrupt on port 0 queue 1

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Jianfeng Tan (9):
  net/virtio: fix rewriting LSC flag
  net/virtio: add Rx descriptor check
  net/virtio: add PCI ops for queue/irq binding
  net/virtio: add Rx queue intr enable/disable functions
  net/virtio: setup rxq interrupts
  net/virtio: unbind intr/eventfd when stop device
  net/virtio: unmapping queue/irq when close device
  examples/l3fwd: add parse-ptype option
  examples/l3fwd-power: fix not stop and close device

 drivers/net/virtio/virtio_ethdev.c | 149 +++++++++++++++++++++++++++++++++++--
 drivers/net/virtio/virtio_ethdev.h |   3 +
 drivers/net/virtio/virtio_pci.c    |  29 ++++++++
 drivers/net/virtio/virtio_pci.h    |   5 ++
 drivers/net/virtio/virtio_rxtx.c   |   9 +++
 drivers/net/virtio/virtqueue.c     |  11 ---
 drivers/net/virtio/virtqueue.h     |  24 +++++-
 examples/l3fwd-power/main.c        |  70 ++++++++++++++++-
 8 files changed, 282 insertions(+), 18 deletions(-)

-- 
2.7.4

^ permalink raw reply	[flat|nested] 63+ messages in thread

* [PATCH v2 1/9] net/virtio: fix rewriting LSC flag
  2016-12-29  7:30 ` [PATCH v2 0/9] rxq interrupt mode for virtio PMD Jianfeng Tan
@ 2016-12-29  7:30   ` Jianfeng Tan
  2016-12-29  7:30   ` [PATCH v2 2/9] net/virtio: add Rx descriptor check Jianfeng Tan
                     ` (9 subsequent siblings)
  10 siblings, 0 replies; 63+ messages in thread
From: Jianfeng Tan @ 2016-12-29  7:30 UTC (permalink / raw)
  To: dev; +Cc: yuanhan.liu, stephen, Jianfeng Tan, stable

The LSC flag is decided according to if VIRTIO_NET_F_STATUS feature
is negotiated. Copy the PCI info after the judgement will rewrite
the correct result.

Fixes: 198ab33677c9 ("net/virtio: move device initialization in a function")

CC: stable@dpdk.org

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

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 079fd6c..aaec338 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1204,14 +1204,14 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
 	if (virtio_negotiate_features(hw, req_features) < 0)
 		return -1;
 
+	rte_eth_copy_pci_info(eth_dev, pci_dev);
+
 	/* If host does not support status then disable LSC */
 	if (!vtpci_with_feature(hw, VIRTIO_NET_F_STATUS))
 		eth_dev->data->dev_flags &= ~RTE_ETH_DEV_INTR_LSC;
 	else
 		eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC;
 
-	rte_eth_copy_pci_info(eth_dev, pci_dev);
-
 	rx_func_get(eth_dev);
 
 	/* Setting up rx_header size for the device */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v2 2/9] net/virtio: add Rx descriptor check
  2016-12-29  7:30 ` [PATCH v2 0/9] rxq interrupt mode for virtio PMD Jianfeng Tan
  2016-12-29  7:30   ` [PATCH v2 1/9] net/virtio: fix rewriting LSC flag Jianfeng Tan
@ 2016-12-29  7:30   ` Jianfeng Tan
  2016-12-29  7:30   ` [PATCH v2 3/9] net/virtio: add PCI ops for queue/irq binding Jianfeng Tan
                     ` (8 subsequent siblings)
  10 siblings, 0 replies; 63+ messages in thread
From: Jianfeng Tan @ 2016-12-29  7:30 UTC (permalink / raw)
  To: dev; +Cc: yuanhan.liu, stephen, Jianfeng Tan

Under interrupt mode, rx_descriptor_done is used as an indicator
for applications to check if some number of packets are ready to
be received.

This patch enables this by checking used ring's local consumed idx
with shared (with backend) idx.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/virtio/virtio_ethdev.c | 1 +
 drivers/net/virtio/virtio_ethdev.h | 3 +++
 drivers/net/virtio/virtio_rxtx.c   | 9 +++++++++
 3 files changed, 13 insertions(+)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index aaec338..c2633c0 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -737,6 +737,7 @@ static const struct eth_dev_ops virtio_eth_dev_ops = {
 	.link_update             = virtio_dev_link_update,
 	.rx_queue_setup          = virtio_dev_rx_queue_setup,
 	.rx_queue_release        = virtio_dev_queue_release,
+	.rx_descriptor_done      = virtio_dev_rx_queue_done,
 	.tx_queue_setup          = virtio_dev_tx_queue_setup,
 	.tx_queue_release        = virtio_dev_queue_release,
 	/* collect stats per queue */
diff --git a/drivers/net/virtio/virtio_ethdev.h b/drivers/net/virtio/virtio_ethdev.h
index 27d9a19..4ab81c6 100644
--- a/drivers/net/virtio/virtio_ethdev.h
+++ b/drivers/net/virtio/virtio_ethdev.h
@@ -78,6 +78,9 @@ void virtio_dev_cq_start(struct rte_eth_dev *dev);
 /*
  * RX/TX function prototypes
  */
+
+int virtio_dev_rx_queue_done(void *rxq, uint16_t offset);
+
 int  virtio_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t rx_queue_id,
 		uint16_t nb_rx_desc, unsigned int socket_id,
 		const struct rte_eth_rxconf *rx_conf,
diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c
index 22d97a4..aeea0db 100644
--- a/drivers/net/virtio/virtio_rxtx.c
+++ b/drivers/net/virtio/virtio_rxtx.c
@@ -72,6 +72,15 @@
 #define VIRTIO_SIMPLE_FLAGS ((uint32_t)ETH_TXQ_FLAGS_NOMULTSEGS | \
 	ETH_TXQ_FLAGS_NOOFFLOADS)
 
+int
+virtio_dev_rx_queue_done(void *rxq, uint16_t offset)
+{
+	struct virtnet_rx *rxvq = rxq;
+	struct virtqueue *vq = rxvq->vq;
+
+	return (VIRTQUEUE_NUSED(vq) >= offset);
+}
+
 static void
 vq_ring_free_chain(struct virtqueue *vq, uint16_t desc_idx)
 {
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v2 3/9] net/virtio: add PCI ops for queue/irq binding
  2016-12-29  7:30 ` [PATCH v2 0/9] rxq interrupt mode for virtio PMD Jianfeng Tan
  2016-12-29  7:30   ` [PATCH v2 1/9] net/virtio: fix rewriting LSC flag Jianfeng Tan
  2016-12-29  7:30   ` [PATCH v2 2/9] net/virtio: add Rx descriptor check Jianfeng Tan
@ 2016-12-29  7:30   ` Jianfeng Tan
  2016-12-30  5:46     ` Yuanhan Liu
  2016-12-29  7:30   ` [PATCH v2 4/9] net/virtio: add Rx queue intr enable/disable functions Jianfeng Tan
                     ` (7 subsequent siblings)
  10 siblings, 1 reply; 63+ messages in thread
From: Jianfeng Tan @ 2016-12-29  7:30 UTC (permalink / raw)
  To: dev; +Cc: yuanhan.liu, stephen, Jianfeng Tan

Add handler in virtio_pci_ops to set queue/irq bind.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/virtio/virtio_pci.c | 29 +++++++++++++++++++++++++++++
 drivers/net/virtio/virtio_pci.h |  5 +++++
 2 files changed, 34 insertions(+)

diff --git a/drivers/net/virtio/virtio_pci.c b/drivers/net/virtio/virtio_pci.c
index 9b47165..4e706cf 100644
--- a/drivers/net/virtio/virtio_pci.c
+++ b/drivers/net/virtio/virtio_pci.c
@@ -217,6 +217,18 @@ legacy_set_config_irq(struct virtio_hw *hw, uint16_t vec)
 }
 
 static uint16_t
+legacy_set_queue_irq(struct virtio_hw *hw, struct virtqueue *vq, uint16_t vec)
+{
+	uint16_t dst;
+
+	rte_eal_pci_ioport_write(&hw->io, &vq->vq_queue_index, 2,
+			 VIRTIO_PCI_QUEUE_SEL);
+	rte_eal_pci_ioport_write(&hw->io, &vec, 2, VIRTIO_MSI_QUEUE_VECTOR);
+	rte_eal_pci_ioport_read(&hw->io, &dst, 2, VIRTIO_MSI_QUEUE_VECTOR);
+	return dst;
+}
+
+static uint16_t
 legacy_get_queue_num(struct virtio_hw *hw, uint16_t queue_id)
 {
 	uint16_t dst;
@@ -310,6 +322,7 @@ static const struct virtio_pci_ops legacy_ops = {
 	.set_features	= legacy_set_features,
 	.get_isr	= legacy_get_isr,
 	.set_config_irq	= legacy_set_config_irq,
+	.set_queue_irq = legacy_set_queue_irq,
 	.get_queue_num	= legacy_get_queue_num,
 	.setup_queue	= legacy_setup_queue,
 	.del_queue	= legacy_del_queue,
@@ -449,6 +462,15 @@ modern_set_config_irq(struct virtio_hw *hw, uint16_t vec)
 }
 
 static uint16_t
+modern_set_queue_irq(struct virtio_hw *hw, struct virtqueue *vq, uint16_t vec)
+{
+	PMD_INIT_LOG(INFO, "vq: %u, vec: %u", vq->vq_queue_index, vec);
+	io_write16(vq->vq_queue_index, &hw->common_cfg->queue_select);
+	io_write16(vec, &hw->common_cfg->queue_msix_vector);
+	return io_read16(&hw->common_cfg->queue_msix_vector);
+}
+
+static uint16_t
 modern_get_queue_num(struct virtio_hw *hw, uint16_t queue_id)
 {
 	io_write16(queue_id, &hw->common_cfg->queue_select);
@@ -526,6 +548,7 @@ static const struct virtio_pci_ops modern_ops = {
 	.set_features	= modern_set_features,
 	.get_isr	= modern_get_isr,
 	.set_config_irq	= modern_set_config_irq,
+	.set_queue_irq = modern_set_queue_irq,
 	.get_queue_num	= modern_get_queue_num,
 	.setup_queue	= modern_setup_queue,
 	.del_queue	= modern_del_queue,
@@ -605,6 +628,12 @@ vtpci_irq_config(struct virtio_hw *hw, uint16_t vec)
 	return hw->vtpci_ops->set_config_irq(hw, vec);
 }
 
+uint16_t
+vtpci_irq_queue(struct virtqueue *vq, uint16_t vec)
+{
+	return vq->hw->vtpci_ops->set_queue_irq(vq->hw, vq, vec);
+}
+
 static void *
 get_cfg_addr(struct rte_pci_device *dev, struct virtio_pci_cap *cap)
 {
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index de271bf..d12d40f 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -235,6 +235,9 @@ struct virtio_pci_ops {
 
 	uint16_t (*set_config_irq)(struct virtio_hw *hw, uint16_t vec);
 
+	uint16_t (*set_queue_irq)(struct virtio_hw *hw, struct virtqueue *vq,
+			uint16_t vec);
+
 	uint16_t (*get_queue_num)(struct virtio_hw *hw, uint16_t queue_id);
 	int (*setup_queue)(struct virtio_hw *hw, struct virtqueue *vq);
 	void (*del_queue)(struct virtio_hw *hw, struct virtqueue *vq);
@@ -317,4 +320,6 @@ uint8_t vtpci_isr(struct virtio_hw *);
 
 uint16_t vtpci_irq_config(struct virtio_hw *, uint16_t);
 
+uint16_t vtpci_irq_queue(struct virtqueue *vq, uint16_t vec);
+
 #endif /* _VIRTIO_PCI_H_ */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v2 4/9] net/virtio: add Rx queue intr enable/disable functions
  2016-12-29  7:30 ` [PATCH v2 0/9] rxq interrupt mode for virtio PMD Jianfeng Tan
                     ` (2 preceding siblings ...)
  2016-12-29  7:30   ` [PATCH v2 3/9] net/virtio: add PCI ops for queue/irq binding Jianfeng Tan
@ 2016-12-29  7:30   ` Jianfeng Tan
  2016-12-30  5:59     ` Yuanhan Liu
  2016-12-29  7:30   ` [PATCH v2 5/9] net/virtio: setup rxq interrupts Jianfeng Tan
                     ` (6 subsequent siblings)
  10 siblings, 1 reply; 63+ messages in thread
From: Jianfeng Tan @ 2016-12-29  7:30 UTC (permalink / raw)
  To: dev; +Cc: yuanhan.liu, stephen, Jianfeng Tan

This patch implements interrupt enable/disable functions for each
Rx queue. And we rely on flags of avail queue as the hint for virtio
device to interrupt virtio driver or not.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/virtio/virtio_ethdev.c | 22 ++++++++++++++++++++++
 drivers/net/virtio/virtqueue.c     | 11 -----------
 drivers/net/virtio/virtqueue.h     | 24 +++++++++++++++++++++++-
 3 files changed, 45 insertions(+), 12 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index c2633c0..3f8b90c 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -715,6 +715,26 @@ virtio_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
 	return 0;
 }
 
+static int
+virtio_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
+{
+	struct virtnet_rx *rxvq = dev->data->rx_queues[queue_id];
+	struct virtqueue *vq = rxvq->vq;
+
+	virtqueue_enable_intr(vq);
+	return 0;
+}
+
+static int
+virtio_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id)
+{
+	struct virtnet_rx *rxvq = dev->data->rx_queues[queue_id];
+	struct virtqueue *vq = rxvq->vq;
+
+	virtqueue_disable_intr(vq);
+	return 0;
+}
+
 /*
  * dev_ops for virtio, bare necessities for basic operation
  */
@@ -736,6 +756,8 @@ static const struct eth_dev_ops virtio_eth_dev_ops = {
 	.xstats_reset            = virtio_dev_stats_reset,
 	.link_update             = virtio_dev_link_update,
 	.rx_queue_setup          = virtio_dev_rx_queue_setup,
+	.rx_queue_intr_enable    = virtio_dev_rx_queue_intr_enable,
+	.rx_queue_intr_disable   = virtio_dev_rx_queue_intr_disable,
 	.rx_queue_release        = virtio_dev_queue_release,
 	.rx_descriptor_done      = virtio_dev_rx_queue_done,
 	.tx_queue_setup          = virtio_dev_tx_queue_setup,
diff --git a/drivers/net/virtio/virtqueue.c b/drivers/net/virtio/virtqueue.c
index 7f60e3e..9ad77b8 100644
--- a/drivers/net/virtio/virtqueue.c
+++ b/drivers/net/virtio/virtqueue.c
@@ -38,17 +38,6 @@
 #include "virtio_logs.h"
 #include "virtio_pci.h"
 
-void
-virtqueue_disable_intr(struct virtqueue *vq)
-{
-	/*
-	 * Set VRING_AVAIL_F_NO_INTERRUPT to hint host
-	 * not to interrupt when it consumes packets
-	 * Note: this is only considered a hint to the host
-	 */
-	vq->vq_ring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT;
-}
-
 /*
  * Two types of mbuf to be cleaned:
  * 1) mbuf that has been consumed by backend but not used by virtio.
diff --git a/drivers/net/virtio/virtqueue.h b/drivers/net/virtio/virtqueue.h
index f0bb089..62be136 100644
--- a/drivers/net/virtio/virtqueue.h
+++ b/drivers/net/virtio/virtqueue.h
@@ -274,7 +274,29 @@ vring_desc_init(struct vring_desc *dp, uint16_t n)
 /**
  * Tell the backend not to interrupt us.
  */
-void virtqueue_disable_intr(struct virtqueue *vq);
+static inline void
+virtqueue_disable_intr(struct virtqueue *vq)
+{
+	/* Set VRING_AVAIL_F_NO_INTERRUPT to hint host
+	 * not to interrupt when it consumes packets
+	 * Note: this is only considered a hint to the host
+	 */
+	vq->vq_ring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT;
+}
+
+/**
+ * Tell the backend to interrupt us.
+ */
+static inline void
+virtqueue_enable_intr(struct virtqueue *vq)
+{
+	/* Unset VRING_AVAIL_F_NO_INTERRUPT to hint host
+	 * to interrupt when it consumes packets
+	 * Note: this is only considered a hint to the host
+	 */
+	vq->vq_ring.avail->flags &= (~VRING_AVAIL_F_NO_INTERRUPT);
+}
+
 /**
  *  Dump virtqueue internal structures, for debug purpose only.
  */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v2 5/9] net/virtio: setup rxq interrupts
  2016-12-29  7:30 ` [PATCH v2 0/9] rxq interrupt mode for virtio PMD Jianfeng Tan
                     ` (3 preceding siblings ...)
  2016-12-29  7:30   ` [PATCH v2 4/9] net/virtio: add Rx queue intr enable/disable functions Jianfeng Tan
@ 2016-12-29  7:30   ` Jianfeng Tan
  2016-12-30  6:27     ` Yuanhan Liu
  2016-12-29  7:30   ` [PATCH v2 6/9] net/virtio: unbind intr/eventfd when stop device Jianfeng Tan
                     ` (5 subsequent siblings)
  10 siblings, 1 reply; 63+ messages in thread
From: Jianfeng Tan @ 2016-12-29  7:30 UTC (permalink / raw)
  To: dev; +Cc: yuanhan.liu, stephen, Jianfeng Tan

This patch mainly allocates structure to store queue/irq mapping,
and configure queue/irq mapping down through PCI ops. It also creates
eventfds for each Rx queue and tell the kernel about the eventfd/intr
binding.

Mostly importantly, different from previous NICs (usually implements
these logic in dev_start()), virtio's interrupt settings should be
configured down to QEMU before sending DRIVER_OK notification.

Note: We only support 1:1 queue/irq mapping so far, which means, each
rx queue has one exclusive interrupt (corresponding to irqfd in the
qemu/kvm) to get notified when packets are available on that queue.

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

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 3f8b90c..082346b 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1206,6 +1206,76 @@ rx_func_get(struct rte_eth_dev *eth_dev)
 		eth_dev->rx_pkt_burst = &virtio_recv_pkts;
 }
 
+/* Only support 1:1 queue/interrupt mapping so far.
+ * TODO: under below cases, lsc and rxq interrupt share one interrupt.
+ * a) binded to uio, igb_uio, vfio (type1);
+ * b) device only has one vec, see _vectors_ option in -device virtio-net-pci.
+ * TODO: support n:1 queue/interrupt mapping.
+ */
+static int
+virtio_queues_bind_intr(struct rte_eth_dev *dev)
+{
+	uint32_t i;
+	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+	struct virtio_hw *hw = dev->data->dev_private;
+
+	PMD_INIT_LOG(INFO, "queue/interrupt binding\n");
+	for (i = 0; i < dev->data->nb_rx_queues; ++i) {
+		intr_handle->intr_vec[i] = i + 1;
+		if (vtpci_irq_queue(hw->vqs[i * VTNET_CQ], i + 1) ==
+			VIRTIO_MSI_NO_VECTOR) {
+			PMD_DRV_LOG(ERR, "failed to set queue vector");
+			return -EBUSY;
+		}
+	}
+
+	return 0;
+}
+
+static int
+virtio_configure_intr(struct rte_eth_dev *dev)
+{
+	uint32_t intr_vector;
+	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+
+	/* check if rxq interrupt is enabled */
+	if (!rte_intr_cap_multiple(intr_handle)) {
+		PMD_INIT_LOG(ERR, "Multiple intr vector not supported");
+		return -ENOTSUP;
+	}
+
+	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 (!intr_handle->intr_vec) {
+		intr_handle->intr_vec =
+			rte_zmalloc("intr_vec", intr_vector * sizeof(int), 0);
+		if (!intr_handle->intr_vec) {
+			PMD_INIT_LOG(ERR, "Failed to allocate %d rxq vectors",
+				     intr_vector);
+			return -ENOMEM;
+		}
+	}
+
+	if (virtio_queues_bind_intr(dev) < 0) {
+		PMD_INIT_LOG(ERR, "Failed to bind queue/interrupt");
+		return -1;
+	}
+
+	/* DO NOT try remove this! This function will enable msix, or QEMU
+	 * will encounter SIGSEGV.
+	 */
+	if (rte_intr_enable(intr_handle) < 0) {
+		PMD_DRV_LOG(ERR, "interrupt enable failed");
+		return -1;
+	}
+
+	return 0;
+}
+
 /* reset device and renegotiate features if needed */
 static int
 virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
@@ -1299,6 +1369,17 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
 	ret = virtio_alloc_queues(eth_dev);
 	if (ret < 0)
 		return ret;
+
+	/* Make sure rxq interrupt is configured before sending DRIVER_OK,
+	 * so that QEMU can properly set those irq into kvm.
+	 */
+	if (eth_dev->data->dev_conf.intr_conf.rxq) {
+		if (virtio_configure_intr(eth_dev) < 0) {
+			PMD_INIT_LOG(ERR, "failed to configure interrupt");
+			return -1;
+		}
+	}
+
 	vtpci_reinit_complete(hw);
 
 	if (pci_dev)
@@ -1503,7 +1584,15 @@ virtio_dev_start(struct rte_eth_dev *dev)
 			PMD_DRV_LOG(ERR, "link status not supported by host");
 			return -ENOTSUP;
 		}
+	}
 
+	/* Enable uio/vfio intr/eventfd mapping: althrough we already did that
+	 * in device configure, but it could be unmapped  when device is
+	 * stopped.
+	 */
+	if (dev->data->dev_conf.intr_conf.lsc ||
+	    dev->data->dev_conf.intr_conf.rxq) {
+		rte_intr_disable(&dev->pci_dev->intr_handle);
 		if (rte_intr_enable(&dev->pci_dev->intr_handle) < 0) {
 			PMD_DRV_LOG(ERR, "interrupt enable failed");
 			return -EIO;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v2 6/9] net/virtio: unbind intr/eventfd when stop device
  2016-12-29  7:30 ` [PATCH v2 0/9] rxq interrupt mode for virtio PMD Jianfeng Tan
                     ` (4 preceding siblings ...)
  2016-12-29  7:30   ` [PATCH v2 5/9] net/virtio: setup rxq interrupts Jianfeng Tan
@ 2016-12-29  7:30   ` Jianfeng Tan
  2016-12-29  7:30   ` [PATCH v2 7/9] net/virtio: unmapping queue/irq when close device Jianfeng Tan
                     ` (4 subsequent siblings)
  10 siblings, 0 replies; 63+ messages in thread
From: Jianfeng Tan @ 2016-12-29  7:30 UTC (permalink / raw)
  To: dev; +Cc: yuanhan.liu, stephen, Jianfeng Tan

When virtio devices get stopped, we just tell the kernel to unbind
the mapping between interrupts and eventfds.

Note: it behaves differently from other NICs which close eventfds,
free struct. In virtio, we do those things when close device in
following patch.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/virtio/virtio_ethdev.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 082346b..0754ba0 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1686,11 +1686,13 @@ static void
 virtio_dev_stop(struct rte_eth_dev *dev)
 {
 	struct rte_eth_link link;
+	struct rte_intr_conf *intr_conf = &dev->data->dev_conf.intr_conf;
+	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
 
 	PMD_INIT_LOG(DEBUG, "stop");
 
-	if (dev->data->dev_conf.intr_conf.lsc)
-		rte_intr_disable(&dev->pci_dev->intr_handle);
+	if (intr_conf->lsc || intr_conf->rxq)
+		rte_intr_disable(intr_handle);
 
 	memset(&link, 0, sizeof(link));
 	virtio_dev_atomic_write_link_status(dev, &link);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v2 7/9] net/virtio: unmapping queue/irq when close device
  2016-12-29  7:30 ` [PATCH v2 0/9] rxq interrupt mode for virtio PMD Jianfeng Tan
                     ` (5 preceding siblings ...)
  2016-12-29  7:30   ` [PATCH v2 6/9] net/virtio: unbind intr/eventfd when stop device Jianfeng Tan
@ 2016-12-29  7:30   ` Jianfeng Tan
  2016-12-30  6:30     ` Yuanhan Liu
  2016-12-29  7:30   ` [PATCH v2 8/9] examples/l3fwd: add parse-ptype option Jianfeng Tan
                     ` (3 subsequent siblings)
  10 siblings, 1 reply; 63+ messages in thread
From: Jianfeng Tan @ 2016-12-29  7:30 UTC (permalink / raw)
  To: dev; +Cc: yuanhan.liu, stephen, Jianfeng Tan

When closing virtio devices, close eventfds, free the struct to
store queue/irq mapping.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/virtio/virtio_ethdev.c | 27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 0754ba0..d1a0afb 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -591,16 +591,30 @@ virtio_alloc_queues(struct rte_eth_dev *dev)
 	return 0;
 }
 
+static void virtio_queues_unbind_intr(struct rte_eth_dev *dev);
+
 static void
 virtio_dev_close(struct rte_eth_dev *dev)
 {
 	struct virtio_hw *hw = dev->data->dev_private;
+	struct rte_intr_conf *intr_conf = &dev->data->dev_conf.intr_conf;
+	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
 
 	PMD_INIT_LOG(DEBUG, "virtio_dev_close");
 
 	/* reset the NIC */
-	if (dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC)
+	if (intr_conf->lsc)
 		vtpci_irq_config(hw, VIRTIO_MSI_NO_VECTOR);
+	if (intr_conf->lsc)
+		virtio_queues_unbind_intr(dev);
+
+	if (intr_conf->lsc || intr_conf->rxq) {
+		rte_intr_disable(intr_handle);
+		rte_intr_efd_disable(intr_handle);
+		rte_free(intr_handle->intr_vec);
+		intr_handle->intr_vec = NULL;
+	}
+
 	vtpci_reset(hw);
 	virtio_dev_free_mbufs(dev);
 	virtio_free_queues(hw);
@@ -1232,6 +1246,17 @@ virtio_queues_bind_intr(struct rte_eth_dev *dev)
 	return 0;
 }
 
+static void
+virtio_queues_unbind_intr(struct rte_eth_dev *dev)
+{
+	uint32_t i;
+	struct virtio_hw *hw = dev->data->dev_private;
+
+	PMD_INIT_LOG(INFO, "queue/interrupt unbinding\n");
+	for (i = 0; i < dev->data->nb_rx_queues; ++i)
+		vtpci_irq_queue(hw->vqs[i * VTNET_CQ], VIRTIO_MSI_NO_VECTOR);
+}
+
 static int
 virtio_configure_intr(struct rte_eth_dev *dev)
 {
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v2 8/9] examples/l3fwd: add parse-ptype option
  2016-12-29  7:30 ` [PATCH v2 0/9] rxq interrupt mode for virtio PMD Jianfeng Tan
                     ` (6 preceding siblings ...)
  2016-12-29  7:30   ` [PATCH v2 7/9] net/virtio: unmapping queue/irq when close device Jianfeng Tan
@ 2016-12-29  7:30   ` Jianfeng Tan
  2016-12-30  6:39     ` Yuanhan Liu
  2016-12-29  7:30   ` [PATCH v2 9/9] examples/l3fwd-power: fix not stop and close device Jianfeng Tan
                     ` (2 subsequent siblings)
  10 siblings, 1 reply; 63+ messages in thread
From: Jianfeng Tan @ 2016-12-29  7:30 UTC (permalink / raw)
  To: dev; +Cc: yuanhan.liu, stephen, Jianfeng Tan

To support those devices that do not provide packet type info when
receiving packets, add a new option, --parse-ptype, to analyze
packet type in the Rx callback.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 examples/l3fwd-power/main.c | 60 ++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 59 insertions(+), 1 deletion(-)

diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c
index b65d683..44843ec 100644
--- a/examples/l3fwd-power/main.c
+++ b/examples/l3fwd-power/main.c
@@ -164,6 +164,8 @@ static uint32_t enabled_port_mask = 0;
 static int promiscuous_on = 0;
 /* NUMA is enabled by default. */
 static int numa_on = 1;
+static int parse_ptype; /**< Parse packet type using rx callback, and */
+			/**< disabled by default */
 
 enum freq_scale_hint_t
 {
@@ -607,6 +609,48 @@ get_ipv4_dst_port(struct ipv4_hdr *ipv4_hdr, uint8_t portid,
 #endif
 
 static inline void
+parse_ptype_one(struct rte_mbuf *m)
+{
+	struct ether_hdr *eth_hdr;
+	uint32_t packet_type = RTE_PTYPE_UNKNOWN;
+	uint16_t ether_type;
+
+	eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
+	ether_type = eth_hdr->ether_type;
+	if (ether_type == rte_cpu_to_be_16(ETHER_TYPE_IPv4))
+		packet_type |= RTE_PTYPE_L3_IPV4_EXT_UNKNOWN;
+	else if (ether_type == rte_cpu_to_be_16(ETHER_TYPE_IPv6))
+		packet_type |= RTE_PTYPE_L3_IPV6_EXT_UNKNOWN;
+
+	m->packet_type = packet_type;
+}
+
+static uint16_t
+cb_parse_ptype(uint8_t port __rte_unused, uint16_t queue __rte_unused,
+	       struct rte_mbuf *pkts[], uint16_t nb_pkts,
+	       uint16_t max_pkts __rte_unused,
+	       void *user_param __rte_unused)
+{
+	unsigned int i;
+
+	for (i = 0; i < nb_pkts; ++i)
+		parse_ptype_one(pkts[i]);
+
+	return nb_pkts;
+}
+
+static int
+add_cb_parse_ptype(uint8_t portid, uint16_t queueid)
+{
+	printf("Port %d: softly parse packet type info\n", portid);
+	if (rte_eth_add_rx_callback(portid, queueid, cb_parse_ptype, NULL))
+		return 0;
+
+	printf("Failed to add rx callback: port=%d\n", portid);
+	return -1;
+}
+
+static inline void
 l3fwd_simple_forward(struct rte_mbuf *m, uint8_t portid,
 				struct lcore_conf *qconf)
 {
@@ -1108,7 +1152,8 @@ print_usage(const char *prgname)
 		"  --config (port,queue,lcore): rx queues configuration\n"
 		"  --no-numa: optional, disable numa awareness\n"
 		"  --enable-jumbo: enable jumbo frame"
-		" which max packet len is PKTLEN in decimal (64-9600)\n",
+		" which max packet len is PKTLEN in decimal (64-9600)\n"
+		"  --parse-ptype: parse packet type by software\n",
 		prgname);
 }
 
@@ -1202,6 +1247,8 @@ parse_config(const char *q_arg)
 	return 0;
 }
 
+#define CMD_LINE_OPT_PARSE_PTYPE "parse-ptype"
+
 /* Parse the argument given in the command line of the application */
 static int
 parse_args(int argc, char **argv)
@@ -1214,6 +1261,7 @@ parse_args(int argc, char **argv)
 		{"config", 1, 0, 0},
 		{"no-numa", 0, 0, 0},
 		{"enable-jumbo", 0, 0, 0},
+		{CMD_LINE_OPT_PARSE_PTYPE, 0, 0, 0},
 		{NULL, 0, 0, 0}
 	};
 
@@ -1284,6 +1332,13 @@ parse_args(int argc, char **argv)
 				(unsigned int)port_conf.rxmode.max_rx_pkt_len);
 			}
 
+			if (!strncmp(lgopts[option_index].name,
+				     CMD_LINE_OPT_PARSE_PTYPE,
+				     sizeof(CMD_LINE_OPT_PARSE_PTYPE))) {
+				printf("soft parse-ptype is enabled\n");
+				parse_ptype = 1;
+			}
+
 			break;
 
 		default:
@@ -1716,6 +1771,9 @@ main(int argc, char **argv)
 				rte_exit(EXIT_FAILURE,
 					"rte_eth_rx_queue_setup: err=%d, "
 						"port=%d\n", ret, portid);
+
+			if (parse_ptype && add_cb_parse_ptype(portid, queueid))
+				rte_exit(EXIT_FAILURE, "Fail to add ptype cb\n");
 		}
 	}
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v2 9/9] examples/l3fwd-power: fix not stop and close device
  2016-12-29  7:30 ` [PATCH v2 0/9] rxq interrupt mode for virtio PMD Jianfeng Tan
                     ` (7 preceding siblings ...)
  2016-12-29  7:30   ` [PATCH v2 8/9] examples/l3fwd: add parse-ptype option Jianfeng Tan
@ 2016-12-29  7:30   ` Jianfeng Tan
  2016-12-30  6:44     ` Yuanhan Liu
  2016-12-29  7:42   ` [PATCH v2 0/9] rxq interrupt mode for virtio PMD Tan, Jianfeng
  2016-12-30  6:57   ` Yuanhan Liu
  10 siblings, 1 reply; 63+ messages in thread
From: Jianfeng Tan @ 2016-12-29  7:30 UTC (permalink / raw)
  To: dev; +Cc: yuanhan.liu, stephen, Jianfeng Tan

As it gets killed, in SIGINT signal handler, device is not stopped
and closed. In virtio's case, vector assignment in the KVM is not
deassigned.

This patch will invoke dev_stop() and dev_close() in signal handler.

Fixes: d7937e2e3d12 ("power: initial import")

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 examples/l3fwd-power/main.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c
index 44843ec..63e1796 100644
--- a/examples/l3fwd-power/main.c
+++ b/examples/l3fwd-power/main.c
@@ -379,6 +379,7 @@ static void
 signal_exit_now(int sigtype)
 {
 	unsigned lcore_id;
+	unsigned int portid, nb_ports;
 	int ret;
 
 	if (sigtype == SIGINT) {
@@ -393,6 +394,15 @@ signal_exit_now(int sigtype)
 					"library de-initialization failed on "
 							"core%u\n", lcore_id);
 		}
+
+		nb_ports = rte_eth_dev_count();
+		for (portid = 0; portid < nb_ports; portid++) {
+			if ((enabled_port_mask & (1 << portid)) == 0)
+				continue;
+
+			rte_eth_dev_stop(portid);
+			rte_eth_dev_close(portid);
+		}
 	}
 
 	rte_exit(EXIT_SUCCESS, "User forced exit\n");
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* Re: [PATCH v2 0/9] rxq interrupt mode for virtio PMD
  2016-12-29  7:30 ` [PATCH v2 0/9] rxq interrupt mode for virtio PMD Jianfeng Tan
                     ` (8 preceding siblings ...)
  2016-12-29  7:30   ` [PATCH v2 9/9] examples/l3fwd-power: fix not stop and close device Jianfeng Tan
@ 2016-12-29  7:42   ` Tan, Jianfeng
  2016-12-30  5:41     ` Yuanhan Liu
  2016-12-30  6:57   ` Yuanhan Liu
  10 siblings, 1 reply; 63+ messages in thread
From: Tan, Jianfeng @ 2016-12-29  7:42 UTC (permalink / raw)
  To: dev; +Cc: yuanhan.liu, stephen

Forget to mention a key part, when we bind virtio to vfio-pci driver in the VM, we need to insert vfio kernel module like this:

$ modprobe vfio enable_unsafe_noiommu_mode=1
$ modprobe vfio-pci

Thanks,
Jianfeng

> -----Original Message-----
> From: Tan, Jianfeng
> Sent: Thursday, December 29, 2016 3:31 PM
> To: dev@dpdk.org
> Cc: yuanhan.liu@linux.intel.com; stephen@networkplumber.org; Tan,
> Jianfeng
> Subject: [PATCH v2 0/9] rxq interrupt mode for virtio PMD
> 
> v2:
>   - Add PCI queue/irq config ops.
>   - Move rxq interrupt settings before sending DRIVER OK.
> 
> Historically, virtio PMD can only be binded to igb_uio or
> uio_pci_generic, and not for vfio-pci. Besides, quote from
> http://dpdk.org/doc/guides-16.11/rel_notes/release_2_1.html:
>   "Per queue RX interrupt events are only allowed in VFIO
>    which supports multiple MSI-X vectors."
> 
> As Linux starts to support vfio noiommu mode since 4.8.0, it's
> a good chance to enable rxq interrupt for virtio PMD.
> 
> How to test:
> 
> Step 1, prepare a VM image with kernel version >= 4.8.0.
> 
> Step 2, on the host, start a testpmd with a vhost port:
> $ testpmd -c 0x7 -m 1024 --vdev 'eth_vhost0,iface=/tmp/sock0,queues=2' \
> 	--no-pci -- -i --rxq=2 --txq=2 --nb-cores=2
> 
> Step 3, boot the VM:
> $ qemu ... -chardev socket,id=chr1,path=/tmp/sock0 \
> 	-netdev vhost-user,id=net1,chardev=chr1,vhostforce,queues=2 \
> 	-device virtio-net-pci,netdev=net1,mq=on,vectors=5 ...
> 
> Step 4, start l3fwd-power in VM:
> $ l3fwd-power -c 0x3 -n 4 -- -p 1 -P --config="(0,0,1),(0,1,1)" --no-numa
> 
> Step 5, send packets from testpmd on the host:
> $ start tx_first
> 
> Then l3fwd-power outputs:
> L3FWD_POWER: lcore 1 is waked up from rx interrupt on port 0 queue 0
> L3FWD_POWER: lcore 1 is waked up from rx interrupt on port 0 queue 1
> 
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> Jianfeng Tan (9):
>   net/virtio: fix rewriting LSC flag
>   net/virtio: add Rx descriptor check
>   net/virtio: add PCI ops for queue/irq binding
>   net/virtio: add Rx queue intr enable/disable functions
>   net/virtio: setup rxq interrupts
>   net/virtio: unbind intr/eventfd when stop device
>   net/virtio: unmapping queue/irq when close device
>   examples/l3fwd: add parse-ptype option
>   examples/l3fwd-power: fix not stop and close device
> 
>  drivers/net/virtio/virtio_ethdev.c | 149
> +++++++++++++++++++++++++++++++++++--
>  drivers/net/virtio/virtio_ethdev.h |   3 +
>  drivers/net/virtio/virtio_pci.c    |  29 ++++++++
>  drivers/net/virtio/virtio_pci.h    |   5 ++
>  drivers/net/virtio/virtio_rxtx.c   |   9 +++
>  drivers/net/virtio/virtqueue.c     |  11 ---
>  drivers/net/virtio/virtqueue.h     |  24 +++++-
>  examples/l3fwd-power/main.c        |  70 ++++++++++++++++-
>  8 files changed, 282 insertions(+), 18 deletions(-)
> 
> --
> 2.7.4

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v2 0/9] rxq interrupt mode for virtio PMD
  2016-12-29  7:42   ` [PATCH v2 0/9] rxq interrupt mode for virtio PMD Tan, Jianfeng
@ 2016-12-30  5:41     ` Yuanhan Liu
  0 siblings, 0 replies; 63+ messages in thread
From: Yuanhan Liu @ 2016-12-30  5:41 UTC (permalink / raw)
  To: Tan, Jianfeng; +Cc: dev, stephen

On Thu, Dec 29, 2016 at 07:42:51AM +0000, Tan, Jianfeng wrote:
> Forget to mention a key part, when we bind virtio to vfio-pci driver in the VM, we need to insert vfio kernel module like this:
> 
> $ modprobe vfio enable_unsafe_noiommu_mode=1
> $ modprobe vfio-pci

Such info should be documated somewhere, say maybe at
doc/guides/nics/virtio.rst

	--yliu

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v2 3/9] net/virtio: add PCI ops for queue/irq binding
  2016-12-29  7:30   ` [PATCH v2 3/9] net/virtio: add PCI ops for queue/irq binding Jianfeng Tan
@ 2016-12-30  5:46     ` Yuanhan Liu
  0 siblings, 0 replies; 63+ messages in thread
From: Yuanhan Liu @ 2016-12-30  5:46 UTC (permalink / raw)
  To: Jianfeng Tan; +Cc: dev, stephen

On Thu, Dec 29, 2016 at 07:30:37AM +0000, Jianfeng Tan wrote:
> Add handler in virtio_pci_ops to set queue/irq bind.
> 
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---
>  drivers/net/virtio/virtio_pci.c | 29 +++++++++++++++++++++++++++++
>  drivers/net/virtio/virtio_pci.h |  5 +++++
>  2 files changed, 34 insertions(+)
> 
> diff --git a/drivers/net/virtio/virtio_pci.c b/drivers/net/virtio/virtio_pci.c
> index 9b47165..4e706cf 100644
> --- a/drivers/net/virtio/virtio_pci.c
> +++ b/drivers/net/virtio/virtio_pci.c
> @@ -217,6 +217,18 @@ legacy_set_config_irq(struct virtio_hw *hw, uint16_t vec)
>  }
>  
>  static uint16_t
> +legacy_set_queue_irq(struct virtio_hw *hw, struct virtqueue *vq, uint16_t vec)
> +{
> +	uint16_t dst;
> +
> +	rte_eal_pci_ioport_write(&hw->io, &vq->vq_queue_index, 2,
> +			 VIRTIO_PCI_QUEUE_SEL);
> +	rte_eal_pci_ioport_write(&hw->io, &vec, 2, VIRTIO_MSI_QUEUE_VECTOR);
> +	rte_eal_pci_ioport_read(&hw->io, &dst, 2, VIRTIO_MSI_QUEUE_VECTOR);
> +	return dst;
> +}
> +
> +static uint16_t
>  legacy_get_queue_num(struct virtio_hw *hw, uint16_t queue_id)
>  {
>  	uint16_t dst;
> @@ -310,6 +322,7 @@ static const struct virtio_pci_ops legacy_ops = {
>  	.set_features	= legacy_set_features,
>  	.get_isr	= legacy_get_isr,
>  	.set_config_irq	= legacy_set_config_irq,
> +	.set_queue_irq = legacy_set_queue_irq,

Please keep the vertical alignment here.

>  	.get_queue_num	= legacy_get_queue_num,
>  	.setup_queue	= legacy_setup_queue,
>  	.del_queue	= legacy_del_queue,
> @@ -449,6 +462,15 @@ modern_set_config_irq(struct virtio_hw *hw, uint16_t vec)
>  }
>  
>  static uint16_t
> +modern_set_queue_irq(struct virtio_hw *hw, struct virtqueue *vq, uint16_t vec)
> +{
> +	PMD_INIT_LOG(INFO, "vq: %u, vec: %u", vq->vq_queue_index, vec);

Such debug info should not exist only in one callback. It should be
in the caller of this callback, before invoke it.

> +	io_write16(vq->vq_queue_index, &hw->common_cfg->queue_select);
> +	io_write16(vec, &hw->common_cfg->queue_msix_vector);
> +	return io_read16(&hw->common_cfg->queue_msix_vector);
> +}
> +
> +static uint16_t
>  modern_get_queue_num(struct virtio_hw *hw, uint16_t queue_id)
>  {
>  	io_write16(queue_id, &hw->common_cfg->queue_select);
> @@ -526,6 +548,7 @@ static const struct virtio_pci_ops modern_ops = {
>  	.set_features	= modern_set_features,
>  	.get_isr	= modern_get_isr,
>  	.set_config_irq	= modern_set_config_irq,
> +	.set_queue_irq = modern_set_queue_irq,

Ditto.

>  	.get_queue_num	= modern_get_queue_num,
>  	.setup_queue	= modern_setup_queue,
>  	.del_queue	= modern_del_queue,
> @@ -605,6 +628,12 @@ vtpci_irq_config(struct virtio_hw *hw, uint16_t vec)
>  	return hw->vtpci_ops->set_config_irq(hw, vec);
>  }
>  
> +uint16_t
> +vtpci_irq_queue(struct virtqueue *vq, uint16_t vec)
> +{
> +	return vq->hw->vtpci_ops->set_queue_irq(vq->hw, vq, vec);
> +}

No need to introduce a wrapper for a vtpci_ops, instead, just invoke
it directly.

	--yliu

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v2 4/9] net/virtio: add Rx queue intr enable/disable functions
  2016-12-29  7:30   ` [PATCH v2 4/9] net/virtio: add Rx queue intr enable/disable functions Jianfeng Tan
@ 2016-12-30  5:59     ` Yuanhan Liu
  0 siblings, 0 replies; 63+ messages in thread
From: Yuanhan Liu @ 2016-12-30  5:59 UTC (permalink / raw)
  To: Jianfeng Tan; +Cc: dev, stephen

On Thu, Dec 29, 2016 at 07:30:38AM +0000, Jianfeng Tan wrote:
>  /*
>   * Two types of mbuf to be cleaned:
>   * 1) mbuf that has been consumed by backend but not used by virtio.
> diff --git a/drivers/net/virtio/virtqueue.h b/drivers/net/virtio/virtqueue.h
> index f0bb089..62be136 100644
> --- a/drivers/net/virtio/virtqueue.h
> +++ b/drivers/net/virtio/virtqueue.h
> @@ -274,7 +274,29 @@ vring_desc_init(struct vring_desc *dp, uint16_t n)
>  /**
>   * Tell the backend not to interrupt us.
>   */
> -void virtqueue_disable_intr(struct virtqueue *vq);
> +static inline void
> +virtqueue_disable_intr(struct virtqueue *vq)
> +{
> +	/* Set VRING_AVAIL_F_NO_INTERRUPT to hint host
> +	 * not to interrupt when it consumes packets
> +	 * Note: this is only considered a hint to the host
> +	 */
> +	vq->vq_ring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT;
> +}
> +
> +/**
> + * Tell the backend to interrupt us.
> + */
> +static inline void
> +virtqueue_enable_intr(struct virtqueue *vq)
> +{
> +	/* Unset VRING_AVAIL_F_NO_INTERRUPT to hint host
> +	 * to interrupt when it consumes packets
> +	 * Note: this is only considered a hint to the host
> +	 */

This kind of comment is a bit weird to me; it becomes weird-er when it
appears twice. Maybe we could just drop it, as the code already expains
it well (disabling interrupt regarding to NO_INTERRUPT). Or, you could
combine the two and write one comment before the two functions.

	--yliu

> +	vq->vq_ring.avail->flags &= (~VRING_AVAIL_F_NO_INTERRUPT);
> +}
> +
>  /**
>   *  Dump virtqueue internal structures, for debug purpose only.
>   */
> -- 
> 2.7.4

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v2 5/9] net/virtio: setup rxq interrupts
  2016-12-29  7:30   ` [PATCH v2 5/9] net/virtio: setup rxq interrupts Jianfeng Tan
@ 2016-12-30  6:27     ` Yuanhan Liu
  2017-01-04  6:56       ` Tan, Jianfeng
  0 siblings, 1 reply; 63+ messages in thread
From: Yuanhan Liu @ 2016-12-30  6:27 UTC (permalink / raw)
  To: Jianfeng Tan; +Cc: dev, stephen

On Thu, Dec 29, 2016 at 07:30:39AM +0000, Jianfeng Tan wrote:
> This patch mainly allocates structure to store queue/irq mapping,
> and configure queue/irq mapping down through PCI ops. It also creates
> eventfds for each Rx queue and tell the kernel about the eventfd/intr
> binding.
> 
> Mostly importantly, different from previous NICs (usually implements
> these logic in dev_start()), virtio's interrupt settings should be
> configured down to QEMU before sending DRIVER_OK notification.

Isn't it obvious we have to have all driver stuff (including interrupt
settings) configured properly before setting DRIVER_OK? :) That said,
it's meanless to state the fact that virtio acts differently than other
nics here on dev_start/stop.

> Note: We only support 1:1 queue/irq mapping so far, which means, each
> rx queue has one exclusive interrupt (corresponding to irqfd in the
> qemu/kvm) to get notified when packets are available on that queue.

That means you have to setup the "vectors=N" option has to set correctly
in QEMU, otherwise it won't work? If so, you also have to doc it somewhere.

> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---
>  drivers/net/virtio/virtio_ethdev.c | 89 ++++++++++++++++++++++++++++++++++++++
>  1 file changed, 89 insertions(+)
> 
> diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
> index 3f8b90c..082346b 100644
> --- a/drivers/net/virtio/virtio_ethdev.c
> +++ b/drivers/net/virtio/virtio_ethdev.c
> @@ -1206,6 +1206,76 @@ rx_func_get(struct rte_eth_dev *eth_dev)
>  		eth_dev->rx_pkt_burst = &virtio_recv_pkts;
>  }
>  
> +/* Only support 1:1 queue/interrupt mapping so far.
> + * TODO: under below cases, lsc and rxq interrupt share one interrupt.
> + * a) binded to uio, igb_uio, vfio (type1);
> + * b) device only has one vec, see _vectors_ option in -device virtio-net-pci.
> + * TODO: support n:1 queue/interrupt mapping.

Both TODOs are actually the same: supporting n:1 mapping. That said, you
don't have to write 2 TODOs here. Please, don't be mean by adding some
whitespace lines.

> + */
> +static int
> +virtio_queues_bind_intr(struct rte_eth_dev *dev)
> +{
> +	uint32_t i;
> +	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
> +	struct virtio_hw *hw = dev->data->dev_private;
> +
> +	PMD_INIT_LOG(INFO, "queue/interrupt binding\n");
> +	for (i = 0; i < dev->data->nb_rx_queues; ++i) {
> +		intr_handle->intr_vec[i] = i + 1;
> +		if (vtpci_irq_queue(hw->vqs[i * VTNET_CQ], i + 1) ==

It's logically wrong to use VTNET_CQ to get the Rx queue index. You
could either use 2 simply, or define a macro for that.


> +			VIRTIO_MSI_NO_VECTOR) {
> +			PMD_DRV_LOG(ERR, "failed to set queue vector");
> +			return -EBUSY;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +static int
> +virtio_configure_intr(struct rte_eth_dev *dev)
> +{
> +	uint32_t intr_vector;
> +	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
> +
> +	/* check if rxq interrupt is enabled */

Unnecessary comment, the function name and the error log explains it
well.

> +	if (!rte_intr_cap_multiple(intr_handle)) {
> +		PMD_INIT_LOG(ERR, "Multiple intr vector not supported");
> +		return -ENOTSUP;
> +	}
> +
> +	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 (!intr_handle->intr_vec) {
> +		intr_handle->intr_vec =
> +			rte_zmalloc("intr_vec", intr_vector * sizeof(int), 0);
> +		if (!intr_handle->intr_vec) {
> +			PMD_INIT_LOG(ERR, "Failed to allocate %d rxq vectors",
> +				     intr_vector);
> +			return -ENOMEM;
> +		}
> +	}
> +
> +	if (virtio_queues_bind_intr(dev) < 0) {
> +		PMD_INIT_LOG(ERR, "Failed to bind queue/interrupt");
> +		return -1;

You have to free intr_handle->intr_vec, otherwise, memory leak occurs.

> +	}
> +
> +	/* DO NOT try remove this! This function will enable msix, or QEMU
> +	 * will encounter SIGSEGV.
> +	 */

Looks like a QEMU bug to me. I mean, even though the driver is badly
configured, it should not crash QEMU.

> +	if (rte_intr_enable(intr_handle) < 0) {
> +		PMD_DRV_LOG(ERR, "interrupt enable failed");
> +		return -1;
> +	}
> +
> +	return 0;
> +}
> +
>  /* reset device and renegotiate features if needed */
>  static int
>  virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
> @@ -1299,6 +1369,17 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
>  	ret = virtio_alloc_queues(eth_dev);
>  	if (ret < 0)
>  		return ret;
> +
> +	/* Make sure rxq interrupt is configured before sending DRIVER_OK,
> +	 * so that QEMU can properly set those irq into kvm.
> +	 */

As said, I don't think such comment is needed: for sure, we have to
setup everything properly (about the device) before setting the
DRIVER_OK flag. 

> +	if (eth_dev->data->dev_conf.intr_conf.rxq) {
> +		if (virtio_configure_intr(eth_dev) < 0) {
> +			PMD_INIT_LOG(ERR, "failed to configure interrupt");
> +			return -1;
> +		}
> +	}
> +
>  	vtpci_reinit_complete(hw);
>  
>  	if (pci_dev)
> @@ -1503,7 +1584,15 @@ virtio_dev_start(struct rte_eth_dev *dev)
>  			PMD_DRV_LOG(ERR, "link status not supported by host");
>  			return -ENOTSUP;
>  		}
> +	}
>  
> +	/* Enable uio/vfio intr/eventfd mapping: althrough we already did that
> +	 * in device configure, but it could be unmapped  when device is
> +	 * stopped.

Well, I didn't see you do that; I did see you do that in next patch though.
That said, the next patch should be merged here, into one patch.

	--yliu
> +	 */
> +	if (dev->data->dev_conf.intr_conf.lsc ||
> +	    dev->data->dev_conf.intr_conf.rxq) {
> +		rte_intr_disable(&dev->pci_dev->intr_handle);
>  		if (rte_intr_enable(&dev->pci_dev->intr_handle) < 0) {
>  			PMD_DRV_LOG(ERR, "interrupt enable failed");
>  			return -EIO;
> -- 
> 2.7.4

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v2 7/9] net/virtio: unmapping queue/irq when close device
  2016-12-29  7:30   ` [PATCH v2 7/9] net/virtio: unmapping queue/irq when close device Jianfeng Tan
@ 2016-12-30  6:30     ` Yuanhan Liu
  0 siblings, 0 replies; 63+ messages in thread
From: Yuanhan Liu @ 2016-12-30  6:30 UTC (permalink / raw)
  To: Jianfeng Tan; +Cc: dev, stephen

On Thu, Dec 29, 2016 at 07:30:41AM +0000, Jianfeng Tan wrote:
> When closing virtio devices, close eventfds, free the struct to
> store queue/irq mapping.
> 
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---
>  drivers/net/virtio/virtio_ethdev.c | 27 ++++++++++++++++++++++++++-
>  1 file changed, 26 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
> index 0754ba0..d1a0afb 100644
> --- a/drivers/net/virtio/virtio_ethdev.c
> +++ b/drivers/net/virtio/virtio_ethdev.c
> @@ -591,16 +591,30 @@ virtio_alloc_queues(struct rte_eth_dev *dev)
>  	return 0;
>  }
>  
> +static void virtio_queues_unbind_intr(struct rte_eth_dev *dev);
> +
>  static void
>  virtio_dev_close(struct rte_eth_dev *dev)
>  {
>  	struct virtio_hw *hw = dev->data->dev_private;
> +	struct rte_intr_conf *intr_conf = &dev->data->dev_conf.intr_conf;
> +	struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;

I saw quite many occurrence of the two, maybe you could define few
macros for that, say VIRTIO_INTR_ENABLED, VIRTIO_RX_INTR_ENABLED,
VIRTIO_LSC_INTR_ENABLED?

	--yliu

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v2 8/9] examples/l3fwd: add parse-ptype option
  2016-12-29  7:30   ` [PATCH v2 8/9] examples/l3fwd: add parse-ptype option Jianfeng Tan
@ 2016-12-30  6:39     ` Yuanhan Liu
  2016-12-30  7:30       ` Tan, Jianfeng
  0 siblings, 1 reply; 63+ messages in thread
From: Yuanhan Liu @ 2016-12-30  6:39 UTC (permalink / raw)
  To: Jianfeng Tan; +Cc: dev, stephen

On Thu, Dec 29, 2016 at 07:30:42AM +0000, Jianfeng Tan wrote:
> To support those devices that do not provide packet type info when
> receiving packets, add a new option, --parse-ptype, to analyze
> packet type in the Rx callback.

I think this would be needed for all PMD drivers don't have the PTYPE
support. For these, --parse-ptype looks like a mandatory option in
the l3fwd example. I didn't find such option given in your test guide
though, which is weird. Mistake?

Besides that, is there a way to query whether a PMD supports PTYPE
or not? If not, we should add a software one by our own. This could
be done without introducing yet another option.

> 
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---
>  examples/l3fwd-power/main.c | 60 ++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 59 insertions(+), 1 deletion(-)
> 
> diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c
> index b65d683..44843ec 100644
> --- a/examples/l3fwd-power/main.c
> +++ b/examples/l3fwd-power/main.c
> @@ -164,6 +164,8 @@ static uint32_t enabled_port_mask = 0;
>  static int promiscuous_on = 0;
>  /* NUMA is enabled by default. */
>  static int numa_on = 1;
> +static int parse_ptype; /**< Parse packet type using rx callback, and */
> +			/**< disabled by default */
>  
>  enum freq_scale_hint_t
>  {
> @@ -607,6 +609,48 @@ get_ipv4_dst_port(struct ipv4_hdr *ipv4_hdr, uint8_t portid,
>  #endif
>  
>  static inline void
> +parse_ptype_one(struct rte_mbuf *m)
> +{
> +	struct ether_hdr *eth_hdr;
> +	uint32_t packet_type = RTE_PTYPE_UNKNOWN;
> +	uint16_t ether_type;
> +
> +	eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
> +	ether_type = eth_hdr->ether_type;
> +	if (ether_type == rte_cpu_to_be_16(ETHER_TYPE_IPv4))
> +		packet_type |= RTE_PTYPE_L3_IPV4_EXT_UNKNOWN;
> +	else if (ether_type == rte_cpu_to_be_16(ETHER_TYPE_IPv6))
> +		packet_type |= RTE_PTYPE_L3_IPV6_EXT_UNKNOWN;

BTW, we have rte_net_get_ptype(). Looks like a better option?

	--yliu

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v2 9/9] examples/l3fwd-power: fix not stop and close device
  2016-12-29  7:30   ` [PATCH v2 9/9] examples/l3fwd-power: fix not stop and close device Jianfeng Tan
@ 2016-12-30  6:44     ` Yuanhan Liu
  2016-12-30  6:56       ` Tan, Jianfeng
  0 siblings, 1 reply; 63+ messages in thread
From: Yuanhan Liu @ 2016-12-30  6:44 UTC (permalink / raw)
  To: Jianfeng Tan; +Cc: dev, stephen

On Thu, Dec 29, 2016 at 07:30:43AM +0000, Jianfeng Tan wrote:
> As it gets killed, in SIGINT signal handler, device is not stopped
> and closed. In virtio's case, vector assignment in the KVM is not
> deassigned.

What wrong could happen then?

> This patch will invoke dev_stop() and dev_close() in signal handler.

I will just say, it may workaround the bug you encountered, particulary,
for this example only. If some people want to use the virtio interrupt
somewhere at another app, he also has to do similar thing.

Is there a more clean way to handle such case in the driver?

	--yliu

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v2 9/9] examples/l3fwd-power: fix not stop and close device
  2016-12-30  6:44     ` Yuanhan Liu
@ 2016-12-30  6:56       ` Tan, Jianfeng
  0 siblings, 0 replies; 63+ messages in thread
From: Tan, Jianfeng @ 2016-12-30  6:56 UTC (permalink / raw)
  To: Yuanhan Liu; +Cc: dev, stephen


> -----Original Message-----
> From: Yuanhan Liu [mailto:yuanhan.liu@linux.intel.com]
> Sent: Friday, December 30, 2016 2:45 PM
> To: Tan, Jianfeng
> Cc: dev@dpdk.org; stephen@networkplumber.org
> Subject: Re: [PATCH v2 9/9] examples/l3fwd-power: fix not stop and close
> device
> 
> On Thu, Dec 29, 2016 at 07:30:43AM +0000, Jianfeng Tan wrote:
> > As it gets killed, in SIGINT signal handler, device is not stopped
> > and closed. In virtio's case, vector assignment in the KVM is not
> > deassigned.
> 
> What wrong could happen then?

Actually, no strange things happen so far. My purpose for this patch is to verify that irqfd is deassigned.
And as calling dev_stop() and dev_close() is a good practice, so I use the word "fix" here.

> 
> > This patch will invoke dev_stop() and dev_close() in signal handler.
> 
> I will just say, it may workaround the bug you encountered, particulary,
> for this example only.

There's no bug to work around.

> If some people want to use the virtio interrupt
> somewhere at another app, he also has to do similar thing.

Vfio-pci is the best place to put device into original state, but is it really necessary to do that? If another program takes over that device, it will be re-initialized.

> 
> Is there a more clean way to handle such case in the driver?

Let's do with the necessity firstly.

Thanks,
Jianfeng

> 
> 	--yliu

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v2 0/9] rxq interrupt mode for virtio PMD
  2016-12-29  7:30 ` [PATCH v2 0/9] rxq interrupt mode for virtio PMD Jianfeng Tan
                     ` (9 preceding siblings ...)
  2016-12-29  7:42   ` [PATCH v2 0/9] rxq interrupt mode for virtio PMD Tan, Jianfeng
@ 2016-12-30  6:57   ` Yuanhan Liu
  10 siblings, 0 replies; 63+ messages in thread
From: Yuanhan Liu @ 2016-12-30  6:57 UTC (permalink / raw)
  To: Jianfeng Tan; +Cc: dev, stephen

On Thu, Dec 29, 2016 at 07:30:34AM +0000, Jianfeng Tan wrote:
> v2:
>   - Add PCI queue/irq config ops.
>   - Move rxq interrupt settings before sending DRIVER OK.
> 
> Historically, virtio PMD can only be binded to igb_uio or
> uio_pci_generic, and not for vfio-pci. Besides, quote from
> http://dpdk.org/doc/guides-16.11/rel_notes/release_2_1.html:
>   "Per queue RX interrupt events are only allowed in VFIO
>    which supports multiple MSI-X vectors."
> 
> As Linux starts to support vfio noiommu mode since 4.8.0, it's
> a good chance to enable rxq interrupt for virtio PMD.

This cover letter (as well as all the commit logs) lacks an _overall_
introducation of how the Rx interrupt works in virtio, say how things
are setup, etc.

	--yliu
> 
> How to test:
> 
> Step 1, prepare a VM image with kernel version >= 4.8.0.
> 
> Step 2, on the host, start a testpmd with a vhost port:
> $ testpmd -c 0x7 -m 1024 --vdev 'eth_vhost0,iface=/tmp/sock0,queues=2' \
> 	--no-pci -- -i --rxq=2 --txq=2 --nb-cores=2
> 
> Step 3, boot the VM:
> $ qemu ... -chardev socket,id=chr1,path=/tmp/sock0 \
> 	-netdev vhost-user,id=net1,chardev=chr1,vhostforce,queues=2 \
> 	-device virtio-net-pci,netdev=net1,mq=on,vectors=5 ...
> 
> Step 4, start l3fwd-power in VM:
> $ l3fwd-power -c 0x3 -n 4 -- -p 1 -P --config="(0,0,1),(0,1,1)" --no-numa
> 
> Step 5, send packets from testpmd on the host:
> $ start tx_first
> 
> Then l3fwd-power outputs:
> L3FWD_POWER: lcore 1 is waked up from rx interrupt on port 0 queue 0
> L3FWD_POWER: lcore 1 is waked up from rx interrupt on port 0 queue 1
> 
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> Jianfeng Tan (9):
>   net/virtio: fix rewriting LSC flag
>   net/virtio: add Rx descriptor check
>   net/virtio: add PCI ops for queue/irq binding
>   net/virtio: add Rx queue intr enable/disable functions
>   net/virtio: setup rxq interrupts
>   net/virtio: unbind intr/eventfd when stop device
>   net/virtio: unmapping queue/irq when close device
>   examples/l3fwd: add parse-ptype option
>   examples/l3fwd-power: fix not stop and close device
> 
>  drivers/net/virtio/virtio_ethdev.c | 149 +++++++++++++++++++++++++++++++++++--
>  drivers/net/virtio/virtio_ethdev.h |   3 +
>  drivers/net/virtio/virtio_pci.c    |  29 ++++++++
>  drivers/net/virtio/virtio_pci.h    |   5 ++
>  drivers/net/virtio/virtio_rxtx.c   |   9 +++
>  drivers/net/virtio/virtqueue.c     |  11 ---
>  drivers/net/virtio/virtqueue.h     |  24 +++++-
>  examples/l3fwd-power/main.c        |  70 ++++++++++++++++-
>  8 files changed, 282 insertions(+), 18 deletions(-)
> 
> -- 
> 2.7.4

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v2 8/9] examples/l3fwd: add parse-ptype option
  2016-12-30  6:39     ` Yuanhan Liu
@ 2016-12-30  7:30       ` Tan, Jianfeng
  2017-01-03  6:59         ` Yuanhan Liu
  0 siblings, 1 reply; 63+ messages in thread
From: Tan, Jianfeng @ 2016-12-30  7:30 UTC (permalink / raw)
  To: Yuanhan Liu; +Cc: dev, stephen

Hi,

> -----Original Message-----
> From: Yuanhan Liu [mailto:yuanhan.liu@linux.intel.com]
> Sent: Friday, December 30, 2016 2:40 PM
> To: Tan, Jianfeng
> Cc: dev@dpdk.org; stephen@networkplumber.org
> Subject: Re: [PATCH v2 8/9] examples/l3fwd: add parse-ptype option
> 
> On Thu, Dec 29, 2016 at 07:30:42AM +0000, Jianfeng Tan wrote:
> > To support those devices that do not provide packet type info when
> > receiving packets, add a new option, --parse-ptype, to analyze
> > packet type in the Rx callback.
> 
> I think this would be needed for all PMD drivers don't have the PTYPE
> support. For these, --parse-ptype looks like a mandatory option in
> the l3fwd example. I didn't find such option given in your test guide
> though, which is weird. Mistake?

Oops, my fault, it should be used with this option. As I just cared about if packets are received, instead of what types of packets are received, so I missed that. I'll fix it.

> 
> Besides that, is there a way to query whether a PMD supports PTYPE
> or not? 

Yes, we have API rte_eth_dev_get_supported_ptypes() to do that. This patch is to emulate the commit 71a7e2424e07 ("examples/l3fwd: fix using packet type blindly").

As we talked offline, I'll leverage this API to query if device support needed ptypes, if not, register callback to analysis ptypes. This avoids to use another option. But for record, this also leads to un-consistent behavior with l3fwd.

Thanks,
Jianfeng
> If not, we should add a software one by our own. This could
> be done without introducing yet another option.
> 
> >
> > Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> > ---
> >  examples/l3fwd-power/main.c | 60
> ++++++++++++++++++++++++++++++++++++++++++++-
> >  1 file changed, 59 insertions(+), 1 deletion(-)
> >
> > diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-
> power/main.c
> > index b65d683..44843ec 100644
> > --- a/examples/l3fwd-power/main.c
> > +++ b/examples/l3fwd-power/main.c
> > @@ -164,6 +164,8 @@ static uint32_t enabled_port_mask = 0;
> >  static int promiscuous_on = 0;
> >  /* NUMA is enabled by default. */
> >  static int numa_on = 1;
> > +static int parse_ptype; /**< Parse packet type using rx callback, and */
> > +			/**< disabled by default */
> >
> >  enum freq_scale_hint_t
> >  {
> > @@ -607,6 +609,48 @@ get_ipv4_dst_port(struct ipv4_hdr *ipv4_hdr,
> uint8_t portid,
> >  #endif
> >
> >  static inline void
> > +parse_ptype_one(struct rte_mbuf *m)
> > +{
> > +	struct ether_hdr *eth_hdr;
> > +	uint32_t packet_type = RTE_PTYPE_UNKNOWN;
> > +	uint16_t ether_type;
> > +
> > +	eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
> > +	ether_type = eth_hdr->ether_type;
> > +	if (ether_type == rte_cpu_to_be_16(ETHER_TYPE_IPv4))
> > +		packet_type |= RTE_PTYPE_L3_IPV4_EXT_UNKNOWN;
> > +	else if (ether_type == rte_cpu_to_be_16(ETHER_TYPE_IPv6))
> > +		packet_type |= RTE_PTYPE_L3_IPV6_EXT_UNKNOWN;
> 
> BTW, we have rte_net_get_ptype(). Looks like a better option?
> 
> 	--yliu

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v2 8/9] examples/l3fwd: add parse-ptype option
  2016-12-30  7:30       ` Tan, Jianfeng
@ 2017-01-03  6:59         ` Yuanhan Liu
  0 siblings, 0 replies; 63+ messages in thread
From: Yuanhan Liu @ 2017-01-03  6:59 UTC (permalink / raw)
  To: Tan, Jianfeng; +Cc: dev, stephen, Thomas Monjalon

On Fri, Dec 30, 2016 at 07:30:19AM +0000, Tan, Jianfeng wrote:
> Hi,
> 
> > -----Original Message-----
> > From: Yuanhan Liu [mailto:yuanhan.liu@linux.intel.com]
> > Sent: Friday, December 30, 2016 2:40 PM
> > To: Tan, Jianfeng
> > Cc: dev@dpdk.org; stephen@networkplumber.org
> > Subject: Re: [PATCH v2 8/9] examples/l3fwd: add parse-ptype option
> > 
> > On Thu, Dec 29, 2016 at 07:30:42AM +0000, Jianfeng Tan wrote:
> > > To support those devices that do not provide packet type info when
> > > receiving packets, add a new option, --parse-ptype, to analyze
> > > packet type in the Rx callback.
> > 
> > I think this would be needed for all PMD drivers don't have the PTYPE
> > support. For these, --parse-ptype looks like a mandatory option in
> > the l3fwd example. I didn't find such option given in your test guide
> > though, which is weird. Mistake?
> 
> Oops, my fault, it should be used with this option. As I just cared about if packets are received, instead of what types of packets are received, so I missed that. I'll fix it.
> 
> > 
> > Besides that, is there a way to query whether a PMD supports PTYPE
> > or not? 
> 
> Yes, we have API rte_eth_dev_get_supported_ptypes() to do that. This patch is to emulate the commit 71a7e2424e07 ("examples/l3fwd: fix using packet type blindly").
> 
> As we talked offline, I'll leverage this API to query if device support needed ptypes, if not, register callback to analysis ptypes. This avoids to use another option.

...
> But for record, this also leads to un-consistent behavior with l3fwd.

Yes, and I think we should keep it consistent to l3fwd and all its
variants. Just think it this way: those variants don't do that will
not work with virtio PMD (and others don't have the PTYPE support).

That said, you could split this patch set to two sets: one for
adding the support of virtio interrupt, another one for fixing the
l3fwd (and its variants) for some PMDs don't have PTYPE support.

OTOH, that's the typical issue we will meet when we make same code
multiple copies, one for demonstrating one specific feature (or
something like that): it's a bit painful if we need change something
common in all copies.

	--yliu

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v2 5/9] net/virtio: setup rxq interrupts
  2016-12-30  6:27     ` Yuanhan Liu
@ 2017-01-04  6:56       ` Tan, Jianfeng
  2017-01-04  7:22         ` Yuanhan Liu
  0 siblings, 1 reply; 63+ messages in thread
From: Tan, Jianfeng @ 2017-01-04  6:56 UTC (permalink / raw)
  To: Yuanhan Liu; +Cc: dev, stephen



On 12/30/2016 2:27 PM, Yuanhan Liu wrote:
> On Thu, Dec 29, 2016 at 07:30:39AM +0000, Jianfeng Tan wrote:
>> This patch mainly allocates structure to store queue/irq mapping,
>> and configure queue/irq mapping down through PCI ops. It also creates
>> eventfds for each Rx queue and tell the kernel about the eventfd/intr
>> binding.
>>
>> Mostly importantly, different from previous NICs (usually implements
>> these logic in dev_start()), virtio's interrupt settings should be
>> configured down to QEMU before sending DRIVER_OK notification.
> Isn't it obvious we have to have all driver stuff (including interrupt
> settings) configured properly before setting DRIVER_OK? :) That said,
> it's meanless to state the fact that virtio acts differently than other
> nics here on dev_start/stop.
>
>> Note: We only support 1:1 queue/irq mapping so far, which means, each
>> rx queue has one exclusive interrupt (corresponding to irqfd in the
>> qemu/kvm) to get notified when packets are available on that queue.
> That means you have to setup the "vectors=N" option has to set correctly
> in QEMU, otherwise it won't work?

Yes, actually, the correct value should be "vectors>=N+1", with N 
standing for the number of queue pairs. It's due to the hard coded 
mapping logic:
0 -> config irq
1 -> rxq0
2 -> rxq1
...

>   If so, you also have to doc it somewhere.

Agreed.

[...]
>> +
>> +	if (virtio_queues_bind_intr(dev) < 0) {
>> +		PMD_INIT_LOG(ERR, "Failed to bind queue/interrupt");
>> +		return -1;
> You have to free intr_handle->intr_vec, otherwise, memory leak occurs.

It's freed at dev_close(). Do you mean freeing and reallocating here? As 
nr_rx_queues is not a changeable value, I don't see the necessity here. 
I miss something?

Thanks,
Jianfeng

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v2 5/9] net/virtio: setup rxq interrupts
  2017-01-04  6:56       ` Tan, Jianfeng
@ 2017-01-04  7:22         ` Yuanhan Liu
  2017-01-04  7:30           ` Tan, Jianfeng
  0 siblings, 1 reply; 63+ messages in thread
From: Yuanhan Liu @ 2017-01-04  7:22 UTC (permalink / raw)
  To: Tan, Jianfeng; +Cc: dev, stephen

On Wed, Jan 04, 2017 at 02:56:50PM +0800, Tan, Jianfeng wrote:
> 
> 
> On 12/30/2016 2:27 PM, Yuanhan Liu wrote:
> >On Thu, Dec 29, 2016 at 07:30:39AM +0000, Jianfeng Tan wrote:
> >>This patch mainly allocates structure to store queue/irq mapping,
> >>and configure queue/irq mapping down through PCI ops. It also creates
> >>eventfds for each Rx queue and tell the kernel about the eventfd/intr
> >>binding.
> >>
> >>Mostly importantly, different from previous NICs (usually implements
> >>these logic in dev_start()), virtio's interrupt settings should be
> >>configured down to QEMU before sending DRIVER_OK notification.
> >Isn't it obvious we have to have all driver stuff (including interrupt
> >settings) configured properly before setting DRIVER_OK? :) That said,
> >it's meanless to state the fact that virtio acts differently than other
> >nics here on dev_start/stop.
> >
> >>Note: We only support 1:1 queue/irq mapping so far, which means, each
> >>rx queue has one exclusive interrupt (corresponding to irqfd in the
> >>qemu/kvm) to get notified when packets are available on that queue.
> >That means you have to setup the "vectors=N" option has to set correctly
> >in QEMU, otherwise it won't work?
> 
> Yes, actually, the correct value should be "vectors>=N+1", with N standing

Yeah, and it's a typo.

> for the number of queue pairs. It's due to the hard coded mapping logic:
> 0 -> config irq
> 1 -> rxq0
> 2 -> rxq1
> ...
> 
> >  If so, you also have to doc it somewhere.
> 
> Agreed.
> 
> [...]
> >>+
> >>+	if (virtio_queues_bind_intr(dev) < 0) {
> >>+		PMD_INIT_LOG(ERR, "Failed to bind queue/interrupt");
> >>+		return -1;
> >You have to free intr_handle->intr_vec, otherwise, memory leak occurs.
> 
> It's freed at dev_close(). Do you mean freeing and reallocating here? As

The typical way is free the resources have been allocated when errors
happens.

> nr_rx_queues is not a changeable value, I don't see the necessity here. I
> miss something?

No. nb_rx_queues does change, when people reconfigure the queue number.
However, the MAX queues the virito supports does not change. You could
use that number for allocation.

	--yliu

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v2 5/9] net/virtio: setup rxq interrupts
  2017-01-04  7:22         ` Yuanhan Liu
@ 2017-01-04  7:30           ` Tan, Jianfeng
  0 siblings, 0 replies; 63+ messages in thread
From: Tan, Jianfeng @ 2017-01-04  7:30 UTC (permalink / raw)
  To: Yuanhan Liu; +Cc: dev, stephen



> -----Original Message-----
> From: Yuanhan Liu [mailto:yuanhan.liu@linux.intel.com]
> Sent: Wednesday, January 4, 2017 3:23 PM
> To: Tan, Jianfeng
> Cc: dev@dpdk.org; stephen@networkplumber.org
> Subject: Re: [PATCH v2 5/9] net/virtio: setup rxq interrupts
> 
> On Wed, Jan 04, 2017 at 02:56:50PM +0800, Tan, Jianfeng wrote:
> >
> >
> > [...]
> > >>+
> > >>+	if (virtio_queues_bind_intr(dev) < 0) {
> > >>+		PMD_INIT_LOG(ERR, "Failed to bind queue/interrupt");
> > >>+		return -1;
> > >You have to free intr_handle->intr_vec, otherwise, memory leak occurs.
> >
> > It's freed at dev_close(). Do you mean freeing and reallocating here? As
> 
> The typical way is free the resources have been allocated when errors
> happens.
> 
> > nr_rx_queues is not a changeable value, I don't see the necessity here. I
> > miss something?
> 
> No. nb_rx_queues does change, when people reconfigure the queue
> number.
> However, the MAX queues the virito supports does not change. You could
> use that number for allocation.

Oh yes. I will fix it.

Thanks,
Jianfeng

> 
> 	--yliu

^ permalink raw reply	[flat|nested] 63+ messages in thread

* [PATCH v3 00/10] rxq interrupt mode for virtio PMD
  2016-12-04  0:18 [PATCH 0/5] Interrupt mode for virtio PMD Jianfeng Tan
                   ` (5 preceding siblings ...)
  2016-12-29  7:30 ` [PATCH v2 0/9] rxq interrupt mode for virtio PMD Jianfeng Tan
@ 2017-01-16 14:46 ` Jianfeng Tan
  2017-01-16 14:46   ` [PATCH v3 01/10] net/virtio: fix rewriting LSC flag Jianfeng Tan
                     ` (10 more replies)
  2017-01-17  7:10 ` [PATCH v4 " Jianfeng Tan
  2017-01-17  8:00 ` [PATCH v5 06/10] net/virtio: setup rxq interrupts Jianfeng Tan
  8 siblings, 11 replies; 63+ messages in thread
From: Jianfeng Tan @ 2017-01-16 14:46 UTC (permalink / raw)
  To: dev; +Cc: yuanhan.liu, stephen, lei.a.yao, Jianfeng Tan

v3:
  - Update documents:
    * doc/guides/nics/features/virtio.ini
    * doc/guides/nics/features/virtio_vec.ini
    * doc/guides/nics/virtio.rst
  - Use hw->max_queue_pairs instead of dev->data->nb_rx_queues to
    allocate intr_vec array.
  - Fix v2 not working on legacy virtio devices by moving msix enabling
    before queue/irq binding.
  - Reword cover letter to give an overview of this series.
  - Remove wrapper to call vtpci->set_config_irq and vtpci->set_queue_irq.
  - Rebase on the new code, and fix a bug after changes by the commit
    bb30369dc10("eal: allow passing const interrupt handle"). Basically,
    it changes the way to get max interrupts. And we need to re-register
    callback to update intr_handle->max_intr.
  - In l3fwd-power ptype fix, use rte_eth_dev_get_supported_ptypes() to
    query if PMD provides needed ptypes.

v2:
  - Add PCI queue/irq config ops.
  - Move rxq interrupt settings before sending DRIVER OK.

Historically, virtio PMD can only be binded to igb_uio or
uio_pci_generic, and not for vfio-pci (iommu group cannot be created as
vIOMMU is not enabled in QEMU yet).  Besides, quote from
http://dpdk.org/doc/guides-16.11/rel_notes/release_2_1.html:
  "Per queue RX interrupt events are only allowed in VFIO
   which supports multiple MSI-X vectors."

Linux starts to support VFIO NO-IOMMU mode since 4.8.0. It cannot put
devices into groups for separation as normal VFIO does. So it does not
require QEMU to support vIOMMU. But it does inherit other benefits from
VFIO framework, like better interrupts supports (than UIO). It gives a
good chance to enable rxq interrupt for virtio PMD.

To implement it,
a. Firstly, we need to enable msix. This should be done before DRIVER_OK
setting and also before queue/irq binding in step b.
b. Bind queue/irq through portio (legacy devices) or mmio (modern devices).
   So far, we hard-code 1:1 queue/irq mapping (each rx queue has one
   exclusive interrupt), like this:
      vec 0 -> config irq
      vec 1 -> rxq0
      vec 2 -> rxq1
      ...
    
    which means, the "vectors" option of QEMU should be configured with
    a value >= N+1 (N is the number of the queue pairs).
c. To enable/disable interrupt notification, flags on virtqueues are used
   to control devices either sending interrupt or not.
d. Encap above behaviors into callbacks in ether_dev_ops, like
   rx_queue_intr_enable/rx_queue_intr_disable/rx_descriptor_done etc.


How to test:

Step 1, prepare a VM image with kernel version >= 4.8.0, and make sure
the kernel is compiled with CONFIG_VFIO_NOIOMMU=y.

Step 2, on the host, start a testpmd with a vhost port:
  $ testpmd -c 0x7 -m 1024 --vdev 'eth_vhost0,iface=/tmp/sock0,queues=2' \
	--no-pci -- -i --rxq=2 --txq=2 --nb-cores=2

Step 3, boot the VM:
  $ qemu ... -chardev socket,id=chr1,path=/tmp/sock0 \
	-netdev vhost-user,id=net1,chardev=chr1,vhostforce,queues=2 \
	-device virtio-net-pci,netdev=net1,mq=on,vectors=5 ...

Step 4, insert kernel modules
  $ modprobe vfio enable_unsafe_noiommu_mode=1
  $ modprobe vfio-pci

Step 5, start l3fwd-power in VM:
  $ l3fwd-power -c 0x3 -n 4 -- -p 1 -P --config="(0,0,1),(0,1,1)" \
						 --no-numa --parse-ptype

Step 6, send packets from testpmd on the host:
  $ start tx_first

Then l3fwd-power outputs:
  L3FWD_POWER: lcore 1 is waked up from rx interrupt on port 0 queue 0
  L3FWD_POWER: lcore 1 is waked up from rx interrupt on port 0 queue 1

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>

Jianfeng Tan (10):
  net/virtio: fix rewriting LSC flag
  net/virtio: clean up wrapper of set_config_irq
  net/virtio: add Rx descriptor check
  net/virtio: add PCI ops for queue/irq binding
  net/virtio: add Rx queue intr enable/disable functions
  net/virtio: setup rxq interrupts
  net/virtio: unbind intr/eventfd when stop device
  net/virtio: unmapping queue/irq when close device
  examples/l3fwd-power: add parse-ptype option
  examples/l3fwd-power: fix not stop and close device

 drivers/net/virtio/virtio_ethdev.c | 161 +++++++++++++++++++++++++++++++++++--
 drivers/net/virtio/virtio_ethdev.h |   3 +
 drivers/net/virtio/virtio_pci.c    |  31 +++++--
 drivers/net/virtio/virtio_pci.h    |   5 +-
 drivers/net/virtio/virtio_rxtx.c   |   9 +++
 drivers/net/virtio/virtqueue.c     |  11 ---
 drivers/net/virtio/virtqueue.h     |  16 +++-
 examples/l3fwd-power/main.c        | 120 ++++++++++++++++++++++++++-
 8 files changed, 325 insertions(+), 31 deletions(-)

-- 
2.7.4

^ permalink raw reply	[flat|nested] 63+ messages in thread

* [PATCH v3 01/10] net/virtio: fix rewriting LSC flag
  2017-01-16 14:46 ` [PATCH v3 00/10] " Jianfeng Tan
@ 2017-01-16 14:46   ` Jianfeng Tan
  2017-01-16 14:46   ` [PATCH v3 02/10] net/virtio: clean up wrapper of set_config_irq Jianfeng Tan
                     ` (9 subsequent siblings)
  10 siblings, 0 replies; 63+ messages in thread
From: Jianfeng Tan @ 2017-01-16 14:46 UTC (permalink / raw)
  To: dev; +Cc: yuanhan.liu, stephen, lei.a.yao, Jianfeng Tan, stable

The LSC flag is decided according to if VIRTIO_NET_F_STATUS feature
is negotiated. Copy the PCI info after the judgement will rewrite
the correct result.

Fixes: 198ab33677c9 ("net/virtio: move device initialization in a function")

CC: stable@dpdk.org

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

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index f596f4d..837d3df 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1208,17 +1208,17 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
 	if (virtio_negotiate_features(hw, req_features) < 0)
 		return -1;
 
+	if (eth_dev->device) {
+		pci_dev = RTE_DEV_TO_PCI(eth_dev->device);
+		rte_eth_copy_pci_info(eth_dev, pci_dev);
+	}
+
 	/* If host does not support status then disable LSC */
 	if (!vtpci_with_feature(hw, VIRTIO_NET_F_STATUS))
 		eth_dev->data->dev_flags &= ~RTE_ETH_DEV_INTR_LSC;
 	else
 		eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC;
 
-	if (eth_dev->device) {
-		pci_dev = RTE_DEV_TO_PCI(eth_dev->device);
-		rte_eth_copy_pci_info(eth_dev, pci_dev);
-	}
-
 	rx_func_get(eth_dev);
 
 	/* Setting up rx_header size for the device */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v3 02/10] net/virtio: clean up wrapper of set_config_irq
  2017-01-16 14:46 ` [PATCH v3 00/10] " Jianfeng Tan
  2017-01-16 14:46   ` [PATCH v3 01/10] net/virtio: fix rewriting LSC flag Jianfeng Tan
@ 2017-01-16 14:46   ` Jianfeng Tan
  2017-01-16 14:46   ` [PATCH v3 03/10] net/virtio: add Rx descriptor check Jianfeng Tan
                     ` (8 subsequent siblings)
  10 siblings, 0 replies; 63+ messages in thread
From: Jianfeng Tan @ 2017-01-16 14:46 UTC (permalink / raw)
  To: dev; +Cc: yuanhan.liu, stephen, lei.a.yao, Jianfeng Tan

We need to define a prototype for such wrapper, which makes thing
too complicated. Remove wrapper and call set_config_irq directly.

Suggested-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/virtio/virtio_ethdev.c | 6 ++++--
 drivers/net/virtio/virtio_pci.c    | 8 --------
 drivers/net/virtio/virtio_pci.h    | 2 --
 3 files changed, 4 insertions(+), 12 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 837d3df..a790c46 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -602,7 +602,7 @@ virtio_dev_close(struct rte_eth_dev *dev)
 
 	/* reset the NIC */
 	if (dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC)
-		vtpci_irq_config(hw, VIRTIO_MSI_NO_VECTOR);
+		VTPCI_OPS(hw)->set_config_irq(hw, VIRTIO_MSI_NO_VECTOR);
 	vtpci_reset(hw);
 	virtio_dev_free_mbufs(dev);
 	virtio_free_queues(hw);
@@ -1520,7 +1520,9 @@ virtio_dev_configure(struct rte_eth_dev *dev)
 	}
 
 	if (dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC)
-		if (vtpci_irq_config(hw, 0) == VIRTIO_MSI_NO_VECTOR) {
+		/* Enable vector (0) for Link State Intrerrupt */
+		if (VTPCI_OPS(hw)->set_config_irq(hw, 0) ==
+				VIRTIO_MSI_NO_VECTOR) {
 			PMD_DRV_LOG(ERR, "failed to set config vector");
 			return -EBUSY;
 		}
diff --git a/drivers/net/virtio/virtio_pci.c b/drivers/net/virtio/virtio_pci.c
index fbdb5b7..3ca6ba1 100644
--- a/drivers/net/virtio/virtio_pci.c
+++ b/drivers/net/virtio/virtio_pci.c
@@ -600,14 +600,6 @@ vtpci_isr(struct virtio_hw *hw)
 	return VTPCI_OPS(hw)->get_isr(hw);
 }
 
-
-/* Enable one vector (0) for Link State Intrerrupt */
-uint16_t
-vtpci_irq_config(struct virtio_hw *hw, uint16_t vec)
-{
-	return VTPCI_OPS(hw)->set_config_irq(hw, vec);
-}
-
 static void *
 get_cfg_addr(struct rte_pci_device *dev, struct virtio_pci_cap *cap)
 {
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index 4235bef..588d41f 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -330,8 +330,6 @@ void vtpci_read_dev_config(struct virtio_hw *, size_t, void *, int);
 
 uint8_t vtpci_isr(struct virtio_hw *);
 
-uint16_t vtpci_irq_config(struct virtio_hw *, uint16_t);
-
 extern const struct virtio_pci_ops legacy_ops;
 extern const struct virtio_pci_ops modern_ops;
 extern const struct virtio_pci_ops virtio_user_ops;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v3 03/10] net/virtio: add Rx descriptor check
  2017-01-16 14:46 ` [PATCH v3 00/10] " Jianfeng Tan
  2017-01-16 14:46   ` [PATCH v3 01/10] net/virtio: fix rewriting LSC flag Jianfeng Tan
  2017-01-16 14:46   ` [PATCH v3 02/10] net/virtio: clean up wrapper of set_config_irq Jianfeng Tan
@ 2017-01-16 14:46   ` Jianfeng Tan
  2017-01-16 19:16     ` Stephen Hemminger
  2017-01-16 14:46   ` [PATCH v3 04/10] net/virtio: add PCI ops for queue/irq binding Jianfeng Tan
                     ` (7 subsequent siblings)
  10 siblings, 1 reply; 63+ messages in thread
From: Jianfeng Tan @ 2017-01-16 14:46 UTC (permalink / raw)
  To: dev; +Cc: yuanhan.liu, stephen, lei.a.yao, Jianfeng Tan

Under interrupt mode, rx_descriptor_done is used as an indicator
for applications to check if some number of packets are ready to
be received.

This patch enables this by checking used ring's local consumed idx
with shared (with backend) idx.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/virtio/virtio_ethdev.c | 1 +
 drivers/net/virtio/virtio_ethdev.h | 3 +++
 drivers/net/virtio/virtio_rxtx.c   | 9 +++++++++
 3 files changed, 13 insertions(+)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index a790c46..bec2be2 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -739,6 +739,7 @@ static const struct eth_dev_ops virtio_eth_dev_ops = {
 	.link_update             = virtio_dev_link_update,
 	.rx_queue_setup          = virtio_dev_rx_queue_setup,
 	.rx_queue_release        = virtio_dev_queue_release,
+	.rx_descriptor_done      = virtio_dev_rx_queue_done,
 	.tx_queue_setup          = virtio_dev_tx_queue_setup,
 	.tx_queue_release        = virtio_dev_queue_release,
 	/* collect stats per queue */
diff --git a/drivers/net/virtio/virtio_ethdev.h b/drivers/net/virtio/virtio_ethdev.h
index 27d9a19..4ab81c6 100644
--- a/drivers/net/virtio/virtio_ethdev.h
+++ b/drivers/net/virtio/virtio_ethdev.h
@@ -78,6 +78,9 @@ void virtio_dev_cq_start(struct rte_eth_dev *dev);
 /*
  * RX/TX function prototypes
  */
+
+int virtio_dev_rx_queue_done(void *rxq, uint16_t offset);
+
 int  virtio_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t rx_queue_id,
 		uint16_t nb_rx_desc, unsigned int socket_id,
 		const struct rte_eth_rxconf *rx_conf,
diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c
index 1e5a6b9..02154b7 100644
--- a/drivers/net/virtio/virtio_rxtx.c
+++ b/drivers/net/virtio/virtio_rxtx.c
@@ -72,6 +72,15 @@
 #define VIRTIO_SIMPLE_FLAGS ((uint32_t)ETH_TXQ_FLAGS_NOMULTSEGS | \
 	ETH_TXQ_FLAGS_NOOFFLOADS)
 
+int
+virtio_dev_rx_queue_done(void *rxq, uint16_t offset)
+{
+	struct virtnet_rx *rxvq = rxq;
+	struct virtqueue *vq = rxvq->vq;
+
+	return (VIRTQUEUE_NUSED(vq) >= offset);
+}
+
 static void
 vq_ring_free_chain(struct virtqueue *vq, uint16_t desc_idx)
 {
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v3 04/10] net/virtio: add PCI ops for queue/irq binding
  2017-01-16 14:46 ` [PATCH v3 00/10] " Jianfeng Tan
                     ` (2 preceding siblings ...)
  2017-01-16 14:46   ` [PATCH v3 03/10] net/virtio: add Rx descriptor check Jianfeng Tan
@ 2017-01-16 14:46   ` Jianfeng Tan
  2017-01-16 14:46   ` [PATCH v3 05/10] net/virtio: add Rx queue intr enable/disable functions Jianfeng Tan
                     ` (6 subsequent siblings)
  10 siblings, 0 replies; 63+ messages in thread
From: Jianfeng Tan @ 2017-01-16 14:46 UTC (permalink / raw)
  To: dev; +Cc: yuanhan.liu, stephen, lei.a.yao, Jianfeng Tan

Add handler in virtio_pci_ops to set queue/irq bind.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/virtio/virtio_pci.c | 23 +++++++++++++++++++++++
 drivers/net/virtio/virtio_pci.h |  3 +++
 2 files changed, 26 insertions(+)

diff --git a/drivers/net/virtio/virtio_pci.c b/drivers/net/virtio/virtio_pci.c
index 3ca6ba1..6d2d10d 100644
--- a/drivers/net/virtio/virtio_pci.c
+++ b/drivers/net/virtio/virtio_pci.c
@@ -219,6 +219,19 @@ legacy_set_config_irq(struct virtio_hw *hw, uint16_t vec)
 }
 
 static uint16_t
+legacy_set_queue_irq(struct virtio_hw *hw, struct virtqueue *vq, uint16_t vec)
+{
+	uint16_t dst;
+
+	rte_eal_pci_ioport_write(VTPCI_IO(hw), &vq->vq_queue_index, 2,
+				 VIRTIO_PCI_QUEUE_SEL);
+	rte_eal_pci_ioport_write(VTPCI_IO(hw), &vec, 2,
+				 VIRTIO_MSI_QUEUE_VECTOR);
+	rte_eal_pci_ioport_read(VTPCI_IO(hw), &dst, 2, VIRTIO_MSI_QUEUE_VECTOR);
+	return dst;
+}
+
+static uint16_t
 legacy_get_queue_num(struct virtio_hw *hw, uint16_t queue_id)
 {
 	uint16_t dst;
@@ -313,6 +326,7 @@ const struct virtio_pci_ops legacy_ops = {
 	.set_features	= legacy_set_features,
 	.get_isr	= legacy_get_isr,
 	.set_config_irq	= legacy_set_config_irq,
+	.set_queue_irq  = legacy_set_queue_irq,
 	.get_queue_num	= legacy_get_queue_num,
 	.setup_queue	= legacy_setup_queue,
 	.del_queue	= legacy_del_queue,
@@ -452,6 +466,14 @@ modern_set_config_irq(struct virtio_hw *hw, uint16_t vec)
 }
 
 static uint16_t
+modern_set_queue_irq(struct virtio_hw *hw, struct virtqueue *vq, uint16_t vec)
+{
+	io_write16(vq->vq_queue_index, &hw->common_cfg->queue_select);
+	io_write16(vec, &hw->common_cfg->queue_msix_vector);
+	return io_read16(&hw->common_cfg->queue_msix_vector);
+}
+
+static uint16_t
 modern_get_queue_num(struct virtio_hw *hw, uint16_t queue_id)
 {
 	io_write16(queue_id, &hw->common_cfg->queue_select);
@@ -529,6 +551,7 @@ const struct virtio_pci_ops modern_ops = {
 	.set_features	= modern_set_features,
 	.get_isr	= modern_get_isr,
 	.set_config_irq	= modern_set_config_irq,
+	.set_queue_irq  = modern_set_queue_irq,
 	.get_queue_num	= modern_get_queue_num,
 	.setup_queue	= modern_setup_queue,
 	.del_queue	= modern_del_queue,
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index 588d41f..59e45c4 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -235,6 +235,9 @@ struct virtio_pci_ops {
 
 	uint16_t (*set_config_irq)(struct virtio_hw *hw, uint16_t vec);
 
+	uint16_t (*set_queue_irq)(struct virtio_hw *hw, struct virtqueue *vq,
+			uint16_t vec);
+
 	uint16_t (*get_queue_num)(struct virtio_hw *hw, uint16_t queue_id);
 	int (*setup_queue)(struct virtio_hw *hw, struct virtqueue *vq);
 	void (*del_queue)(struct virtio_hw *hw, struct virtqueue *vq);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v3 05/10] net/virtio: add Rx queue intr enable/disable functions
  2017-01-16 14:46 ` [PATCH v3 00/10] " Jianfeng Tan
                     ` (3 preceding siblings ...)
  2017-01-16 14:46   ` [PATCH v3 04/10] net/virtio: add PCI ops for queue/irq binding Jianfeng Tan
@ 2017-01-16 14:46   ` Jianfeng Tan
  2017-01-17  2:30     ` Jason Wang
  2017-01-16 14:46   ` [PATCH v3 06/10] net/virtio: setup rxq interrupts Jianfeng Tan
                     ` (5 subsequent siblings)
  10 siblings, 1 reply; 63+ messages in thread
From: Jianfeng Tan @ 2017-01-16 14:46 UTC (permalink / raw)
  To: dev; +Cc: yuanhan.liu, stephen, lei.a.yao, Jianfeng Tan

This patch implements interrupt enable/disable functions for each
Rx queue. And we rely on flags of avail queue as the hint for virtio
device to interrupt virtio driver or not.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/virtio/virtio_ethdev.c | 22 ++++++++++++++++++++++
 drivers/net/virtio/virtqueue.c     | 11 -----------
 drivers/net/virtio/virtqueue.h     | 16 +++++++++++++++-
 3 files changed, 37 insertions(+), 12 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index bec2be2..4224d17 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -717,6 +717,26 @@ virtio_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
 	return 0;
 }
 
+static int
+virtio_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
+{
+	struct virtnet_rx *rxvq = dev->data->rx_queues[queue_id];
+	struct virtqueue *vq = rxvq->vq;
+
+	virtqueue_enable_intr(vq);
+	return 0;
+}
+
+static int
+virtio_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id)
+{
+	struct virtnet_rx *rxvq = dev->data->rx_queues[queue_id];
+	struct virtqueue *vq = rxvq->vq;
+
+	virtqueue_disable_intr(vq);
+	return 0;
+}
+
 /*
  * dev_ops for virtio, bare necessities for basic operation
  */
@@ -738,6 +758,8 @@ static const struct eth_dev_ops virtio_eth_dev_ops = {
 	.xstats_reset            = virtio_dev_stats_reset,
 	.link_update             = virtio_dev_link_update,
 	.rx_queue_setup          = virtio_dev_rx_queue_setup,
+	.rx_queue_intr_enable    = virtio_dev_rx_queue_intr_enable,
+	.rx_queue_intr_disable   = virtio_dev_rx_queue_intr_disable,
 	.rx_queue_release        = virtio_dev_queue_release,
 	.rx_descriptor_done      = virtio_dev_rx_queue_done,
 	.tx_queue_setup          = virtio_dev_tx_queue_setup,
diff --git a/drivers/net/virtio/virtqueue.c b/drivers/net/virtio/virtqueue.c
index 7f60e3e..9ad77b8 100644
--- a/drivers/net/virtio/virtqueue.c
+++ b/drivers/net/virtio/virtqueue.c
@@ -38,17 +38,6 @@
 #include "virtio_logs.h"
 #include "virtio_pci.h"
 
-void
-virtqueue_disable_intr(struct virtqueue *vq)
-{
-	/*
-	 * Set VRING_AVAIL_F_NO_INTERRUPT to hint host
-	 * not to interrupt when it consumes packets
-	 * Note: this is only considered a hint to the host
-	 */
-	vq->vq_ring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT;
-}
-
 /*
  * Two types of mbuf to be cleaned:
  * 1) mbuf that has been consumed by backend but not used by virtio.
diff --git a/drivers/net/virtio/virtqueue.h b/drivers/net/virtio/virtqueue.h
index b1070e0..f9e3736 100644
--- a/drivers/net/virtio/virtqueue.h
+++ b/drivers/net/virtio/virtqueue.h
@@ -274,7 +274,21 @@ vring_desc_init(struct vring_desc *dp, uint16_t n)
 /**
  * Tell the backend not to interrupt us.
  */
-void virtqueue_disable_intr(struct virtqueue *vq);
+static inline void
+virtqueue_disable_intr(struct virtqueue *vq)
+{
+	vq->vq_ring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT;
+}
+
+/**
+ * Tell the backend to interrupt us.
+ */
+static inline void
+virtqueue_enable_intr(struct virtqueue *vq)
+{
+	vq->vq_ring.avail->flags &= (~VRING_AVAIL_F_NO_INTERRUPT);
+}
+
 /**
  *  Dump virtqueue internal structures, for debug purpose only.
  */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v3 06/10] net/virtio: setup rxq interrupts
  2017-01-16 14:46 ` [PATCH v3 00/10] " Jianfeng Tan
                     ` (4 preceding siblings ...)
  2017-01-16 14:46   ` [PATCH v3 05/10] net/virtio: add Rx queue intr enable/disable functions Jianfeng Tan
@ 2017-01-16 14:46   ` Jianfeng Tan
  2017-01-16 14:46   ` [PATCH v3 07/10] net/virtio: unbind intr/eventfd when stop device Jianfeng Tan
                     ` (4 subsequent siblings)
  10 siblings, 0 replies; 63+ messages in thread
From: Jianfeng Tan @ 2017-01-16 14:46 UTC (permalink / raw)
  To: dev; +Cc: yuanhan.liu, stephen, lei.a.yao, Jianfeng Tan

This patch mainly allocates structure to store queue/irq mapping,
and configure queue/irq mapping down through PCI ops. It also creates
eventfds for each Rx queue and tell the kernel about the eventfd/intr
binding.

Note: So far, we hard-code 1:1 queue/irq mapping (each rx queue has
one exclusive interrupt), like this:
  vec 0 -> config irq
  vec 1 -> rxq0
  vec 2 -> rxq1
  ...

which means, the "vectors" option of QEMU should be configured with
a value >= N+1 (N is the number of the queue pairs).

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

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 4224d17..e870125 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1210,6 +1210,82 @@ rx_func_get(struct rte_eth_dev *eth_dev)
 		eth_dev->rx_pkt_burst = &virtio_recv_pkts;
 }
 
+/* Only support 1:1 queue/interrupt mapping so far.
+ * TODO: support n:1 queue/interrupt mapping when there are limited number of
+ * interrupt vectors (<N+1).
+ */
+static int
+virtio_queues_bind_intr(struct rte_eth_dev *dev)
+{
+	uint32_t i;
+	struct virtio_hw *hw = dev->data->dev_private;
+
+	PMD_INIT_LOG(INFO, "queue/interrupt binding\n");
+	for (i = 0; i < dev->data->nb_rx_queues; ++i) {
+		dev->intr_handle->intr_vec[i] = i + 1;
+		if (VTPCI_OPS(hw)->set_queue_irq(hw, hw->vqs[i * 2], i + 1) ==
+						 VIRTIO_MSI_NO_VECTOR) {
+			PMD_DRV_LOG(ERR, "failed to set queue vector");
+			return -EBUSY;
+		}
+	}
+
+	return 0;
+}
+
+static int
+virtio_configure_intr(struct rte_eth_dev *dev)
+{
+	struct virtio_hw *hw = dev->data->dev_private;
+
+	if (!rte_intr_cap_multiple(dev->intr_handle)) {
+		PMD_INIT_LOG(ERR, "Multiple intr vector not supported");
+		return -ENOTSUP;
+	}
+
+	if (rte_intr_efd_enable(dev->intr_handle, dev->data->nb_rx_queues)) {
+		PMD_INIT_LOG(ERR, "Fail to create eventfd");
+		return -1;
+	}
+
+	if (!dev->intr_handle->intr_vec) {
+		dev->intr_handle->intr_vec =
+			rte_zmalloc("intr_vec",
+				    hw->max_queue_pairs * sizeof(int), 0);
+		if (!dev->intr_handle->intr_vec) {
+			PMD_INIT_LOG(ERR, "Failed to allocate %u rxq vectors",
+				     hw->max_queue_pairs);
+			return -ENOMEM;
+		}
+	}
+
+	/* Re-register callback to update max_intr */
+	rte_intr_callback_unregister(dev->intr_handle,
+				     virtio_interrupt_handler,
+				     dev);
+	rte_intr_callback_register(dev->intr_handle,
+				   virtio_interrupt_handler,
+				   dev);
+
+	/* DO NOT try to remove this! This function will enable msix, or QEMU
+	 * will encounter SIGSEGV when DRIVER_OK is sent.
+	 * And for legacy devices, this should be done before queue/vec binding
+	 * to change the config size from 20 to 24, or VIRTIO_MSI_QUEUE_VECTOR
+	 * (22) will be ignored.
+	 */
+	if (rte_intr_enable(dev->intr_handle) < 0) {
+		PMD_DRV_LOG(ERR, "interrupt enable failed");
+		return -1;
+	}
+
+	if (virtio_queues_bind_intr(dev) < 0) {
+		PMD_INIT_LOG(ERR, "Failed to bind queue/interrupt");
+		return -1;
+	}
+
+	return 0;
+}
+
 /* reset device and renegotiate features if needed */
 static int
 virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
@@ -1306,6 +1382,14 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
 	ret = virtio_alloc_queues(eth_dev);
 	if (ret < 0)
 		return ret;
+
+	if (eth_dev->data->dev_conf.intr_conf.rxq) {
+		if (virtio_configure_intr(eth_dev) < 0) {
+			PMD_INIT_LOG(ERR, "failed to configure interrupt");
+			return -1;
+		}
+	}
+
 	vtpci_reinit_complete(hw);
 
 	if (pci_dev)
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v3 07/10] net/virtio: unbind intr/eventfd when stop device
  2017-01-16 14:46 ` [PATCH v3 00/10] " Jianfeng Tan
                     ` (5 preceding siblings ...)
  2017-01-16 14:46   ` [PATCH v3 06/10] net/virtio: setup rxq interrupts Jianfeng Tan
@ 2017-01-16 14:46   ` Jianfeng Tan
  2017-01-16 14:47   ` [PATCH v3 08/10] net/virtio: unmapping queue/irq when close device Jianfeng Tan
                     ` (3 subsequent siblings)
  10 siblings, 0 replies; 63+ messages in thread
From: Jianfeng Tan @ 2017-01-16 14:46 UTC (permalink / raw)
  To: dev; +Cc: yuanhan.liu, stephen, lei.a.yao, Jianfeng Tan

When virtio devices get stopped, tell the kernel to unbind the
mapping between interrupts and eventfds.

Note: it behaves differently from other NICs which close eventfds,
free struct. In virtio, we do those things when close device in
following patch.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/virtio/virtio_ethdev.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index e870125..5030ed5 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1652,6 +1652,15 @@ virtio_dev_start(struct rte_eth_dev *dev)
 			PMD_DRV_LOG(ERR, "link status not supported by host");
 			return -ENOTSUP;
 		}
+	}
+
+	/* Enable uio/vfio intr/eventfd mapping: althrough we already did that
+	 * in device configure, but it could be unmapped  when device is
+	 * stopped.
+	 */
+	if (dev->data->dev_conf.intr_conf.lsc ||
+	    dev->data->dev_conf.intr_conf.rxq) {
+		rte_intr_disable(dev->intr_handle);
 
 		if (rte_intr_enable(dev->intr_handle) < 0) {
 			PMD_DRV_LOG(ERR, "interrupt enable failed");
@@ -1746,10 +1755,11 @@ static void
 virtio_dev_stop(struct rte_eth_dev *dev)
 {
 	struct rte_eth_link link;
+	struct rte_intr_conf *intr_conf = &dev->data->dev_conf.intr_conf;
 
 	PMD_INIT_LOG(DEBUG, "stop");
 
-	if (dev->data->dev_conf.intr_conf.lsc)
+	if (intr_conf->lsc || intr_conf->rxq)
 		rte_intr_disable(dev->intr_handle);
 
 	memset(&link, 0, sizeof(link));
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v3 08/10] net/virtio: unmapping queue/irq when close device
  2017-01-16 14:46 ` [PATCH v3 00/10] " Jianfeng Tan
                     ` (6 preceding siblings ...)
  2017-01-16 14:46   ` [PATCH v3 07/10] net/virtio: unbind intr/eventfd when stop device Jianfeng Tan
@ 2017-01-16 14:47   ` Jianfeng Tan
  2017-01-16 14:47   ` [PATCH v3 09/10] examples/l3fwd-power: add parse-ptype option Jianfeng Tan
                     ` (2 subsequent siblings)
  10 siblings, 0 replies; 63+ messages in thread
From: Jianfeng Tan @ 2017-01-16 14:47 UTC (permalink / raw)
  To: dev; +Cc: yuanhan.liu, stephen, lei.a.yao, Jianfeng Tan

When closing virtio devices, close eventfds, free the struct to
store queue/irq mapping.

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

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 5030ed5..0aad295 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -593,16 +593,29 @@ virtio_alloc_queues(struct rte_eth_dev *dev)
 	return 0;
 }
 
+static void virtio_queues_unbind_intr(struct rte_eth_dev *dev);
+
 static void
 virtio_dev_close(struct rte_eth_dev *dev)
 {
 	struct virtio_hw *hw = dev->data->dev_private;
+	struct rte_intr_conf *intr_conf = &dev->data->dev_conf.intr_conf;
 
 	PMD_INIT_LOG(DEBUG, "virtio_dev_close");
 
 	/* reset the NIC */
 	if (dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC)
 		VTPCI_OPS(hw)->set_config_irq(hw, VIRTIO_MSI_NO_VECTOR);
+	if (intr_conf->rxq)
+		virtio_queues_unbind_intr(dev);
+
+	if (intr_conf->lsc || intr_conf->rxq) {
+		rte_intr_disable(dev->intr_handle);
+		rte_intr_efd_disable(dev->intr_handle);
+		rte_free(dev->intr_handle->intr_vec);
+		dev->intr_handle->intr_vec = NULL;
+	}
+
 	vtpci_reset(hw);
 	virtio_dev_free_mbufs(dev);
 	virtio_free_queues(hw);
@@ -1233,6 +1246,19 @@ virtio_queues_bind_intr(struct rte_eth_dev *dev)
 	return 0;
 }
 
+static void
+virtio_queues_unbind_intr(struct rte_eth_dev *dev)
+{
+	uint32_t i;
+	struct virtio_hw *hw = dev->data->dev_private;
+
+	PMD_INIT_LOG(INFO, "queue/interrupt unbinding\n");
+	for (i = 0; i < dev->data->nb_rx_queues; ++i)
+		VTPCI_OPS(hw)->set_queue_irq(hw,
+					     hw->vqs[i * VTNET_CQ],
+					     VIRTIO_MSI_NO_VECTOR);
+}
+
 static int
 virtio_configure_intr(struct rte_eth_dev *dev)
 {
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v3 09/10] examples/l3fwd-power: add parse-ptype option
  2017-01-16 14:46 ` [PATCH v3 00/10] " Jianfeng Tan
                     ` (7 preceding siblings ...)
  2017-01-16 14:47   ` [PATCH v3 08/10] net/virtio: unmapping queue/irq when close device Jianfeng Tan
@ 2017-01-16 14:47   ` Jianfeng Tan
  2017-01-17  5:16     ` Yuanhan Liu
  2017-01-16 14:47   ` [PATCH v3 10/10] examples/l3fwd-power: fix not stop and close device Jianfeng Tan
  2017-01-17  2:14   ` [PATCH v3 00/10] rxq interrupt mode for virtio PMD Yao, Lei A
  10 siblings, 1 reply; 63+ messages in thread
From: Jianfeng Tan @ 2017-01-16 14:47 UTC (permalink / raw)
  To: dev; +Cc: yuanhan.liu, stephen, lei.a.yao, Jianfeng Tan

To support those devices that do not provide packet type info when
receiving packets, add a new option, --parse-ptype, to analyze
packet type in the Rx callback.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 examples/l3fwd-power/main.c | 110 +++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 109 insertions(+), 1 deletion(-)

diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c
index b65d683..6f10d0a 100644
--- a/examples/l3fwd-power/main.c
+++ b/examples/l3fwd-power/main.c
@@ -164,6 +164,8 @@ static uint32_t enabled_port_mask = 0;
 static int promiscuous_on = 0;
 /* NUMA is enabled by default. */
 static int numa_on = 1;
+static int parse_ptype; /**< Parse packet type using rx callback, and */
+			/**< disabled by default */
 
 enum freq_scale_hint_t
 {
@@ -607,6 +609,48 @@ get_ipv4_dst_port(struct ipv4_hdr *ipv4_hdr, uint8_t portid,
 #endif
 
 static inline void
+parse_ptype_one(struct rte_mbuf *m)
+{
+	struct ether_hdr *eth_hdr;
+	uint32_t packet_type = RTE_PTYPE_UNKNOWN;
+	uint16_t ether_type;
+
+	eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
+	ether_type = eth_hdr->ether_type;
+	if (ether_type == rte_cpu_to_be_16(ETHER_TYPE_IPv4))
+		packet_type |= RTE_PTYPE_L3_IPV4_EXT_UNKNOWN;
+	else if (ether_type == rte_cpu_to_be_16(ETHER_TYPE_IPv6))
+		packet_type |= RTE_PTYPE_L3_IPV6_EXT_UNKNOWN;
+
+	m->packet_type = packet_type;
+}
+
+static uint16_t
+cb_parse_ptype(uint8_t port __rte_unused, uint16_t queue __rte_unused,
+	       struct rte_mbuf *pkts[], uint16_t nb_pkts,
+	       uint16_t max_pkts __rte_unused,
+	       void *user_param __rte_unused)
+{
+	unsigned int i;
+
+	for (i = 0; i < nb_pkts; ++i)
+		parse_ptype_one(pkts[i]);
+
+	return nb_pkts;
+}
+
+static int
+add_cb_parse_ptype(uint8_t portid, uint16_t queueid)
+{
+	printf("Port %d: softly parse packet type info\n", portid);
+	if (rte_eth_add_rx_callback(portid, queueid, cb_parse_ptype, NULL))
+		return 0;
+
+	printf("Failed to add rx callback: port=%d\n", portid);
+	return -1;
+}
+
+static inline void
 l3fwd_simple_forward(struct rte_mbuf *m, uint8_t portid,
 				struct lcore_conf *qconf)
 {
@@ -1108,7 +1152,8 @@ print_usage(const char *prgname)
 		"  --config (port,queue,lcore): rx queues configuration\n"
 		"  --no-numa: optional, disable numa awareness\n"
 		"  --enable-jumbo: enable jumbo frame"
-		" which max packet len is PKTLEN in decimal (64-9600)\n",
+		" which max packet len is PKTLEN in decimal (64-9600)\n"
+		"  --parse-ptype: parse packet type by software\n",
 		prgname);
 }
 
@@ -1202,6 +1247,8 @@ parse_config(const char *q_arg)
 	return 0;
 }
 
+#define CMD_LINE_OPT_PARSE_PTYPE "parse-ptype"
+
 /* Parse the argument given in the command line of the application */
 static int
 parse_args(int argc, char **argv)
@@ -1214,6 +1261,7 @@ parse_args(int argc, char **argv)
 		{"config", 1, 0, 0},
 		{"no-numa", 0, 0, 0},
 		{"enable-jumbo", 0, 0, 0},
+		{CMD_LINE_OPT_PARSE_PTYPE, 0, 0, 0},
 		{NULL, 0, 0, 0}
 	};
 
@@ -1284,6 +1332,13 @@ parse_args(int argc, char **argv)
 				(unsigned int)port_conf.rxmode.max_rx_pkt_len);
 			}
 
+			if (!strncmp(lgopts[option_index].name,
+				     CMD_LINE_OPT_PARSE_PTYPE,
+				     sizeof(CMD_LINE_OPT_PARSE_PTYPE))) {
+				printf("soft parse-ptype is enabled\n");
+				parse_ptype = 1;
+			}
+
 			break;
 
 		default:
@@ -1531,6 +1586,51 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 	}
 }
 
+static int check_ptype(uint8_t portid)
+{
+	int i, ret;
+	int ptype_l3_ipv4 = 0;
+#if (APP_LOOKUP_METHOD == APP_LOOKUP_EXACT_MATCH)
+	int ptype_l3_ipv6 = 0;
+#endif
+	uint32_t ptype_mask = RTE_PTYPE_L3_MASK;
+
+	ret = rte_eth_dev_get_supported_ptypes(portid, ptype_mask, NULL, 0);
+	if (ret <= 0)
+		return 0;
+
+	uint32_t ptypes[ret];
+
+	ret = rte_eth_dev_get_supported_ptypes(portid, ptype_mask, ptypes, ret);
+	for (i = 0; i < ret; ++i) {
+		if (ptypes[i] & RTE_PTYPE_L3_IPV4)
+			ptype_l3_ipv4 = 1;
+#if (APP_LOOKUP_METHOD == APP_LOOKUP_EXACT_MATCH)
+		if (ptypes[i] & RTE_PTYPE_L3_IPV6)
+			ptype_l3_ipv6 = 1;
+#endif
+	}
+
+	if (ptype_l3_ipv4 == 0)
+		printf("port %d cannot parse RTE_PTYPE_L3_IPV4\n", portid);
+
+#if (APP_LOOKUP_METHOD == APP_LOOKUP_EXACT_MATCH)
+	if (ptype_l3_ipv6 == 0)
+		printf("port %d cannot parse RTE_PTYPE_L3_IPV6\n", portid);
+#endif
+
+#if (APP_LOOKUP_METHOD == APP_LOOKUP_LPM)
+	if (ptype_l3_ipv4)
+#else
+	// APP_LOOKUP_EXACT_MATCH
+	if (ptype_l3_ipv4 && ptype_l3_ipv6)
+#endif
+		return 1;
+
+	return 0;
+
+}
+
 int
 main(int argc, char **argv)
 {
@@ -1716,6 +1816,14 @@ main(int argc, char **argv)
 				rte_exit(EXIT_FAILURE,
 					"rte_eth_rx_queue_setup: err=%d, "
 						"port=%d\n", ret, portid);
+
+			if (parse_ptype) {
+				if (add_cb_parse_ptype(portid, queueid) < 0)
+					rte_exit(EXIT_FAILURE,
+						 "Fail to add ptype cb\n");
+			} else if (!check_ptype(portid))
+				rte_exit(EXIT_FAILURE,
+					 "PMD can not provide needed ptypes\n");
 		}
 	}
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v3 10/10] examples/l3fwd-power: fix not stop and close device
  2017-01-16 14:46 ` [PATCH v3 00/10] " Jianfeng Tan
                     ` (8 preceding siblings ...)
  2017-01-16 14:47   ` [PATCH v3 09/10] examples/l3fwd-power: add parse-ptype option Jianfeng Tan
@ 2017-01-16 14:47   ` Jianfeng Tan
  2017-01-17  2:14   ` [PATCH v3 00/10] rxq interrupt mode for virtio PMD Yao, Lei A
  10 siblings, 0 replies; 63+ messages in thread
From: Jianfeng Tan @ 2017-01-16 14:47 UTC (permalink / raw)
  To: dev; +Cc: yuanhan.liu, stephen, lei.a.yao, Jianfeng Tan

As it gets killed, in SIGINT signal handler, device is not stopped
and closed. In virtio's case, vector assignment in the KVM is not
deassigned.

This patch will invoke dev_stop() and dev_close() in signal handler.

Fixes: d7937e2e3d12 ("power: initial import")

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 examples/l3fwd-power/main.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c
index 6f10d0a..71730a1 100644
--- a/examples/l3fwd-power/main.c
+++ b/examples/l3fwd-power/main.c
@@ -379,6 +379,7 @@ static void
 signal_exit_now(int sigtype)
 {
 	unsigned lcore_id;
+	unsigned int portid, nb_ports;
 	int ret;
 
 	if (sigtype == SIGINT) {
@@ -393,6 +394,15 @@ signal_exit_now(int sigtype)
 					"library de-initialization failed on "
 							"core%u\n", lcore_id);
 		}
+
+		nb_ports = rte_eth_dev_count();
+		for (portid = 0; portid < nb_ports; portid++) {
+			if ((enabled_port_mask & (1 << portid)) == 0)
+				continue;
+
+			rte_eth_dev_stop(portid);
+			rte_eth_dev_close(portid);
+		}
 	}
 
 	rte_exit(EXIT_SUCCESS, "User forced exit\n");
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* Re: [PATCH v3 03/10] net/virtio: add Rx descriptor check
  2017-01-16 14:46   ` [PATCH v3 03/10] net/virtio: add Rx descriptor check Jianfeng Tan
@ 2017-01-16 19:16     ` Stephen Hemminger
  2017-01-17  4:09       ` Yuanhan Liu
  0 siblings, 1 reply; 63+ messages in thread
From: Stephen Hemminger @ 2017-01-16 19:16 UTC (permalink / raw)
  To: Jianfeng Tan; +Cc: dev, yuanhan.liu, lei.a.yao

On Mon, 16 Jan 2017 14:46:55 +0000
Jianfeng Tan <jianfeng.tan@intel.com> wrote:

> +	return (VIRTQUEUE_NUSED(vq) >= offset);

Unneeded parenthesis in return statement.
This is a style thing, Linux folks see it as unnecessary. BSD folks like it

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v3 00/10] rxq interrupt mode for virtio PMD
  2017-01-16 14:46 ` [PATCH v3 00/10] " Jianfeng Tan
                     ` (9 preceding siblings ...)
  2017-01-16 14:47   ` [PATCH v3 10/10] examples/l3fwd-power: fix not stop and close device Jianfeng Tan
@ 2017-01-17  2:14   ` Yao, Lei A
  10 siblings, 0 replies; 63+ messages in thread
From: Yao, Lei A @ 2017-01-17  2:14 UTC (permalink / raw)
  To: Tan, Jianfeng, dev; +Cc: yuanhan.liu, stephen

Tested-by: Lei Yao <lei.a.yao@intel.com>
Apply patch to dpdk_next_virtio branch.
Qemu version: 2.5.0
Kernel version in VM: 4.8.1 

Following TCs are tested and passed:
Test Case1: Basic Virtio Interrupt test
Test Case2: Interrupted received in VM with different Virtio version(0.95 and 1.0)
Test Case3: Interrupted by packet data on all queue
Test Case4: Interrupted by packet data on unique queue
Test Case5: Stop packet transmit, related cores will be back to sleep


> -----Original Message-----
> From: Tan, Jianfeng
> Sent: Monday, January 16, 2017 10:47 PM
> To: dev@dpdk.org
> Cc: yuanhan.liu@linux.intel.com; stephen@networkplumber.org; Yao, Lei A
> <lei.a.yao@intel.com>; Tan, Jianfeng <jianfeng.tan@intel.com>
> Subject: [PATCH v3 00/10] rxq interrupt mode for virtio PMD
> 
> v3:
>   - Update documents:
>     * doc/guides/nics/features/virtio.ini
>     * doc/guides/nics/features/virtio_vec.ini
>     * doc/guides/nics/virtio.rst
>   - Use hw->max_queue_pairs instead of dev->data->nb_rx_queues to
>     allocate intr_vec array.
>   - Fix v2 not working on legacy virtio devices by moving msix enabling
>     before queue/irq binding.
>   - Reword cover letter to give an overview of this series.
>   - Remove wrapper to call vtpci->set_config_irq and vtpci->set_queue_irq.
>   - Rebase on the new code, and fix a bug after changes by the commit
>     bb30369dc10("eal: allow passing const interrupt handle"). Basically,
>     it changes the way to get max interrupts. And we need to re-register
>     callback to update intr_handle->max_intr.
>   - In l3fwd-power ptype fix, use rte_eth_dev_get_supported_ptypes() to
>     query if PMD provides needed ptypes.
> 
> v2:
>   - Add PCI queue/irq config ops.
>   - Move rxq interrupt settings before sending DRIVER OK.
> 
> Historically, virtio PMD can only be binded to igb_uio or
> uio_pci_generic, and not for vfio-pci (iommu group cannot be created as
> vIOMMU is not enabled in QEMU yet).  Besides, quote from
> http://dpdk.org/doc/guides-16.11/rel_notes/release_2_1.html:
>   "Per queue RX interrupt events are only allowed in VFIO
>    which supports multiple MSI-X vectors."
> 
> Linux starts to support VFIO NO-IOMMU mode since 4.8.0. It cannot put
> devices into groups for separation as normal VFIO does. So it does not
> require QEMU to support vIOMMU. But it does inherit other benefits from
> VFIO framework, like better interrupts supports (than UIO). It gives a
> good chance to enable rxq interrupt for virtio PMD.
> 
> To implement it,
> a. Firstly, we need to enable msix. This should be done before DRIVER_OK
> setting and also before queue/irq binding in step b.
> b. Bind queue/irq through portio (legacy devices) or mmio (modern devices).
>    So far, we hard-code 1:1 queue/irq mapping (each rx queue has one
>    exclusive interrupt), like this:
>       vec 0 -> config irq
>       vec 1 -> rxq0
>       vec 2 -> rxq1
>       ...
> 
>     which means, the "vectors" option of QEMU should be configured with
>     a value >= N+1 (N is the number of the queue pairs).
> c. To enable/disable interrupt notification, flags on virtqueues are used
>    to control devices either sending interrupt or not.
> d. Encap above behaviors into callbacks in ether_dev_ops, like
>    rx_queue_intr_enable/rx_queue_intr_disable/rx_descriptor_done etc.
> 
> 
> How to test:
> 
> Step 1, prepare a VM image with kernel version >= 4.8.0, and make sure
> the kernel is compiled with CONFIG_VFIO_NOIOMMU=y.
> 
> Step 2, on the host, start a testpmd with a vhost port:
>   $ testpmd -c 0x7 -m 1024 --vdev 'eth_vhost0,iface=/tmp/sock0,queues=2' \
> 	--no-pci -- -i --rxq=2 --txq=2 --nb-cores=2
> 
> Step 3, boot the VM:
>   $ qemu ... -chardev socket,id=chr1,path=/tmp/sock0 \
> 	-netdev vhost-user,id=net1,chardev=chr1,vhostforce,queues=2 \
> 	-device virtio-net-pci,netdev=net1,mq=on,vectors=5 ...
> 
> Step 4, insert kernel modules
>   $ modprobe vfio enable_unsafe_noiommu_mode=1
>   $ modprobe vfio-pci
> 
> Step 5, start l3fwd-power in VM:
>   $ l3fwd-power -c 0x3 -n 4 -- -p 1 -P --config="(0,0,1),(0,1,1)" \
> 						 --no-numa --parse-ptype
> 
> Step 6, send packets from testpmd on the host:
>   $ start tx_first
> 
> Then l3fwd-power outputs:
>   L3FWD_POWER: lcore 1 is waked up from rx interrupt on port 0 queue 0
>   L3FWD_POWER: lcore 1 is waked up from rx interrupt on port 0 queue 1
> 
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> 
> Jianfeng Tan (10):
>   net/virtio: fix rewriting LSC flag
>   net/virtio: clean up wrapper of set_config_irq
>   net/virtio: add Rx descriptor check
>   net/virtio: add PCI ops for queue/irq binding
>   net/virtio: add Rx queue intr enable/disable functions
>   net/virtio: setup rxq interrupts
>   net/virtio: unbind intr/eventfd when stop device
>   net/virtio: unmapping queue/irq when close device
>   examples/l3fwd-power: add parse-ptype option
>   examples/l3fwd-power: fix not stop and close device
> 
>  drivers/net/virtio/virtio_ethdev.c | 161
> +++++++++++++++++++++++++++++++++++--
>  drivers/net/virtio/virtio_ethdev.h |   3 +
>  drivers/net/virtio/virtio_pci.c    |  31 +++++--
>  drivers/net/virtio/virtio_pci.h    |   5 +-
>  drivers/net/virtio/virtio_rxtx.c   |   9 +++
>  drivers/net/virtio/virtqueue.c     |  11 ---
>  drivers/net/virtio/virtqueue.h     |  16 +++-
>  examples/l3fwd-power/main.c        | 120 ++++++++++++++++++++++++++-
>  8 files changed, 325 insertions(+), 31 deletions(-)
> 
> --
> 2.7.4

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v3 05/10] net/virtio: add Rx queue intr enable/disable functions
  2017-01-16 14:46   ` [PATCH v3 05/10] net/virtio: add Rx queue intr enable/disable functions Jianfeng Tan
@ 2017-01-17  2:30     ` Jason Wang
  0 siblings, 0 replies; 63+ messages in thread
From: Jason Wang @ 2017-01-17  2:30 UTC (permalink / raw)
  To: Jianfeng Tan, dev; +Cc: yuanhan.liu, stephen, lei.a.yao



On 2017年01月16日 22:46, Jianfeng Tan wrote:
> This patch implements interrupt enable/disable functions for each
> Rx queue. And we rely on flags of avail queue as the hint for virtio
> device to interrupt virtio driver or not.
>
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---
>   drivers/net/virtio/virtio_ethdev.c | 22 ++++++++++++++++++++++
>   drivers/net/virtio/virtqueue.c     | 11 -----------
>   drivers/net/virtio/virtqueue.h     | 16 +++++++++++++++-
>   3 files changed, 37 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
> index bec2be2..4224d17 100644
> --- a/drivers/net/virtio/virtio_ethdev.c
> +++ b/drivers/net/virtio/virtio_ethdev.c
> @@ -717,6 +717,26 @@ virtio_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
>   	return 0;
>   }
>   
> +static int
> +virtio_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
> +{
> +	struct virtnet_rx *rxvq = dev->data->rx_queues[queue_id];
> +	struct virtqueue *vq = rxvq->vq;
> +
> +	virtqueue_enable_intr(vq);
> +	return 0;
> +}
> +
> +static int
> +virtio_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id)
> +{
> +	struct virtnet_rx *rxvq = dev->data->rx_queues[queue_id];
> +	struct virtqueue *vq = rxvq->vq;
> +
> +	virtqueue_disable_intr(vq);
> +	return 0;
> +}
> +
>   /*
>    * dev_ops for virtio, bare necessities for basic operation
>    */
> @@ -738,6 +758,8 @@ static const struct eth_dev_ops virtio_eth_dev_ops = {
>   	.xstats_reset            = virtio_dev_stats_reset,
>   	.link_update             = virtio_dev_link_update,
>   	.rx_queue_setup          = virtio_dev_rx_queue_setup,
> +	.rx_queue_intr_enable    = virtio_dev_rx_queue_intr_enable,
> +	.rx_queue_intr_disable   = virtio_dev_rx_queue_intr_disable,
>   	.rx_queue_release        = virtio_dev_queue_release,
>   	.rx_descriptor_done      = virtio_dev_rx_queue_done,
>   	.tx_queue_setup          = virtio_dev_tx_queue_setup,
> diff --git a/drivers/net/virtio/virtqueue.c b/drivers/net/virtio/virtqueue.c
> index 7f60e3e..9ad77b8 100644
> --- a/drivers/net/virtio/virtqueue.c
> +++ b/drivers/net/virtio/virtqueue.c
> @@ -38,17 +38,6 @@
>   #include "virtio_logs.h"
>   #include "virtio_pci.h"
>   
> -void
> -virtqueue_disable_intr(struct virtqueue *vq)
> -{
> -	/*
> -	 * Set VRING_AVAIL_F_NO_INTERRUPT to hint host
> -	 * not to interrupt when it consumes packets
> -	 * Note: this is only considered a hint to the host
> -	 */
> -	vq->vq_ring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT;
> -}
> -
>   /*
>    * Two types of mbuf to be cleaned:
>    * 1) mbuf that has been consumed by backend but not used by virtio.
> diff --git a/drivers/net/virtio/virtqueue.h b/drivers/net/virtio/virtqueue.h
> index b1070e0..f9e3736 100644
> --- a/drivers/net/virtio/virtqueue.h
> +++ b/drivers/net/virtio/virtqueue.h
> @@ -274,7 +274,21 @@ vring_desc_init(struct vring_desc *dp, uint16_t n)
>   /**
>    * Tell the backend not to interrupt us.
>    */
> -void virtqueue_disable_intr(struct virtqueue *vq);
> +static inline void
> +virtqueue_disable_intr(struct virtqueue *vq)
> +{
> +	vq->vq_ring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT;
> +}

I think we'd better consider to implement even index in the future.

Thanks

> +
> +/**
> + * Tell the backend to interrupt us.
> + */
> +static inline void
> +virtqueue_enable_intr(struct virtqueue *vq)
> +{
> +	vq->vq_ring.avail->flags &= (~VRING_AVAIL_F_NO_INTERRUPT);
> +}
> +
>   /**
>    *  Dump virtqueue internal structures, for debug purpose only.
>    */

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v3 03/10] net/virtio: add Rx descriptor check
  2017-01-16 19:16     ` Stephen Hemminger
@ 2017-01-17  4:09       ` Yuanhan Liu
  0 siblings, 0 replies; 63+ messages in thread
From: Yuanhan Liu @ 2017-01-17  4:09 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: Jianfeng Tan, dev, lei.a.yao

On Mon, Jan 16, 2017 at 11:16:03AM -0800, Stephen Hemminger wrote:
> On Mon, 16 Jan 2017 14:46:55 +0000
> Jianfeng Tan <jianfeng.tan@intel.com> wrote:
> 
> > +	return (VIRTQUEUE_NUSED(vq) >= offset);
> 
> Unneeded parenthesis in return statement.
> This is a style thing, Linux folks see it as unnecessary. BSD folks like it

I will remove them while apply. Thanks.

	--yliu

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v3 09/10] examples/l3fwd-power: add parse-ptype option
  2017-01-16 14:47   ` [PATCH v3 09/10] examples/l3fwd-power: add parse-ptype option Jianfeng Tan
@ 2017-01-17  5:16     ` Yuanhan Liu
  2017-01-17  5:23       ` Tan, Jianfeng
  0 siblings, 1 reply; 63+ messages in thread
From: Yuanhan Liu @ 2017-01-17  5:16 UTC (permalink / raw)
  To: Jianfeng Tan; +Cc: dev, stephen, lei.a.yao

On Mon, Jan 16, 2017 at 02:47:01PM +0000, Jianfeng Tan wrote:
> +#if (APP_LOOKUP_METHOD == APP_LOOKUP_LPM)
> +	if (ptype_l3_ipv4)
> +#else
> +	// APP_LOOKUP_EXACT_MATCH

No c++ comment.

Besides, this patchset misses the release note. Also bear in mind I
think this feature deserves a howto doc.

	--yliu

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v3 09/10] examples/l3fwd-power: add parse-ptype option
  2017-01-17  5:16     ` Yuanhan Liu
@ 2017-01-17  5:23       ` Tan, Jianfeng
  0 siblings, 0 replies; 63+ messages in thread
From: Tan, Jianfeng @ 2017-01-17  5:23 UTC (permalink / raw)
  To: Yuanhan Liu; +Cc: dev, stephen, Yao, Lei A



> -----Original Message-----
> From: Yuanhan Liu [mailto:yuanhan.liu@linux.intel.com]
> Sent: Tuesday, January 17, 2017 1:16 PM
> To: Tan, Jianfeng
> Cc: dev@dpdk.org; stephen@networkplumber.org; Yao, Lei A
> Subject: Re: [PATCH v3 09/10] examples/l3fwd-power: add parse-ptype
> option
> 
> On Mon, Jan 16, 2017 at 02:47:01PM +0000, Jianfeng Tan wrote:
> > +#if (APP_LOOKUP_METHOD == APP_LOOKUP_LPM)
> > +	if (ptype_l3_ipv4)
> > +#else
> > +	// APP_LOOKUP_EXACT_MATCH
> 
> No c++ comment.

OK.

> 
> Besides, this patchset misses the release note. Also bear in mind I
> think this feature deserves a howto doc.

Sorry, I missed that in my stash. Will send a new version with fixing Stephen's comment.

Thanks,
Jianfeng

> 
> 	--yliu

^ permalink raw reply	[flat|nested] 63+ messages in thread

* [PATCH v4 00/10] rxq interrupt mode for virtio PMD
  2016-12-04  0:18 [PATCH 0/5] Interrupt mode for virtio PMD Jianfeng Tan
                   ` (6 preceding siblings ...)
  2017-01-16 14:46 ` [PATCH v3 00/10] " Jianfeng Tan
@ 2017-01-17  7:10 ` Jianfeng Tan
  2017-01-17  7:10   ` [PATCH v4 01/10] net/virtio: fix rewriting LSC flag Jianfeng Tan
                     ` (10 more replies)
  2017-01-17  8:00 ` [PATCH v5 06/10] net/virtio: setup rxq interrupts Jianfeng Tan
  8 siblings, 11 replies; 63+ messages in thread
From: Jianfeng Tan @ 2017-01-17  7:10 UTC (permalink / raw)
  To: dev; +Cc: yuanhan.liu, stephen, lei.a.yao, Jianfeng Tan

v4:
  - Update documents:
    * doc/guides/nics/features/virtio.ini
    * doc/guides/nics/features/virtio_vec.ini
    * doc/guides/nics/virtio.rst
  - Remove unneeded parenthesis in return statement.
  - Change c++ comment style.

v3:
  - Use hw->max_queue_pairs instead of dev->data->nb_rx_queues to
    allocate intr_vec array.
  - Fix v2 not working on legacy virtio devices by moving msix enabling
    before queue/irq binding.
  - Reword cover letter to give an overview of this series.
  - Remove wrapper to call vtpci->set_config_irq and vtpci->set_queue_irq.
  - Rebase on the new code, and fix a bug after changes by the commit
    bb30369dc10("eal: allow passing const interrupt handle"). Basically,
    it changes the way to get max interrupts. And we need to re-register
    callback to update intr_handle->max_intr.
  - In l3fwd-power ptype fix, use rte_eth_dev_get_supported_ptypes() to
    query if PMD provides needed ptypes.

v2:
  - Add PCI queue/irq config ops.
  - Move rxq interrupt settings before sending DRIVER OK.

Historically, virtio PMD can only be binded to igb_uio or
uio_pci_generic, and not for vfio-pci (iommu group cannot be created as
vIOMMU is not enabled in QEMU yet).  Besides, quote from
http://dpdk.org/doc/guides-16.11/rel_notes/release_2_1.html:
  "Per queue RX interrupt events are only allowed in VFIO
   which supports multiple MSI-X vectors."

Linux starts to support VFIO NO-IOMMU mode since 4.8.0. It cannot put
devices into groups for separation as normal VFIO does. So it does not
require QEMU to support vIOMMU. But it does inherit other benefits from
VFIO framework, like better interrupts supports (than UIO). It gives a
good chance to enable rxq interrupt for virtio PMD.

To implement it,
a. Firstly, we need to enable msix. This should be done before DRIVER_OK
setting and also before queue/irq binding in step b.
b. Bind queue/irq through portio (legacy devices) or mmio (modern devices).
   So far, we hard-code 1:1 queue/irq mapping (each rx queue has one
   exclusive interrupt), like this:
      vec 0 -> config irq
      vec 1 -> rxq0
      vec 2 -> rxq1
      ...
    
    which means, the "vectors" option of QEMU should be configured with
    a value >= N+1 (N is the number of the queue pairs).
c. To enable/disable interrupt notification, flags on virtqueues are used
   to control devices either sending interrupt or not.
d. Encap above behaviors into callbacks in ether_dev_ops, like
   rx_queue_intr_enable/rx_queue_intr_disable/rx_descriptor_done etc.


How to test:

Step 1, prepare a VM image with kernel version >= 4.8.0, and make sure
the kernel is compiled with CONFIG_VFIO_NOIOMMU=y.

Step 2, on the host, start a testpmd with a vhost port:
  $ testpmd -c 0x7 -m 1024 --vdev 'eth_vhost0,iface=/tmp/sock0,queues=2' \
	--no-pci -- -i --rxq=2 --txq=2 --nb-cores=2

Step 3, boot the VM:
  $ qemu ... -chardev socket,id=chr1,path=/tmp/sock0 \
	-netdev vhost-user,id=net1,chardev=chr1,vhostforce,queues=2 \
	-device virtio-net-pci,netdev=net1,mq=on,vectors=5 ...

Step 4, insert kernel modules
  $ modprobe vfio enable_unsafe_noiommu_mode=1
  $ modprobe vfio-pci

Step 5, start l3fwd-power in VM:
  $ l3fwd-power -c 0x3 -n 4 -- -p 1 -P --config="(0,0,1),(0,1,1)" \
						 --no-numa --parse-ptype

Step 6, send packets from testpmd on the host:
  $ start tx_first

Then l3fwd-power outputs:
  L3FWD_POWER: lcore 1 is waked up from rx interrupt on port 0 queue 0
  L3FWD_POWER: lcore 1 is waked up from rx interrupt on port 0 queue 1

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Tested-by: Lei Yao <lei.a.yao@intel.com>

Jianfeng Tan (10):
  net/virtio: fix rewriting LSC flag
  net/virtio: clean up wrapper of set_config_irq
  net/virtio: add Rx descriptor check
  net/virtio: add PCI ops for queue/irq binding
  net/virtio: add Rx queue intr enable/disable functions
  net/virtio: setup rxq interrupts
  net/virtio: unbind intr/eventfd when stop device
  net/virtio: unmapping queue/irq when close device
  examples/l3fwd-power: add parse-ptype option
  examples/l3fwd-power: fix not stop and close device

 doc/guides/nics/features/virtio.ini     |   1 +
 doc/guides/nics/features/virtio_vec.ini |   1 +
 doc/guides/nics/virtio.rst              |  58 ++++++++++++
 drivers/net/virtio/virtio_ethdev.c      | 161 ++++++++++++++++++++++++++++++--
 drivers/net/virtio/virtio_ethdev.h      |   3 +
 drivers/net/virtio/virtio_pci.c         |  31 ++++--
 drivers/net/virtio/virtio_pci.h         |   5 +-
 drivers/net/virtio/virtio_rxtx.c        |   9 ++
 drivers/net/virtio/virtqueue.c          |  11 ---
 drivers/net/virtio/virtqueue.h          |  16 +++-
 examples/l3fwd-power/main.c             | 119 ++++++++++++++++++++++-
 11 files changed, 384 insertions(+), 31 deletions(-)

-- 
2.7.4

^ permalink raw reply	[flat|nested] 63+ messages in thread

* [PATCH v4 01/10] net/virtio: fix rewriting LSC flag
  2017-01-17  7:10 ` [PATCH v4 " Jianfeng Tan
@ 2017-01-17  7:10   ` Jianfeng Tan
  2017-01-17  7:10   ` [PATCH v4 02/10] net/virtio: clean up wrapper of set_config_irq Jianfeng Tan
                     ` (9 subsequent siblings)
  10 siblings, 0 replies; 63+ messages in thread
From: Jianfeng Tan @ 2017-01-17  7:10 UTC (permalink / raw)
  To: dev; +Cc: yuanhan.liu, stephen, lei.a.yao, Jianfeng Tan, stable

The LSC flag is decided according to if VIRTIO_NET_F_STATUS feature
is negotiated. Copy the PCI info after the judgement will rewrite
the correct result.

Fixes: 198ab33677c9 ("net/virtio: move device initialization in a function")

CC: stable@dpdk.org

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Tested-by: Lei Yao <lei.a.yao@intel.com>
---
 drivers/net/virtio/virtio_ethdev.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index f596f4d..837d3df 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1208,17 +1208,17 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
 	if (virtio_negotiate_features(hw, req_features) < 0)
 		return -1;
 
+	if (eth_dev->device) {
+		pci_dev = RTE_DEV_TO_PCI(eth_dev->device);
+		rte_eth_copy_pci_info(eth_dev, pci_dev);
+	}
+
 	/* If host does not support status then disable LSC */
 	if (!vtpci_with_feature(hw, VIRTIO_NET_F_STATUS))
 		eth_dev->data->dev_flags &= ~RTE_ETH_DEV_INTR_LSC;
 	else
 		eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC;
 
-	if (eth_dev->device) {
-		pci_dev = RTE_DEV_TO_PCI(eth_dev->device);
-		rte_eth_copy_pci_info(eth_dev, pci_dev);
-	}
-
 	rx_func_get(eth_dev);
 
 	/* Setting up rx_header size for the device */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v4 02/10] net/virtio: clean up wrapper of set_config_irq
  2017-01-17  7:10 ` [PATCH v4 " Jianfeng Tan
  2017-01-17  7:10   ` [PATCH v4 01/10] net/virtio: fix rewriting LSC flag Jianfeng Tan
@ 2017-01-17  7:10   ` Jianfeng Tan
  2017-01-17  7:10   ` [PATCH v4 03/10] net/virtio: add Rx descriptor check Jianfeng Tan
                     ` (8 subsequent siblings)
  10 siblings, 0 replies; 63+ messages in thread
From: Jianfeng Tan @ 2017-01-17  7:10 UTC (permalink / raw)
  To: dev; +Cc: yuanhan.liu, stephen, lei.a.yao, Jianfeng Tan

We need to define a prototype for such wrapper, which makes thing
too complicated. Remove wrapper and call set_config_irq directly.

Suggested-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Tested-by: Lei Yao <lei.a.yao@intel.com>
---
 drivers/net/virtio/virtio_ethdev.c | 6 ++++--
 drivers/net/virtio/virtio_pci.c    | 8 --------
 drivers/net/virtio/virtio_pci.h    | 2 --
 3 files changed, 4 insertions(+), 12 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 837d3df..a790c46 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -602,7 +602,7 @@ virtio_dev_close(struct rte_eth_dev *dev)
 
 	/* reset the NIC */
 	if (dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC)
-		vtpci_irq_config(hw, VIRTIO_MSI_NO_VECTOR);
+		VTPCI_OPS(hw)->set_config_irq(hw, VIRTIO_MSI_NO_VECTOR);
 	vtpci_reset(hw);
 	virtio_dev_free_mbufs(dev);
 	virtio_free_queues(hw);
@@ -1520,7 +1520,9 @@ virtio_dev_configure(struct rte_eth_dev *dev)
 	}
 
 	if (dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC)
-		if (vtpci_irq_config(hw, 0) == VIRTIO_MSI_NO_VECTOR) {
+		/* Enable vector (0) for Link State Intrerrupt */
+		if (VTPCI_OPS(hw)->set_config_irq(hw, 0) ==
+				VIRTIO_MSI_NO_VECTOR) {
 			PMD_DRV_LOG(ERR, "failed to set config vector");
 			return -EBUSY;
 		}
diff --git a/drivers/net/virtio/virtio_pci.c b/drivers/net/virtio/virtio_pci.c
index fbdb5b7..3ca6ba1 100644
--- a/drivers/net/virtio/virtio_pci.c
+++ b/drivers/net/virtio/virtio_pci.c
@@ -600,14 +600,6 @@ vtpci_isr(struct virtio_hw *hw)
 	return VTPCI_OPS(hw)->get_isr(hw);
 }
 
-
-/* Enable one vector (0) for Link State Intrerrupt */
-uint16_t
-vtpci_irq_config(struct virtio_hw *hw, uint16_t vec)
-{
-	return VTPCI_OPS(hw)->set_config_irq(hw, vec);
-}
-
 static void *
 get_cfg_addr(struct rte_pci_device *dev, struct virtio_pci_cap *cap)
 {
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index 4235bef..588d41f 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -330,8 +330,6 @@ void vtpci_read_dev_config(struct virtio_hw *, size_t, void *, int);
 
 uint8_t vtpci_isr(struct virtio_hw *);
 
-uint16_t vtpci_irq_config(struct virtio_hw *, uint16_t);
-
 extern const struct virtio_pci_ops legacy_ops;
 extern const struct virtio_pci_ops modern_ops;
 extern const struct virtio_pci_ops virtio_user_ops;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v4 03/10] net/virtio: add Rx descriptor check
  2017-01-17  7:10 ` [PATCH v4 " Jianfeng Tan
  2017-01-17  7:10   ` [PATCH v4 01/10] net/virtio: fix rewriting LSC flag Jianfeng Tan
  2017-01-17  7:10   ` [PATCH v4 02/10] net/virtio: clean up wrapper of set_config_irq Jianfeng Tan
@ 2017-01-17  7:10   ` Jianfeng Tan
  2017-01-17  7:10   ` [PATCH v4 04/10] net/virtio: add PCI ops for queue/irq binding Jianfeng Tan
                     ` (7 subsequent siblings)
  10 siblings, 0 replies; 63+ messages in thread
From: Jianfeng Tan @ 2017-01-17  7:10 UTC (permalink / raw)
  To: dev; +Cc: yuanhan.liu, stephen, lei.a.yao, Jianfeng Tan

Under interrupt mode, rx_descriptor_done is used as an indicator
for applications to check if some number of packets are ready to
be received.

This patch enables this by checking used ring's local consumed idx
with shared (with backend) idx.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Tested-by: Lei Yao <lei.a.yao@intel.com>
---
 drivers/net/virtio/virtio_ethdev.c | 1 +
 drivers/net/virtio/virtio_ethdev.h | 3 +++
 drivers/net/virtio/virtio_rxtx.c   | 9 +++++++++
 3 files changed, 13 insertions(+)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index a790c46..bec2be2 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -739,6 +739,7 @@ static const struct eth_dev_ops virtio_eth_dev_ops = {
 	.link_update             = virtio_dev_link_update,
 	.rx_queue_setup          = virtio_dev_rx_queue_setup,
 	.rx_queue_release        = virtio_dev_queue_release,
+	.rx_descriptor_done      = virtio_dev_rx_queue_done,
 	.tx_queue_setup          = virtio_dev_tx_queue_setup,
 	.tx_queue_release        = virtio_dev_queue_release,
 	/* collect stats per queue */
diff --git a/drivers/net/virtio/virtio_ethdev.h b/drivers/net/virtio/virtio_ethdev.h
index 27d9a19..4ab81c6 100644
--- a/drivers/net/virtio/virtio_ethdev.h
+++ b/drivers/net/virtio/virtio_ethdev.h
@@ -78,6 +78,9 @@ void virtio_dev_cq_start(struct rte_eth_dev *dev);
 /*
  * RX/TX function prototypes
  */
+
+int virtio_dev_rx_queue_done(void *rxq, uint16_t offset);
+
 int  virtio_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t rx_queue_id,
 		uint16_t nb_rx_desc, unsigned int socket_id,
 		const struct rte_eth_rxconf *rx_conf,
diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c
index 1e5a6b9..b29565e 100644
--- a/drivers/net/virtio/virtio_rxtx.c
+++ b/drivers/net/virtio/virtio_rxtx.c
@@ -72,6 +72,15 @@
 #define VIRTIO_SIMPLE_FLAGS ((uint32_t)ETH_TXQ_FLAGS_NOMULTSEGS | \
 	ETH_TXQ_FLAGS_NOOFFLOADS)
 
+int
+virtio_dev_rx_queue_done(void *rxq, uint16_t offset)
+{
+	struct virtnet_rx *rxvq = rxq;
+	struct virtqueue *vq = rxvq->vq;
+
+	return VIRTQUEUE_NUSED(vq) >= offset;
+}
+
 static void
 vq_ring_free_chain(struct virtqueue *vq, uint16_t desc_idx)
 {
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v4 04/10] net/virtio: add PCI ops for queue/irq binding
  2017-01-17  7:10 ` [PATCH v4 " Jianfeng Tan
                     ` (2 preceding siblings ...)
  2017-01-17  7:10   ` [PATCH v4 03/10] net/virtio: add Rx descriptor check Jianfeng Tan
@ 2017-01-17  7:10   ` Jianfeng Tan
  2017-01-17  7:10   ` [PATCH v4 05/10] net/virtio: add Rx queue intr enable/disable functions Jianfeng Tan
                     ` (6 subsequent siblings)
  10 siblings, 0 replies; 63+ messages in thread
From: Jianfeng Tan @ 2017-01-17  7:10 UTC (permalink / raw)
  To: dev; +Cc: yuanhan.liu, stephen, lei.a.yao, Jianfeng Tan

Add handler in virtio_pci_ops to set queue/irq bind.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Tested-by: Lei Yao <lei.a.yao@intel.com>
---
 drivers/net/virtio/virtio_pci.c | 23 +++++++++++++++++++++++
 drivers/net/virtio/virtio_pci.h |  3 +++
 2 files changed, 26 insertions(+)

diff --git a/drivers/net/virtio/virtio_pci.c b/drivers/net/virtio/virtio_pci.c
index 3ca6ba1..6d2d10d 100644
--- a/drivers/net/virtio/virtio_pci.c
+++ b/drivers/net/virtio/virtio_pci.c
@@ -219,6 +219,19 @@ legacy_set_config_irq(struct virtio_hw *hw, uint16_t vec)
 }
 
 static uint16_t
+legacy_set_queue_irq(struct virtio_hw *hw, struct virtqueue *vq, uint16_t vec)
+{
+	uint16_t dst;
+
+	rte_eal_pci_ioport_write(VTPCI_IO(hw), &vq->vq_queue_index, 2,
+				 VIRTIO_PCI_QUEUE_SEL);
+	rte_eal_pci_ioport_write(VTPCI_IO(hw), &vec, 2,
+				 VIRTIO_MSI_QUEUE_VECTOR);
+	rte_eal_pci_ioport_read(VTPCI_IO(hw), &dst, 2, VIRTIO_MSI_QUEUE_VECTOR);
+	return dst;
+}
+
+static uint16_t
 legacy_get_queue_num(struct virtio_hw *hw, uint16_t queue_id)
 {
 	uint16_t dst;
@@ -313,6 +326,7 @@ const struct virtio_pci_ops legacy_ops = {
 	.set_features	= legacy_set_features,
 	.get_isr	= legacy_get_isr,
 	.set_config_irq	= legacy_set_config_irq,
+	.set_queue_irq  = legacy_set_queue_irq,
 	.get_queue_num	= legacy_get_queue_num,
 	.setup_queue	= legacy_setup_queue,
 	.del_queue	= legacy_del_queue,
@@ -452,6 +466,14 @@ modern_set_config_irq(struct virtio_hw *hw, uint16_t vec)
 }
 
 static uint16_t
+modern_set_queue_irq(struct virtio_hw *hw, struct virtqueue *vq, uint16_t vec)
+{
+	io_write16(vq->vq_queue_index, &hw->common_cfg->queue_select);
+	io_write16(vec, &hw->common_cfg->queue_msix_vector);
+	return io_read16(&hw->common_cfg->queue_msix_vector);
+}
+
+static uint16_t
 modern_get_queue_num(struct virtio_hw *hw, uint16_t queue_id)
 {
 	io_write16(queue_id, &hw->common_cfg->queue_select);
@@ -529,6 +551,7 @@ const struct virtio_pci_ops modern_ops = {
 	.set_features	= modern_set_features,
 	.get_isr	= modern_get_isr,
 	.set_config_irq	= modern_set_config_irq,
+	.set_queue_irq  = modern_set_queue_irq,
 	.get_queue_num	= modern_get_queue_num,
 	.setup_queue	= modern_setup_queue,
 	.del_queue	= modern_del_queue,
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index 588d41f..59e45c4 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -235,6 +235,9 @@ struct virtio_pci_ops {
 
 	uint16_t (*set_config_irq)(struct virtio_hw *hw, uint16_t vec);
 
+	uint16_t (*set_queue_irq)(struct virtio_hw *hw, struct virtqueue *vq,
+			uint16_t vec);
+
 	uint16_t (*get_queue_num)(struct virtio_hw *hw, uint16_t queue_id);
 	int (*setup_queue)(struct virtio_hw *hw, struct virtqueue *vq);
 	void (*del_queue)(struct virtio_hw *hw, struct virtqueue *vq);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v4 05/10] net/virtio: add Rx queue intr enable/disable functions
  2017-01-17  7:10 ` [PATCH v4 " Jianfeng Tan
                     ` (3 preceding siblings ...)
  2017-01-17  7:10   ` [PATCH v4 04/10] net/virtio: add PCI ops for queue/irq binding Jianfeng Tan
@ 2017-01-17  7:10   ` Jianfeng Tan
  2017-01-17  7:10   ` [PATCH v4 06/10] net/virtio: setup rxq interrupts Jianfeng Tan
                     ` (5 subsequent siblings)
  10 siblings, 0 replies; 63+ messages in thread
From: Jianfeng Tan @ 2017-01-17  7:10 UTC (permalink / raw)
  To: dev; +Cc: yuanhan.liu, stephen, lei.a.yao, Jianfeng Tan

This patch implements interrupt enable/disable functions for each
Rx queue. And we rely on flags of avail queue as the hint for virtio
device to interrupt virtio driver or not.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Tested-by: Lei Yao <lei.a.yao@intel.com>
---
 drivers/net/virtio/virtio_ethdev.c | 22 ++++++++++++++++++++++
 drivers/net/virtio/virtqueue.c     | 11 -----------
 drivers/net/virtio/virtqueue.h     | 16 +++++++++++++++-
 3 files changed, 37 insertions(+), 12 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index bec2be2..4224d17 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -717,6 +717,26 @@ virtio_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
 	return 0;
 }
 
+static int
+virtio_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
+{
+	struct virtnet_rx *rxvq = dev->data->rx_queues[queue_id];
+	struct virtqueue *vq = rxvq->vq;
+
+	virtqueue_enable_intr(vq);
+	return 0;
+}
+
+static int
+virtio_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id)
+{
+	struct virtnet_rx *rxvq = dev->data->rx_queues[queue_id];
+	struct virtqueue *vq = rxvq->vq;
+
+	virtqueue_disable_intr(vq);
+	return 0;
+}
+
 /*
  * dev_ops for virtio, bare necessities for basic operation
  */
@@ -738,6 +758,8 @@ static const struct eth_dev_ops virtio_eth_dev_ops = {
 	.xstats_reset            = virtio_dev_stats_reset,
 	.link_update             = virtio_dev_link_update,
 	.rx_queue_setup          = virtio_dev_rx_queue_setup,
+	.rx_queue_intr_enable    = virtio_dev_rx_queue_intr_enable,
+	.rx_queue_intr_disable   = virtio_dev_rx_queue_intr_disable,
 	.rx_queue_release        = virtio_dev_queue_release,
 	.rx_descriptor_done      = virtio_dev_rx_queue_done,
 	.tx_queue_setup          = virtio_dev_tx_queue_setup,
diff --git a/drivers/net/virtio/virtqueue.c b/drivers/net/virtio/virtqueue.c
index 7f60e3e..9ad77b8 100644
--- a/drivers/net/virtio/virtqueue.c
+++ b/drivers/net/virtio/virtqueue.c
@@ -38,17 +38,6 @@
 #include "virtio_logs.h"
 #include "virtio_pci.h"
 
-void
-virtqueue_disable_intr(struct virtqueue *vq)
-{
-	/*
-	 * Set VRING_AVAIL_F_NO_INTERRUPT to hint host
-	 * not to interrupt when it consumes packets
-	 * Note: this is only considered a hint to the host
-	 */
-	vq->vq_ring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT;
-}
-
 /*
  * Two types of mbuf to be cleaned:
  * 1) mbuf that has been consumed by backend but not used by virtio.
diff --git a/drivers/net/virtio/virtqueue.h b/drivers/net/virtio/virtqueue.h
index b1070e0..f9e3736 100644
--- a/drivers/net/virtio/virtqueue.h
+++ b/drivers/net/virtio/virtqueue.h
@@ -274,7 +274,21 @@ vring_desc_init(struct vring_desc *dp, uint16_t n)
 /**
  * Tell the backend not to interrupt us.
  */
-void virtqueue_disable_intr(struct virtqueue *vq);
+static inline void
+virtqueue_disable_intr(struct virtqueue *vq)
+{
+	vq->vq_ring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT;
+}
+
+/**
+ * Tell the backend to interrupt us.
+ */
+static inline void
+virtqueue_enable_intr(struct virtqueue *vq)
+{
+	vq->vq_ring.avail->flags &= (~VRING_AVAIL_F_NO_INTERRUPT);
+}
+
 /**
  *  Dump virtqueue internal structures, for debug purpose only.
  */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v4 06/10] net/virtio: setup rxq interrupts
  2017-01-17  7:10 ` [PATCH v4 " Jianfeng Tan
                     ` (4 preceding siblings ...)
  2017-01-17  7:10   ` [PATCH v4 05/10] net/virtio: add Rx queue intr enable/disable functions Jianfeng Tan
@ 2017-01-17  7:10   ` Jianfeng Tan
  2017-01-17  7:10   ` [PATCH v4 07/10] net/virtio: unbind intr/eventfd when stop device Jianfeng Tan
                     ` (4 subsequent siblings)
  10 siblings, 0 replies; 63+ messages in thread
From: Jianfeng Tan @ 2017-01-17  7:10 UTC (permalink / raw)
  To: dev; +Cc: yuanhan.liu, stephen, lei.a.yao, Jianfeng Tan

This patch mainly allocates structure to store queue/irq mapping,
and configure queue/irq mapping down through PCI ops. It also creates
eventfds for each Rx queue and tell the kernel about the eventfd/intr
binding.

Note: So far, we hard-code 1:1 queue/irq mapping (each rx queue has
one exclusive interrupt), like this:
  vec 0 -> config irq
  vec 1 -> rxq0
  vec 2 -> rxq1
  ...

which means, the "vectors" option of QEMU should be configured with
a value >= N+1 (N is the number of the queue pairs).

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Tested-by: Lei Yao <lei.a.yao@intel.com>
---
 doc/guides/nics/features/virtio.ini     |  1 +
 doc/guides/nics/features/virtio_vec.ini |  1 +
 doc/guides/nics/virtio.rst              | 58 +++++++++++++++++++++++
 drivers/net/virtio/virtio_ethdev.c      | 84 +++++++++++++++++++++++++++++++++
 4 files changed, 144 insertions(+)

diff --git a/doc/guides/nics/features/virtio.ini b/doc/guides/nics/features/virtio.ini
index f5de291..7f038c5 100644
--- a/doc/guides/nics/features/virtio.ini
+++ b/doc/guides/nics/features/virtio.ini
@@ -5,6 +5,7 @@
 ;
 [Features]
 Link status          = Y
+Rx interrupt         = Y
 Queue start/stop     = Y
 Scattered Rx         = Y
 Promiscuous mode     = Y
diff --git a/doc/guides/nics/features/virtio_vec.ini b/doc/guides/nics/features/virtio_vec.ini
index 6dc7cf0..ec93f5c 100644
--- a/doc/guides/nics/features/virtio_vec.ini
+++ b/doc/guides/nics/features/virtio_vec.ini
@@ -5,6 +5,7 @@
 ;
 [Features]
 Link status          = Y
+Rx interrupt         = Y
 Queue start/stop     = Y
 Promiscuous mode     = Y
 Allmulticast mode    = Y
diff --git a/doc/guides/nics/virtio.rst b/doc/guides/nics/virtio.rst
index c90e517..42600f3 100644
--- a/doc/guides/nics/virtio.rst
+++ b/doc/guides/nics/virtio.rst
@@ -87,6 +87,8 @@ In this release, the virtio PMD driver provides the basic functionality of packe
 
 *   Virtio supports Link State interrupt.
 
+*   Virtio supports Rx interrupt (so far, only support 1:1 mapping for queue/interrupt).
+
 *   Virtio supports software vlan stripping and inserting.
 
 *   Virtio supports using port IO to get PCI resource when uio/igb_uio module is not available.
@@ -274,3 +276,59 @@ Example of using the vector version of the virtio poll mode driver in
 ``testpmd``::
 
    testpmd -c 0x7 -n 4 -- -i --txqflags=0xF01 --rxq=1 --txq=1 --nb-cores=1
+
+
+Interrupt mode
+--------------
+
+There are three kinds of interrupts from a virtio device over PCI bus: config
+interrupt, Rx interrupts, and Tx interrupts. Config interrupt is used for
+notification of device configuration changes, especially link status (lsc).
+Interrupt mode is translated into Rx interrupts in the context of DPDK.
+
+Prerequisites for Rx interrupts
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To support Rx interrupts,
+#. Check if guest kernel supports VFIO-NOIOMMU:
+
+    Linux started to support VFIO-NOIOMMU since 4.8.0. Make sure the guest
+    kernel is compiled with:
+
+    .. code-block:: console
+
+        CONFIG_VFIO_NOIOMMU=y
+
+#. Properly set msix vectors when starting VM:
+
+    Enable multi-queue when starting VM, and specify msix vectors in qemu
+    cmdline. (N+1) is the minimum, and (2N+2) is mostly recommended.
+
+    .. code-block:: console
+
+        $(QEMU) ... -device virtio-net-pci,mq=on,vectors=2N+2 ...
+
+#. In VM, insert vfio module in NOIOMMU mode:
+
+    .. code-block:: console
+
+        modprobe vfio enable_unsafe_noiommu_mode=1
+        modprobe vfio-pci
+
+#. In VM, bind the virtio device with vfio-pci:
+
+    .. code-block:: console
+
+        python tools/dpdk-devbind.py -b vfio-pci 00:03.0
+
+Example
+~~~~~~~
+
+Here we use l3fwd-power as an example to show how to get started.
+
+    Example:
+
+    .. code-block:: console
+
+        $ l3fwd-power -c 0x3 -- -p 1 -P --config="(0,0,1)" \
+                                               --no-numa --parse-ptype
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 4224d17..e870125 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1210,6 +1210,82 @@ rx_func_get(struct rte_eth_dev *eth_dev)
 		eth_dev->rx_pkt_burst = &virtio_recv_pkts;
 }
 
+/* Only support 1:1 queue/interrupt mapping so far.
+ * TODO: support n:1 queue/interrupt mapping when there are limited number of
+ * interrupt vectors (<N+1).
+ */
+static int
+virtio_queues_bind_intr(struct rte_eth_dev *dev)
+{
+	uint32_t i;
+	struct virtio_hw *hw = dev->data->dev_private;
+
+	PMD_INIT_LOG(INFO, "queue/interrupt binding\n");
+	for (i = 0; i < dev->data->nb_rx_queues; ++i) {
+		dev->intr_handle->intr_vec[i] = i + 1;
+		if (VTPCI_OPS(hw)->set_queue_irq(hw, hw->vqs[i * 2], i + 1) ==
+						 VIRTIO_MSI_NO_VECTOR) {
+			PMD_DRV_LOG(ERR, "failed to set queue vector");
+			return -EBUSY;
+		}
+	}
+
+	return 0;
+}
+
+static int
+virtio_configure_intr(struct rte_eth_dev *dev)
+{
+	struct virtio_hw *hw = dev->data->dev_private;
+
+	if (!rte_intr_cap_multiple(dev->intr_handle)) {
+		PMD_INIT_LOG(ERR, "Multiple intr vector not supported");
+		return -ENOTSUP;
+	}
+
+	if (rte_intr_efd_enable(dev->intr_handle, dev->data->nb_rx_queues)) {
+		PMD_INIT_LOG(ERR, "Fail to create eventfd");
+		return -1;
+	}
+
+	if (!dev->intr_handle->intr_vec) {
+		dev->intr_handle->intr_vec =
+			rte_zmalloc("intr_vec",
+				    hw->max_queue_pairs * sizeof(int), 0);
+		if (!dev->intr_handle->intr_vec) {
+			PMD_INIT_LOG(ERR, "Failed to allocate %u rxq vectors",
+				     hw->max_queue_pairs);
+			return -ENOMEM;
+		}
+	}
+
+	/* Re-register callback to update max_intr */
+	rte_intr_callback_unregister(dev->intr_handle,
+				     virtio_interrupt_handler,
+				     dev);
+	rte_intr_callback_register(dev->intr_handle,
+				   virtio_interrupt_handler,
+				   dev);
+
+	/* DO NOT try to remove this! This function will enable msix, or QEMU
+	 * will encounter SIGSEGV when DRIVER_OK is sent.
+	 * And for legacy devices, this should be done before queue/vec binding
+	 * to change the config size from 20 to 24, or VIRTIO_MSI_QUEUE_VECTOR
+	 * (22) will be ignored.
+	 */
+	if (rte_intr_enable(dev->intr_handle) < 0) {
+		PMD_DRV_LOG(ERR, "interrupt enable failed");
+		return -1;
+	}
+
+	if (virtio_queues_bind_intr(dev) < 0) {
+		PMD_INIT_LOG(ERR, "Failed to bind queue/interrupt");
+		return -1;
+	}
+
+	return 0;
+}
+
 /* reset device and renegotiate features if needed */
 static int
 virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
@@ -1306,6 +1382,14 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
 	ret = virtio_alloc_queues(eth_dev);
 	if (ret < 0)
 		return ret;
+
+	if (eth_dev->data->dev_conf.intr_conf.rxq) {
+		if (virtio_configure_intr(eth_dev) < 0) {
+			PMD_INIT_LOG(ERR, "failed to configure interrupt");
+			return -1;
+		}
+	}
+
 	vtpci_reinit_complete(hw);
 
 	if (pci_dev)
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v4 07/10] net/virtio: unbind intr/eventfd when stop device
  2017-01-17  7:10 ` [PATCH v4 " Jianfeng Tan
                     ` (5 preceding siblings ...)
  2017-01-17  7:10   ` [PATCH v4 06/10] net/virtio: setup rxq interrupts Jianfeng Tan
@ 2017-01-17  7:10   ` Jianfeng Tan
  2017-01-17  7:10   ` [PATCH v4 08/10] net/virtio: unmapping queue/irq when close device Jianfeng Tan
                     ` (3 subsequent siblings)
  10 siblings, 0 replies; 63+ messages in thread
From: Jianfeng Tan @ 2017-01-17  7:10 UTC (permalink / raw)
  To: dev; +Cc: yuanhan.liu, stephen, lei.a.yao, Jianfeng Tan

When virtio devices get stopped, tell the kernel to unbind the
mapping between interrupts and eventfds.

Note: it behaves differently from other NICs which close eventfds,
free struct. In virtio, we do those things when close device in
following patch.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Tested-by: Lei Yao <lei.a.yao@intel.com>
---
 drivers/net/virtio/virtio_ethdev.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index e870125..5030ed5 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1652,6 +1652,15 @@ virtio_dev_start(struct rte_eth_dev *dev)
 			PMD_DRV_LOG(ERR, "link status not supported by host");
 			return -ENOTSUP;
 		}
+	}
+
+	/* Enable uio/vfio intr/eventfd mapping: althrough we already did that
+	 * in device configure, but it could be unmapped  when device is
+	 * stopped.
+	 */
+	if (dev->data->dev_conf.intr_conf.lsc ||
+	    dev->data->dev_conf.intr_conf.rxq) {
+		rte_intr_disable(dev->intr_handle);
 
 		if (rte_intr_enable(dev->intr_handle) < 0) {
 			PMD_DRV_LOG(ERR, "interrupt enable failed");
@@ -1746,10 +1755,11 @@ static void
 virtio_dev_stop(struct rte_eth_dev *dev)
 {
 	struct rte_eth_link link;
+	struct rte_intr_conf *intr_conf = &dev->data->dev_conf.intr_conf;
 
 	PMD_INIT_LOG(DEBUG, "stop");
 
-	if (dev->data->dev_conf.intr_conf.lsc)
+	if (intr_conf->lsc || intr_conf->rxq)
 		rte_intr_disable(dev->intr_handle);
 
 	memset(&link, 0, sizeof(link));
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v4 08/10] net/virtio: unmapping queue/irq when close device
  2017-01-17  7:10 ` [PATCH v4 " Jianfeng Tan
                     ` (6 preceding siblings ...)
  2017-01-17  7:10   ` [PATCH v4 07/10] net/virtio: unbind intr/eventfd when stop device Jianfeng Tan
@ 2017-01-17  7:10   ` Jianfeng Tan
  2017-01-17  7:10   ` [PATCH v4 09/10] examples/l3fwd-power: add parse-ptype option Jianfeng Tan
                     ` (2 subsequent siblings)
  10 siblings, 0 replies; 63+ messages in thread
From: Jianfeng Tan @ 2017-01-17  7:10 UTC (permalink / raw)
  To: dev; +Cc: yuanhan.liu, stephen, lei.a.yao, Jianfeng Tan

When closing virtio devices, close eventfds, free the struct to
store queue/irq mapping.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Tested-by: Lei Yao <lei.a.yao@intel.com>
---
 drivers/net/virtio/virtio_ethdev.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 5030ed5..0aad295 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -593,16 +593,29 @@ virtio_alloc_queues(struct rte_eth_dev *dev)
 	return 0;
 }
 
+static void virtio_queues_unbind_intr(struct rte_eth_dev *dev);
+
 static void
 virtio_dev_close(struct rte_eth_dev *dev)
 {
 	struct virtio_hw *hw = dev->data->dev_private;
+	struct rte_intr_conf *intr_conf = &dev->data->dev_conf.intr_conf;
 
 	PMD_INIT_LOG(DEBUG, "virtio_dev_close");
 
 	/* reset the NIC */
 	if (dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC)
 		VTPCI_OPS(hw)->set_config_irq(hw, VIRTIO_MSI_NO_VECTOR);
+	if (intr_conf->rxq)
+		virtio_queues_unbind_intr(dev);
+
+	if (intr_conf->lsc || intr_conf->rxq) {
+		rte_intr_disable(dev->intr_handle);
+		rte_intr_efd_disable(dev->intr_handle);
+		rte_free(dev->intr_handle->intr_vec);
+		dev->intr_handle->intr_vec = NULL;
+	}
+
 	vtpci_reset(hw);
 	virtio_dev_free_mbufs(dev);
 	virtio_free_queues(hw);
@@ -1233,6 +1246,19 @@ virtio_queues_bind_intr(struct rte_eth_dev *dev)
 	return 0;
 }
 
+static void
+virtio_queues_unbind_intr(struct rte_eth_dev *dev)
+{
+	uint32_t i;
+	struct virtio_hw *hw = dev->data->dev_private;
+
+	PMD_INIT_LOG(INFO, "queue/interrupt unbinding\n");
+	for (i = 0; i < dev->data->nb_rx_queues; ++i)
+		VTPCI_OPS(hw)->set_queue_irq(hw,
+					     hw->vqs[i * VTNET_CQ],
+					     VIRTIO_MSI_NO_VECTOR);
+}
+
 static int
 virtio_configure_intr(struct rte_eth_dev *dev)
 {
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v4 09/10] examples/l3fwd-power: add parse-ptype option
  2017-01-17  7:10 ` [PATCH v4 " Jianfeng Tan
                     ` (7 preceding siblings ...)
  2017-01-17  7:10   ` [PATCH v4 08/10] net/virtio: unmapping queue/irq when close device Jianfeng Tan
@ 2017-01-17  7:10   ` Jianfeng Tan
  2017-01-17  7:10   ` [PATCH v4 10/10] examples/l3fwd-power: fix not stop and close device Jianfeng Tan
  2017-01-17  8:28   ` [PATCH v4 00/10] rxq interrupt mode for virtio PMD Yuanhan Liu
  10 siblings, 0 replies; 63+ messages in thread
From: Jianfeng Tan @ 2017-01-17  7:10 UTC (permalink / raw)
  To: dev; +Cc: yuanhan.liu, stephen, lei.a.yao, Jianfeng Tan

To support those devices that do not provide packet type info when
receiving packets, add a new option, --parse-ptype, to analyze
packet type in the Rx callback.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Tested-by: Lei Yao <lei.a.yao@intel.com>
---
 examples/l3fwd-power/main.c | 109 +++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 108 insertions(+), 1 deletion(-)

diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c
index b65d683..e741434 100644
--- a/examples/l3fwd-power/main.c
+++ b/examples/l3fwd-power/main.c
@@ -164,6 +164,8 @@ static uint32_t enabled_port_mask = 0;
 static int promiscuous_on = 0;
 /* NUMA is enabled by default. */
 static int numa_on = 1;
+static int parse_ptype; /**< Parse packet type using rx callback, and */
+			/**< disabled by default */
 
 enum freq_scale_hint_t
 {
@@ -607,6 +609,48 @@ get_ipv4_dst_port(struct ipv4_hdr *ipv4_hdr, uint8_t portid,
 #endif
 
 static inline void
+parse_ptype_one(struct rte_mbuf *m)
+{
+	struct ether_hdr *eth_hdr;
+	uint32_t packet_type = RTE_PTYPE_UNKNOWN;
+	uint16_t ether_type;
+
+	eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
+	ether_type = eth_hdr->ether_type;
+	if (ether_type == rte_cpu_to_be_16(ETHER_TYPE_IPv4))
+		packet_type |= RTE_PTYPE_L3_IPV4_EXT_UNKNOWN;
+	else if (ether_type == rte_cpu_to_be_16(ETHER_TYPE_IPv6))
+		packet_type |= RTE_PTYPE_L3_IPV6_EXT_UNKNOWN;
+
+	m->packet_type = packet_type;
+}
+
+static uint16_t
+cb_parse_ptype(uint8_t port __rte_unused, uint16_t queue __rte_unused,
+	       struct rte_mbuf *pkts[], uint16_t nb_pkts,
+	       uint16_t max_pkts __rte_unused,
+	       void *user_param __rte_unused)
+{
+	unsigned int i;
+
+	for (i = 0; i < nb_pkts; ++i)
+		parse_ptype_one(pkts[i]);
+
+	return nb_pkts;
+}
+
+static int
+add_cb_parse_ptype(uint8_t portid, uint16_t queueid)
+{
+	printf("Port %d: softly parse packet type info\n", portid);
+	if (rte_eth_add_rx_callback(portid, queueid, cb_parse_ptype, NULL))
+		return 0;
+
+	printf("Failed to add rx callback: port=%d\n", portid);
+	return -1;
+}
+
+static inline void
 l3fwd_simple_forward(struct rte_mbuf *m, uint8_t portid,
 				struct lcore_conf *qconf)
 {
@@ -1108,7 +1152,8 @@ print_usage(const char *prgname)
 		"  --config (port,queue,lcore): rx queues configuration\n"
 		"  --no-numa: optional, disable numa awareness\n"
 		"  --enable-jumbo: enable jumbo frame"
-		" which max packet len is PKTLEN in decimal (64-9600)\n",
+		" which max packet len is PKTLEN in decimal (64-9600)\n"
+		"  --parse-ptype: parse packet type by software\n",
 		prgname);
 }
 
@@ -1202,6 +1247,8 @@ parse_config(const char *q_arg)
 	return 0;
 }
 
+#define CMD_LINE_OPT_PARSE_PTYPE "parse-ptype"
+
 /* Parse the argument given in the command line of the application */
 static int
 parse_args(int argc, char **argv)
@@ -1214,6 +1261,7 @@ parse_args(int argc, char **argv)
 		{"config", 1, 0, 0},
 		{"no-numa", 0, 0, 0},
 		{"enable-jumbo", 0, 0, 0},
+		{CMD_LINE_OPT_PARSE_PTYPE, 0, 0, 0},
 		{NULL, 0, 0, 0}
 	};
 
@@ -1284,6 +1332,13 @@ parse_args(int argc, char **argv)
 				(unsigned int)port_conf.rxmode.max_rx_pkt_len);
 			}
 
+			if (!strncmp(lgopts[option_index].name,
+				     CMD_LINE_OPT_PARSE_PTYPE,
+				     sizeof(CMD_LINE_OPT_PARSE_PTYPE))) {
+				printf("soft parse-ptype is enabled\n");
+				parse_ptype = 1;
+			}
+
 			break;
 
 		default:
@@ -1531,6 +1586,50 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 	}
 }
 
+static int check_ptype(uint8_t portid)
+{
+	int i, ret;
+	int ptype_l3_ipv4 = 0;
+#if (APP_LOOKUP_METHOD == APP_LOOKUP_EXACT_MATCH)
+	int ptype_l3_ipv6 = 0;
+#endif
+	uint32_t ptype_mask = RTE_PTYPE_L3_MASK;
+
+	ret = rte_eth_dev_get_supported_ptypes(portid, ptype_mask, NULL, 0);
+	if (ret <= 0)
+		return 0;
+
+	uint32_t ptypes[ret];
+
+	ret = rte_eth_dev_get_supported_ptypes(portid, ptype_mask, ptypes, ret);
+	for (i = 0; i < ret; ++i) {
+		if (ptypes[i] & RTE_PTYPE_L3_IPV4)
+			ptype_l3_ipv4 = 1;
+#if (APP_LOOKUP_METHOD == APP_LOOKUP_EXACT_MATCH)
+		if (ptypes[i] & RTE_PTYPE_L3_IPV6)
+			ptype_l3_ipv6 = 1;
+#endif
+	}
+
+	if (ptype_l3_ipv4 == 0)
+		printf("port %d cannot parse RTE_PTYPE_L3_IPV4\n", portid);
+
+#if (APP_LOOKUP_METHOD == APP_LOOKUP_EXACT_MATCH)
+	if (ptype_l3_ipv6 == 0)
+		printf("port %d cannot parse RTE_PTYPE_L3_IPV6\n", portid);
+#endif
+
+#if (APP_LOOKUP_METHOD == APP_LOOKUP_LPM)
+	if (ptype_l3_ipv4)
+#else /* APP_LOOKUP_EXACT_MATCH */
+	if (ptype_l3_ipv4 && ptype_l3_ipv6)
+#endif
+		return 1;
+
+	return 0;
+
+}
+
 int
 main(int argc, char **argv)
 {
@@ -1716,6 +1815,14 @@ main(int argc, char **argv)
 				rte_exit(EXIT_FAILURE,
 					"rte_eth_rx_queue_setup: err=%d, "
 						"port=%d\n", ret, portid);
+
+			if (parse_ptype) {
+				if (add_cb_parse_ptype(portid, queueid) < 0)
+					rte_exit(EXIT_FAILURE,
+						 "Fail to add ptype cb\n");
+			} else if (!check_ptype(portid))
+				rte_exit(EXIT_FAILURE,
+					 "PMD can not provide needed ptypes\n");
 		}
 	}
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v4 10/10] examples/l3fwd-power: fix not stop and close device
  2017-01-17  7:10 ` [PATCH v4 " Jianfeng Tan
                     ` (8 preceding siblings ...)
  2017-01-17  7:10   ` [PATCH v4 09/10] examples/l3fwd-power: add parse-ptype option Jianfeng Tan
@ 2017-01-17  7:10   ` Jianfeng Tan
  2017-01-17  8:28   ` [PATCH v4 00/10] rxq interrupt mode for virtio PMD Yuanhan Liu
  10 siblings, 0 replies; 63+ messages in thread
From: Jianfeng Tan @ 2017-01-17  7:10 UTC (permalink / raw)
  To: dev; +Cc: yuanhan.liu, stephen, lei.a.yao, Jianfeng Tan

As it gets killed, in SIGINT signal handler, device is not stopped
and closed. In virtio's case, vector assignment in the KVM is not
deassigned.

This patch will invoke dev_stop() and dev_close() in signal handler.

Fixes: d7937e2e3d12 ("power: initial import")

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Tested-by: Lei Yao <lei.a.yao@intel.com>
---
 examples/l3fwd-power/main.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c
index e741434..15b47c7 100644
--- a/examples/l3fwd-power/main.c
+++ b/examples/l3fwd-power/main.c
@@ -379,6 +379,7 @@ static void
 signal_exit_now(int sigtype)
 {
 	unsigned lcore_id;
+	unsigned int portid, nb_ports;
 	int ret;
 
 	if (sigtype == SIGINT) {
@@ -393,6 +394,15 @@ signal_exit_now(int sigtype)
 					"library de-initialization failed on "
 							"core%u\n", lcore_id);
 		}
+
+		nb_ports = rte_eth_dev_count();
+		for (portid = 0; portid < nb_ports; portid++) {
+			if ((enabled_port_mask & (1 << portid)) == 0)
+				continue;
+
+			rte_eth_dev_stop(portid);
+			rte_eth_dev_close(portid);
+		}
 	}
 
 	rte_exit(EXIT_SUCCESS, "User forced exit\n");
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v5 06/10] net/virtio: setup rxq interrupts
  2016-12-04  0:18 [PATCH 0/5] Interrupt mode for virtio PMD Jianfeng Tan
                   ` (7 preceding siblings ...)
  2017-01-17  7:10 ` [PATCH v4 " Jianfeng Tan
@ 2017-01-17  8:00 ` Jianfeng Tan
  8 siblings, 0 replies; 63+ messages in thread
From: Jianfeng Tan @ 2017-01-17  8:00 UTC (permalink / raw)
  To: dev; +Cc: yuanhan.liu, stephen, lei.a.yao, Jianfeng Tan

This patch mainly allocates structure to store queue/irq mapping,
and configure queue/irq mapping down through PCI ops. It also creates
eventfds for each Rx queue and tell the kernel about the eventfd/intr
binding.

Note: So far, we hard-code 1:1 queue/irq mapping (each rx queue has
one exclusive interrupt), like this:
  vec 0 -> config irq
  vec 1 -> rxq0
  vec 2 -> rxq1
  ...

which means, the "vectors" option of QEMU should be configured with
a value >= N+1 (N is the number of the queue pairs).

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Tested-by: Lei Yao <lei.a.yao@intel.com>
---
 v5:
   - add rel note.
 doc/guides/nics/features/virtio.ini     |  1 +
 doc/guides/nics/features/virtio_vec.ini |  1 +
 doc/guides/nics/virtio.rst              | 60 +++++++++++++++++++++++
 doc/guides/rel_notes/release_17_02.rst  | 12 +++++
 drivers/net/virtio/virtio_ethdev.c      | 84 +++++++++++++++++++++++++++++++++
 5 files changed, 158 insertions(+)

diff --git a/doc/guides/nics/features/virtio.ini b/doc/guides/nics/features/virtio.ini
index f5de291..7f038c5 100644
--- a/doc/guides/nics/features/virtio.ini
+++ b/doc/guides/nics/features/virtio.ini
@@ -5,6 +5,7 @@
 ;
 [Features]
 Link status          = Y
+Rx interrupt         = Y
 Queue start/stop     = Y
 Scattered Rx         = Y
 Promiscuous mode     = Y
diff --git a/doc/guides/nics/features/virtio_vec.ini b/doc/guides/nics/features/virtio_vec.ini
index 6dc7cf0..ec93f5c 100644
--- a/doc/guides/nics/features/virtio_vec.ini
+++ b/doc/guides/nics/features/virtio_vec.ini
@@ -5,6 +5,7 @@
 ;
 [Features]
 Link status          = Y
+Rx interrupt         = Y
 Queue start/stop     = Y
 Promiscuous mode     = Y
 Allmulticast mode    = Y
diff --git a/doc/guides/nics/virtio.rst b/doc/guides/nics/virtio.rst
index c90e517..dcf4d35 100644
--- a/doc/guides/nics/virtio.rst
+++ b/doc/guides/nics/virtio.rst
@@ -87,6 +87,8 @@ In this release, the virtio PMD driver provides the basic functionality of packe
 
 *   Virtio supports Link State interrupt.
 
+*   Virtio supports Rx interrupt (so far, only support 1:1 mapping for queue/interrupt).
+
 *   Virtio supports software vlan stripping and inserting.
 
 *   Virtio supports using port IO to get PCI resource when uio/igb_uio module is not available.
@@ -274,3 +276,61 @@ Example of using the vector version of the virtio poll mode driver in
 ``testpmd``::
 
    testpmd -c 0x7 -n 4 -- -i --txqflags=0xF01 --rxq=1 --txq=1 --nb-cores=1
+
+
+Interrupt mode
+--------------
+
+.. _virtio_interrupt_mode:
+
+There are three kinds of interrupts from a virtio device over PCI bus: config
+interrupt, Rx interrupts, and Tx interrupts. Config interrupt is used for
+notification of device configuration changes, especially link status (lsc).
+Interrupt mode is translated into Rx interrupts in the context of DPDK.
+
+Prerequisites for Rx interrupts
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To support Rx interrupts,
+#. Check if guest kernel supports VFIO-NOIOMMU:
+
+    Linux started to support VFIO-NOIOMMU since 4.8.0. Make sure the guest
+    kernel is compiled with:
+
+    .. code-block:: console
+
+        CONFIG_VFIO_NOIOMMU=y
+
+#. Properly set msix vectors when starting VM:
+
+    Enable multi-queue when starting VM, and specify msix vectors in qemu
+    cmdline. (N+1) is the minimum, and (2N+2) is mostly recommended.
+
+    .. code-block:: console
+
+        $(QEMU) ... -device virtio-net-pci,mq=on,vectors=2N+2 ...
+
+#. In VM, insert vfio module in NOIOMMU mode:
+
+    .. code-block:: console
+
+        modprobe vfio enable_unsafe_noiommu_mode=1
+        modprobe vfio-pci
+
+#. In VM, bind the virtio device with vfio-pci:
+
+    .. code-block:: console
+
+        python tools/dpdk-devbind.py -b vfio-pci 00:03.0
+
+Example
+~~~~~~~
+
+Here we use l3fwd-power as an example to show how to get started.
+
+    Example:
+
+    .. code-block:: console
+
+        $ l3fwd-power -c 0x3 -- -p 1 -P --config="(0,0,1)" \
+                                               --no-numa --parse-ptype
diff --git a/doc/guides/rel_notes/release_17_02.rst b/doc/guides/rel_notes/release_17_02.rst
index 13affa2..af1198f 100644
--- a/doc/guides/rel_notes/release_17_02.rst
+++ b/doc/guides/rel_notes/release_17_02.rst
@@ -52,6 +52,18 @@ New Features
   See the :ref:`Generic flow API <Generic_flow_API>` documentation for more
   information.
 
+* **Rxq interrupt mode for virtio.**
+
+  This feature enables rxq interrupt mode for virtio pci net devices as
+  binded to VFIO (noiommu mode) and drived by virtio PMD.
+
+  With this feature, virtio PMD can switch between polling mode and
+  interrupt mode, to achieve best performance, and at the same time save
+  power. It can work on both legacy and modern virtio devices. At this mode,
+  each rxq is mapped with an exluded MSIx interrupt.
+
+  See the :ref:`Virtio Interrupt Mode <virtio_interrupt_mode>` documentation
+  for more information.
 
 Resolved Issues
 ---------------
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 4224d17..e870125 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1210,6 +1210,82 @@ rx_func_get(struct rte_eth_dev *eth_dev)
 		eth_dev->rx_pkt_burst = &virtio_recv_pkts;
 }
 
+/* Only support 1:1 queue/interrupt mapping so far.
+ * TODO: support n:1 queue/interrupt mapping when there are limited number of
+ * interrupt vectors (<N+1).
+ */
+static int
+virtio_queues_bind_intr(struct rte_eth_dev *dev)
+{
+	uint32_t i;
+	struct virtio_hw *hw = dev->data->dev_private;
+
+	PMD_INIT_LOG(INFO, "queue/interrupt binding\n");
+	for (i = 0; i < dev->data->nb_rx_queues; ++i) {
+		dev->intr_handle->intr_vec[i] = i + 1;
+		if (VTPCI_OPS(hw)->set_queue_irq(hw, hw->vqs[i * 2], i + 1) ==
+						 VIRTIO_MSI_NO_VECTOR) {
+			PMD_DRV_LOG(ERR, "failed to set queue vector");
+			return -EBUSY;
+		}
+	}
+
+	return 0;
+}
+
+static int
+virtio_configure_intr(struct rte_eth_dev *dev)
+{
+	struct virtio_hw *hw = dev->data->dev_private;
+
+	if (!rte_intr_cap_multiple(dev->intr_handle)) {
+		PMD_INIT_LOG(ERR, "Multiple intr vector not supported");
+		return -ENOTSUP;
+	}
+
+	if (rte_intr_efd_enable(dev->intr_handle, dev->data->nb_rx_queues)) {
+		PMD_INIT_LOG(ERR, "Fail to create eventfd");
+		return -1;
+	}
+
+	if (!dev->intr_handle->intr_vec) {
+		dev->intr_handle->intr_vec =
+			rte_zmalloc("intr_vec",
+				    hw->max_queue_pairs * sizeof(int), 0);
+		if (!dev->intr_handle->intr_vec) {
+			PMD_INIT_LOG(ERR, "Failed to allocate %u rxq vectors",
+				     hw->max_queue_pairs);
+			return -ENOMEM;
+		}
+	}
+
+	/* Re-register callback to update max_intr */
+	rte_intr_callback_unregister(dev->intr_handle,
+				     virtio_interrupt_handler,
+				     dev);
+	rte_intr_callback_register(dev->intr_handle,
+				   virtio_interrupt_handler,
+				   dev);
+
+	/* DO NOT try to remove this! This function will enable msix, or QEMU
+	 * will encounter SIGSEGV when DRIVER_OK is sent.
+	 * And for legacy devices, this should be done before queue/vec binding
+	 * to change the config size from 20 to 24, or VIRTIO_MSI_QUEUE_VECTOR
+	 * (22) will be ignored.
+	 */
+	if (rte_intr_enable(dev->intr_handle) < 0) {
+		PMD_DRV_LOG(ERR, "interrupt enable failed");
+		return -1;
+	}
+
+	if (virtio_queues_bind_intr(dev) < 0) {
+		PMD_INIT_LOG(ERR, "Failed to bind queue/interrupt");
+		return -1;
+	}
+
+	return 0;
+}
+
 /* reset device and renegotiate features if needed */
 static int
 virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
@@ -1306,6 +1382,14 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
 	ret = virtio_alloc_queues(eth_dev);
 	if (ret < 0)
 		return ret;
+
+	if (eth_dev->data->dev_conf.intr_conf.rxq) {
+		if (virtio_configure_intr(eth_dev) < 0) {
+			PMD_INIT_LOG(ERR, "failed to configure interrupt");
+			return -1;
+		}
+	}
+
 	vtpci_reinit_complete(hw);
 
 	if (pci_dev)
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* Re: [PATCH v4 00/10] rxq interrupt mode for virtio PMD
  2017-01-17  7:10 ` [PATCH v4 " Jianfeng Tan
                     ` (9 preceding siblings ...)
  2017-01-17  7:10   ` [PATCH v4 10/10] examples/l3fwd-power: fix not stop and close device Jianfeng Tan
@ 2017-01-17  8:28   ` Yuanhan Liu
  10 siblings, 0 replies; 63+ messages in thread
From: Yuanhan Liu @ 2017-01-17  8:28 UTC (permalink / raw)
  To: Jianfeng Tan; +Cc: dev, stephen, lei.a.yao

On Tue, Jan 17, 2017 at 07:10:20AM +0000, Jianfeng Tan wrote:
> v4:
>   - Update documents:
>     * doc/guides/nics/features/virtio.ini
>     * doc/guides/nics/features/virtio_vec.ini
>     * doc/guides/nics/virtio.rst
>   - Remove unneeded parenthesis in return statement.
>   - Change c++ comment style.

Series applied to dpdk-next-virtio.

Thanks.

	--yliu

^ permalink raw reply	[flat|nested] 63+ messages in thread

end of thread, other threads:[~2017-01-17  8:26 UTC | newest]

Thread overview: 63+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-12-04  0:18 [PATCH 0/5] Interrupt mode for virtio PMD Jianfeng Tan
2016-12-04  0:18 ` [PATCH 1/5] net/virtio: add Rx descriptor check Jianfeng Tan
2016-12-04  0:18 ` [PATCH 2/5] net/virtio: setup Rx fastpath interrupts Jianfeng Tan
2016-12-04  0:18 ` [PATCH 3/5] net/virtio: remove Rx queue interrupts when stopping Jianfeng Tan
2016-12-04  0:18 ` [PATCH 4/5] net/virtio: add Rx queue intr enable/disable functions Jianfeng Tan
2016-12-04  0:18 ` [PATCH 5/5] examples/l3fwd: add parse-ptype option Jianfeng Tan
2016-12-08  6:59   ` Yuanhan Liu
2016-12-08  7:40     ` Tan, Jianfeng
2016-12-29  7:30 ` [PATCH v2 0/9] rxq interrupt mode for virtio PMD Jianfeng Tan
2016-12-29  7:30   ` [PATCH v2 1/9] net/virtio: fix rewriting LSC flag Jianfeng Tan
2016-12-29  7:30   ` [PATCH v2 2/9] net/virtio: add Rx descriptor check Jianfeng Tan
2016-12-29  7:30   ` [PATCH v2 3/9] net/virtio: add PCI ops for queue/irq binding Jianfeng Tan
2016-12-30  5:46     ` Yuanhan Liu
2016-12-29  7:30   ` [PATCH v2 4/9] net/virtio: add Rx queue intr enable/disable functions Jianfeng Tan
2016-12-30  5:59     ` Yuanhan Liu
2016-12-29  7:30   ` [PATCH v2 5/9] net/virtio: setup rxq interrupts Jianfeng Tan
2016-12-30  6:27     ` Yuanhan Liu
2017-01-04  6:56       ` Tan, Jianfeng
2017-01-04  7:22         ` Yuanhan Liu
2017-01-04  7:30           ` Tan, Jianfeng
2016-12-29  7:30   ` [PATCH v2 6/9] net/virtio: unbind intr/eventfd when stop device Jianfeng Tan
2016-12-29  7:30   ` [PATCH v2 7/9] net/virtio: unmapping queue/irq when close device Jianfeng Tan
2016-12-30  6:30     ` Yuanhan Liu
2016-12-29  7:30   ` [PATCH v2 8/9] examples/l3fwd: add parse-ptype option Jianfeng Tan
2016-12-30  6:39     ` Yuanhan Liu
2016-12-30  7:30       ` Tan, Jianfeng
2017-01-03  6:59         ` Yuanhan Liu
2016-12-29  7:30   ` [PATCH v2 9/9] examples/l3fwd-power: fix not stop and close device Jianfeng Tan
2016-12-30  6:44     ` Yuanhan Liu
2016-12-30  6:56       ` Tan, Jianfeng
2016-12-29  7:42   ` [PATCH v2 0/9] rxq interrupt mode for virtio PMD Tan, Jianfeng
2016-12-30  5:41     ` Yuanhan Liu
2016-12-30  6:57   ` Yuanhan Liu
2017-01-16 14:46 ` [PATCH v3 00/10] " Jianfeng Tan
2017-01-16 14:46   ` [PATCH v3 01/10] net/virtio: fix rewriting LSC flag Jianfeng Tan
2017-01-16 14:46   ` [PATCH v3 02/10] net/virtio: clean up wrapper of set_config_irq Jianfeng Tan
2017-01-16 14:46   ` [PATCH v3 03/10] net/virtio: add Rx descriptor check Jianfeng Tan
2017-01-16 19:16     ` Stephen Hemminger
2017-01-17  4:09       ` Yuanhan Liu
2017-01-16 14:46   ` [PATCH v3 04/10] net/virtio: add PCI ops for queue/irq binding Jianfeng Tan
2017-01-16 14:46   ` [PATCH v3 05/10] net/virtio: add Rx queue intr enable/disable functions Jianfeng Tan
2017-01-17  2:30     ` Jason Wang
2017-01-16 14:46   ` [PATCH v3 06/10] net/virtio: setup rxq interrupts Jianfeng Tan
2017-01-16 14:46   ` [PATCH v3 07/10] net/virtio: unbind intr/eventfd when stop device Jianfeng Tan
2017-01-16 14:47   ` [PATCH v3 08/10] net/virtio: unmapping queue/irq when close device Jianfeng Tan
2017-01-16 14:47   ` [PATCH v3 09/10] examples/l3fwd-power: add parse-ptype option Jianfeng Tan
2017-01-17  5:16     ` Yuanhan Liu
2017-01-17  5:23       ` Tan, Jianfeng
2017-01-16 14:47   ` [PATCH v3 10/10] examples/l3fwd-power: fix not stop and close device Jianfeng Tan
2017-01-17  2:14   ` [PATCH v3 00/10] rxq interrupt mode for virtio PMD Yao, Lei A
2017-01-17  7:10 ` [PATCH v4 " Jianfeng Tan
2017-01-17  7:10   ` [PATCH v4 01/10] net/virtio: fix rewriting LSC flag Jianfeng Tan
2017-01-17  7:10   ` [PATCH v4 02/10] net/virtio: clean up wrapper of set_config_irq Jianfeng Tan
2017-01-17  7:10   ` [PATCH v4 03/10] net/virtio: add Rx descriptor check Jianfeng Tan
2017-01-17  7:10   ` [PATCH v4 04/10] net/virtio: add PCI ops for queue/irq binding Jianfeng Tan
2017-01-17  7:10   ` [PATCH v4 05/10] net/virtio: add Rx queue intr enable/disable functions Jianfeng Tan
2017-01-17  7:10   ` [PATCH v4 06/10] net/virtio: setup rxq interrupts Jianfeng Tan
2017-01-17  7:10   ` [PATCH v4 07/10] net/virtio: unbind intr/eventfd when stop device Jianfeng Tan
2017-01-17  7:10   ` [PATCH v4 08/10] net/virtio: unmapping queue/irq when close device Jianfeng Tan
2017-01-17  7:10   ` [PATCH v4 09/10] examples/l3fwd-power: add parse-ptype option Jianfeng Tan
2017-01-17  7:10   ` [PATCH v4 10/10] examples/l3fwd-power: fix not stop and close device Jianfeng Tan
2017-01-17  8:28   ` [PATCH v4 00/10] rxq interrupt mode for virtio PMD Yuanhan Liu
2017-01-17  8:00 ` [PATCH v5 06/10] net/virtio: setup rxq interrupts Jianfeng Tan

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.