[dpdk-dev,4/5] net/virtio-user: add lsc support with vhost-user adapter

Message ID 1488563803-87754-5-git-send-email-jianfeng.tan@intel.com (mailing list archive)
State Superseded, archived
Delegated to: Yuanhan Liu
Headers

Checks

Context Check Description
ci/checkpatch warning coding style issues
ci/Intel-compilation success Compilation OK

Commit Message

Jianfeng Tan March 3, 2017, 5:56 p.m. UTC
  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 and cannot be re-connected. We will force the
link state to be down.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/virtio/virtio_ethdev.c               |  2 +-
 drivers/net/virtio/virtio_ethdev.h               |  2 ++
 drivers/net/virtio/virtio_user/virtio_user_dev.c |  2 ++
 drivers/net/virtio/virtio_user_ethdev.c          | 35 +++++++++++++++++++++++-
 4 files changed, 39 insertions(+), 2 deletions(-)
  

Comments

Yuanhan Liu March 17, 2017, 8:29 a.m. UTC | #1
On Fri, Mar 03, 2017 at 05:56:42PM +0000, Jianfeng Tan wrote:
> 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 and cannot be re-connected. We will force the
> link state to be down.
> 
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
>  static void
>  virtio_user_read_dev_config(struct virtio_hw *hw, size_t offset,
>  		     void *dst, int length)
> @@ -63,8 +77,27 @@ 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 flags;
> +			int r;
> +
> +			flags = fcntl(dev->vhostfd, F_GETFL);
> +			fcntl(dev->vhostfd, F_SETFL, flags | O_NONBLOCK);
> +			r = recv(dev->vhostfd, buf, 128, 0);

I think you need specify flag MSG_PEEK, to not consume the data if
there any?

	--yliu
> +			if (r == 0 || (r < 0 && errno != EAGAIN)) {
> +				dev->status &= (~VIRTIO_NET_S_LINK_UP);
> +				/* link can never be up again */
> +				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;
> -- 
> 2.7.4
  
Jianfeng Tan March 27, 2017, 1:51 a.m. UTC | #2
> -----Original Message-----
> From: Yuanhan Liu [mailto:yuanhan.liu@linux.intel.com]
> Sent: Friday, March 17, 2017 4:29 PM
> To: Tan, Jianfeng
> Cc: dev@dpdk.org; david.marchand@6wind.com
> Subject: Re: [PATCH 4/5] net/virtio-user: add lsc support with vhost-user
> adapter
> 
> On Fri, Mar 03, 2017 at 05:56:42PM +0000, Jianfeng Tan wrote:
> > 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 and cannot be re-connected. We will force the
> > link state to be down.
> >
> > Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> >  static void
> >  virtio_user_read_dev_config(struct virtio_hw *hw, size_t offset,
> >  		     void *dst, int length)
> > @@ -63,8 +77,27 @@ 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 flags;
> > +			int r;
> > +
> > +			flags = fcntl(dev->vhostfd, F_GETFL);
> > +			fcntl(dev->vhostfd, F_SETFL, flags | O_NONBLOCK);
> > +			r = recv(dev->vhostfd, buf, 128, 0);
> 
> I think you need specify flag MSG_PEEK, to not consume the data if
> there any?

Thanks for catching this issue, I'll fix it in next version.

Thanks,
Jianfeng
  

Patch

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 5d80d1a..58b20eb 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1190,7 +1190,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 777a14b..3f13763 100644
--- a/drivers/net/virtio/virtio_ethdev.h
+++ b/drivers/net/virtio/virtio_ethdev.h
@@ -112,4 +112,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/virtio_user_dev.c b/drivers/net/virtio/virtio_user/virtio_user_dev.c
index cc6f557..2d79818 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
@@ -158,6 +158,8 @@  virtio_user_fill_intr_handle(struct virtio_user_dev *dev, uint8_t portid)
 	eth_dev->intr_handle->nb_efd = dev->max_queue_pairs;
 	eth_dev->intr_handle->max_intr = dev->max_queue_pairs + 1;
 	eth_dev->intr_handle->type = RTE_INTR_HANDLE_VDEV;
+	if (dev->vhostfd >= 0)
+		eth_dev->intr_handle->fd = dev->vhostfd;
 }
 
 int
diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c
index fbdd0a8..14f4a5c 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,27 @@  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 flags;
+			int r;
+
+			flags = fcntl(dev->vhostfd, F_GETFL);
+			fcntl(dev->vhostfd, F_SETFL, flags | O_NONBLOCK);
+			r = recv(dev->vhostfd, buf, 128, 0);
+			if (r == 0 || (r < 0 && errno != EAGAIN)) {
+				dev->status &= (~VIRTIO_NET_S_LINK_UP);
+				/* link can never be up again */
+				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;