[dpdk-dev] [PATCH v3 5/5] net/virtio-user: add lsc support

Jianfeng Tan jianfeng.tan at intel.com
Fri Mar 31 21:44:58 CEST 2017


So far, virtio-user with vhost-user as the backend can only support
client mode. So when vhost user backend is down, i.e., unix socket
connection is broken, the connection cannot be re-connected. We will
forcely set the link state to be down.

Note: virtio-user with vhost-kernel as the backend still cannot
support lsc now as we fail to find a way to monitor the backend, tap
device, up/down events.

Signed-off-by: Jianfeng Tan <jianfeng.tan at intel.com>
---
 doc/guides/rel_notes/release_17_05.rst  |  7 ++++-
 drivers/net/virtio/virtio_ethdev.c      |  2 +-
 drivers/net/virtio/virtio_ethdev.h      |  2 ++
 drivers/net/virtio/virtio_user_ethdev.c | 51 +++++++++++++++++++++++++++++++--
 4 files changed, 58 insertions(+), 4 deletions(-)

diff --git a/doc/guides/rel_notes/release_17_05.rst b/doc/guides/rel_notes/release_17_05.rst
index 2b5eaab..42ba190 100644
--- a/doc/guides/rel_notes/release_17_05.rst
+++ b/doc/guides/rel_notes/release_17_05.rst
@@ -59,11 +59,12 @@ New Features
 
 * **Added interrupt mode support for virtio-user.**
 
-  Implemented Rxq interrupt mode support for virtio-user as a virtual
+  Implemented Rxq interrupt mode and LSC support for virtio-user as a virtual
   device. Supported cases:
 
   * Rxq interrupt for virtio-user + vhost-user as the backend.
   * Rxq interrupt for virtio-user + vhost-kernel as the backend.
+  * LSC interrupt for virtio-user + vhost-user as the backend.
 
 Resolved Issues
 ---------------
@@ -119,6 +120,10 @@ Known Issues
    Also, make sure to start the actual text at the margin.
    =========================================================
 
+   * **LSC interrupt cannot work for virtio-user + vhost-kernel.**
+
+     LSC interrupt cannot be detected when setting the backend, tap device,
+     up/down as we fail to find a way to monitor such event.
 
 API Changes
 -----------
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index d9986ab..6a9568f 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1205,7 +1205,7 @@ virtio_negotiate_features(struct virtio_hw *hw, uint64_t req_features)
  * Process Virtio Config changed interrupt and call the callback
  * if link state changed.
  */
-static void
+void
 virtio_interrupt_handler(struct rte_intr_handle *handle,
 			 void *param)
 {
diff --git a/drivers/net/virtio/virtio_ethdev.h b/drivers/net/virtio/virtio_ethdev.h
index aa78adc..4009c4d 100644
--- a/drivers/net/virtio/virtio_ethdev.h
+++ b/drivers/net/virtio/virtio_ethdev.h
@@ -113,4 +113,6 @@ uint16_t virtio_xmit_pkts_simple(void *tx_queue, struct rte_mbuf **tx_pkts,
 
 int eth_virtio_dev_init(struct rte_eth_dev *eth_dev);
 
+void virtio_interrupt_handler(struct rte_intr_handle *handle, void *param);
+
 #endif /* _VIRTIO_ETHDEV_H_ */
diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c
index e8b14e5..d8cea20 100644
--- a/drivers/net/virtio/virtio_user_ethdev.c
+++ b/drivers/net/virtio/virtio_user_ethdev.c
@@ -34,10 +34,14 @@
 #include <stdint.h>
 #include <sys/types.h>
 #include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
 
 #include <rte_malloc.h>
 #include <rte_kvargs.h>
 #include <rte_vdev.h>
+#include <rte_alarm.h>
 
 #include "virtio_ethdev.h"
 #include "virtio_logs.h"
@@ -49,6 +53,16 @@
 #define virtio_user_get_dev(hw) \
 	((struct virtio_user_dev *)(hw)->virtio_user_dev)
 
+static void virtio_user_delayed_handler(void *param)
+{
+	struct virtio_hw *hw = (struct virtio_hw *)param;
+	struct rte_eth_dev *dev = &rte_eth_devices[hw->port_id];
+
+	rte_intr_callback_unregister(dev->intr_handle,
+				     virtio_interrupt_handler,
+				     dev);
+}
+
 static void
 virtio_user_read_dev_config(struct virtio_hw *hw, size_t offset,
 		     void *dst, int length)
@@ -63,8 +77,37 @@ virtio_user_read_dev_config(struct virtio_hw *hw, size_t offset,
 		return;
 	}
 
-	if (offset == offsetof(struct virtio_net_config, status))
+	if (offset == offsetof(struct virtio_net_config, status)) {
+		char buf[128];
+
+		if (dev->vhostfd >= 0) {
+			int r;
+			int flags;
+
+			flags = fcntl(dev->vhostfd, F_GETFL);
+			fcntl(dev->vhostfd, F_SETFL, flags | O_NONBLOCK);
+			r = recv(dev->vhostfd, buf, 128, MSG_PEEK);
+			if (r == 0 || (r < 0 && errno != EAGAIN)) {
+				dev->status &= (~VIRTIO_NET_S_LINK_UP);
+				PMD_DRV_LOG(ERR, "virtio-user port %u is down",
+					    hw->port_id);
+				/* Only client mode is available now. Once the
+				 * connection is broken, it can never be up
+				 * again. Besides, this function could be called
+				 * in the process of interrupt handling,
+				 * callback cannot be unregistered here, set an
+				 * alarm to do it.
+				 */
+				rte_eal_alarm_set(1,
+						  virtio_user_delayed_handler,
+						  (void *)hw);
+			} else {
+				dev->status |= VIRTIO_NET_S_LINK_UP;
+			}
+			fcntl(dev->vhostfd, F_SETFL, flags & (~O_NONBLOCK));
+		}
 		*(uint16_t *)dst = dev->status;
+	}
 
 	if (offset == offsetof(struct virtio_net_config, max_virtqueue_pairs))
 		*(uint16_t *)dst = dev->max_queue_pairs;
@@ -319,7 +362,11 @@ virtio_user_eth_dev_alloc(const char *name)
 
 	dev->portid = hw->port_id = data->port_id;
 	virtio_hw_internal[hw->port_id].vtpci_ops = &virtio_user_ops;
-	hw->use_msix = 0;
+	/* After commit 26bbd3e7dc51("net/virtio: disable LSC interrupt if MSIX
+	 * not enabled"), we require this to enable LSC. Just pretend that we
+	 * support msix.
+	 */
+	hw->use_msix = 1;
 	hw->modern   = 0;
 	hw->use_simple_rxtx = 0;
 	hw->virtio_user_dev = dev;
-- 
2.7.4



More information about the dev mailing list