All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 1/2] net/vhost: create datagram sockets immediately
@ 2017-01-03 16:22 Charles (Chas) Williams
  2017-01-03 16:22 ` [PATCH v4 2/2] net/vhost: emulate device start/stop behavior Charles (Chas) Williams
  2017-01-04  8:06 ` [PATCH v4 1/2] net/vhost: create datagram sockets immediately Yuanhan Liu
  0 siblings, 2 replies; 3+ messages in thread
From: Charles (Chas) Williams @ 2017-01-03 16:22 UTC (permalink / raw)
  To: dev; +Cc: mtetsuyah, yuanhan.liu, Charles (Chas) Williams

If you create a vhost server device, it doesn't create the actual datagram
socket until you call .dev_start().  If you call .dev_stop() is also
deletes those sockets.  For QEMU clients, this is a problem since QEMU
doesn't know how to re-attach to datagram sockets that have gone away.

To fix this, register and unregister the datagram sockets during device
creation and removal.

Fixes: ee584e9710b9 ("vhost: add driver on top of the library")

Signed-off-by: Chas Williams <ciwillia@brocade.com>
---
 drivers/net/vhost/rte_eth_vhost.c | 45 +++++++++++++++------------------------
 1 file changed, 17 insertions(+), 28 deletions(-)

diff --git a/drivers/net/vhost/rte_eth_vhost.c b/drivers/net/vhost/rte_eth_vhost.c
index 60b0f51..c669e79 100644
--- a/drivers/net/vhost/rte_eth_vhost.c
+++ b/drivers/net/vhost/rte_eth_vhost.c
@@ -113,9 +113,6 @@ struct pmd_internal {
 	char *dev_name;
 	char *iface_name;
 	uint16_t max_queues;
-	uint64_t flags;
-
-	volatile uint16_t once;
 };
 
 struct internal_list {
@@ -772,35 +769,14 @@ vhost_driver_session_stop(void)
 }
 
 static int
-eth_dev_start(struct rte_eth_dev *dev)
+eth_dev_start(struct rte_eth_dev *dev __rte_unused)
 {
-	struct pmd_internal *internal = dev->data->dev_private;
-	int ret = 0;
-
-	if (rte_atomic16_cmpset(&internal->once, 0, 1)) {
-		ret = rte_vhost_driver_register(internal->iface_name,
-						internal->flags);
-		if (ret)
-			return ret;
-	}
-
-	/* We need only one message handling thread */
-	if (rte_atomic16_add_return(&nb_started_ports, 1) == 1)
-		ret = vhost_driver_session_start();
-
-	return ret;
+	return 0;
 }
 
 static void
-eth_dev_stop(struct rte_eth_dev *dev)
+eth_dev_stop(struct rte_eth_dev *dev __rte_unused)
 {
-	struct pmd_internal *internal = dev->data->dev_private;
-
-	if (rte_atomic16_cmpset(&internal->once, 1, 0))
-		rte_vhost_driver_unregister(internal->iface_name);
-
-	if (rte_atomic16_sub_return(&nb_started_ports, 1) == 0)
-		vhost_driver_session_stop();
 }
 
 static int
@@ -1043,7 +1019,6 @@ eth_dev_vhost_create(const char *name, char *iface_name, int16_t queues,
 	internal->iface_name = strdup(iface_name);
 	if (internal->iface_name == NULL)
 		goto error;
-	internal->flags = flags;
 
 	list->eth_dev = eth_dev;
 	pthread_mutex_lock(&internal_list_lock);
@@ -1078,6 +1053,15 @@ eth_dev_vhost_create(const char *name, char *iface_name, int16_t queues,
 	eth_dev->rx_pkt_burst = eth_vhost_rx;
 	eth_dev->tx_pkt_burst = eth_vhost_tx;
 
+	if (rte_vhost_driver_register(iface_name, flags))
+		goto error;
+
+	/* We need only one message handling thread */
+	if (rte_atomic16_add_return(&nb_started_ports, 1) == 1) {
+		if (vhost_driver_session_start())
+			goto error;
+	}
+
 	return data->port_id;
 
 error:
@@ -1215,6 +1199,11 @@ rte_pmd_vhost_remove(const char *name)
 
 	eth_dev_stop(eth_dev);
 
+	rte_vhost_driver_unregister(internal->iface_name);
+
+	if (rte_atomic16_sub_return(&nb_started_ports, 1) == 0)
+		vhost_driver_session_stop();
+
 	rte_free(vring_states[eth_dev->data->port_id]);
 	vring_states[eth_dev->data->port_id] = NULL;
 
-- 
2.1.4

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

* [PATCH v4 2/2] net/vhost: emulate device start/stop behavior
  2017-01-03 16:22 [PATCH v4 1/2] net/vhost: create datagram sockets immediately Charles (Chas) Williams
@ 2017-01-03 16:22 ` Charles (Chas) Williams
  2017-01-04  8:06 ` [PATCH v4 1/2] net/vhost: create datagram sockets immediately Yuanhan Liu
  1 sibling, 0 replies; 3+ messages in thread
From: Charles (Chas) Williams @ 2017-01-03 16:22 UTC (permalink / raw)
  To: dev; +Cc: mtetsuyah, yuanhan.liu, Charles (Chas) Williams

.dev_start()/.dev_stop() roughly corresponds to the local device's port
being ready.  This is different from the remote client being connected
which is roughly link up or down.  Emulate the device start/stop behavior
by separately tracking the start/stop state to determine if we should
allow packets to be queued to/from the remote client.

Signed-off-by: Chas Williams <ciwillia@brocade.com>
---
 drivers/net/vhost/rte_eth_vhost.c | 82 ++++++++++++++++++++++++---------------
 1 file changed, 51 insertions(+), 31 deletions(-)

diff --git a/drivers/net/vhost/rte_eth_vhost.c b/drivers/net/vhost/rte_eth_vhost.c
index c669e79..0b5b80a 100644
--- a/drivers/net/vhost/rte_eth_vhost.c
+++ b/drivers/net/vhost/rte_eth_vhost.c
@@ -110,9 +110,11 @@ struct vhost_queue {
 };
 
 struct pmd_internal {
+	rte_atomic32_t dev_attached;
 	char *dev_name;
 	char *iface_name;
 	uint16_t max_queues;
+	rte_atomic32_t started;
 };
 
 struct internal_list {
@@ -490,6 +492,38 @@ find_internal_resource(char *ifname)
 	return list;
 }
 
+static void
+update_queuing_status(struct rte_eth_dev *dev)
+{
+	struct pmd_internal *internal = dev->data->dev_private;
+	struct vhost_queue *vq;
+	unsigned int i;
+	int allow_queuing = 1;
+
+	if (rte_atomic32_read(&internal->started) == 0 ||
+	    rte_atomic32_read(&internal->dev_attached) == 0)
+		allow_queuing = 0;
+
+	/* Wait until rx/tx_pkt_burst stops accessing vhost device */
+	for (i = 0; i < dev->data->nb_rx_queues; i++) {
+		vq = dev->data->rx_queues[i];
+		if (vq == NULL)
+			continue;
+		rte_atomic32_set(&vq->allow_queuing, allow_queuing);
+		while (rte_atomic32_read(&vq->while_queuing))
+			rte_pause();
+	}
+
+	for (i = 0; i < dev->data->nb_tx_queues; i++) {
+		vq = dev->data->tx_queues[i];
+		if (vq == NULL)
+			continue;
+		rte_atomic32_set(&vq->allow_queuing, allow_queuing);
+		while (rte_atomic32_read(&vq->while_queuing))
+			rte_pause();
+	}
+}
+
 static int
 new_device(int vid)
 {
@@ -541,18 +575,8 @@ new_device(int vid)
 
 	eth_dev->data->dev_link.link_status = ETH_LINK_UP;
 
-	for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
-		vq = eth_dev->data->rx_queues[i];
-		if (vq == NULL)
-			continue;
-		rte_atomic32_set(&vq->allow_queuing, 1);
-	}
-	for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
-		vq = eth_dev->data->tx_queues[i];
-		if (vq == NULL)
-			continue;
-		rte_atomic32_set(&vq->allow_queuing, 1);
-	}
+	rte_atomic32_set(&internal->dev_attached, 1);
+	update_queuing_status(eth_dev);
 
 	RTE_LOG(INFO, PMD, "New connection established\n");
 
@@ -565,6 +589,7 @@ static void
 destroy_device(int vid)
 {
 	struct rte_eth_dev *eth_dev;
+	struct pmd_internal *internal;
 	struct vhost_queue *vq;
 	struct internal_list *list;
 	char ifname[PATH_MAX];
@@ -578,24 +603,10 @@ destroy_device(int vid)
 		return;
 	}
 	eth_dev = list->eth_dev;
+	internal = eth_dev->data->dev_private;
 
-	/* Wait until rx/tx_pkt_burst stops accessing vhost device */
-	for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
-		vq = eth_dev->data->rx_queues[i];
-		if (vq == NULL)
-			continue;
-		rte_atomic32_set(&vq->allow_queuing, 0);
-		while (rte_atomic32_read(&vq->while_queuing))
-			rte_pause();
-	}
-	for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
-		vq = eth_dev->data->tx_queues[i];
-		if (vq == NULL)
-			continue;
-		rte_atomic32_set(&vq->allow_queuing, 0);
-		while (rte_atomic32_read(&vq->while_queuing))
-			rte_pause();
-	}
+	rte_atomic32_set(&internal->dev_attached, 0);
+	update_queuing_status(eth_dev);
 
 	eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
 
@@ -769,14 +780,23 @@ vhost_driver_session_stop(void)
 }
 
 static int
-eth_dev_start(struct rte_eth_dev *dev __rte_unused)
+eth_dev_start(struct rte_eth_dev *dev)
 {
+	struct pmd_internal *internal = dev->data->dev_private;
+
+	rte_atomic32_set(&internal->started, 1);
+	update_queuing_status(dev);
+
 	return 0;
 }
 
 static void
-eth_dev_stop(struct rte_eth_dev *dev __rte_unused)
+eth_dev_stop(struct rte_eth_dev *dev)
 {
+	struct pmd_internal *internal = dev->data->dev_private;
+
+	rte_atomic32_set(&internal->started, 0);
+	update_queuing_status(dev);
 }
 
 static int
-- 
2.1.4

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

* Re: [PATCH v4 1/2] net/vhost: create datagram sockets immediately
  2017-01-03 16:22 [PATCH v4 1/2] net/vhost: create datagram sockets immediately Charles (Chas) Williams
  2017-01-03 16:22 ` [PATCH v4 2/2] net/vhost: emulate device start/stop behavior Charles (Chas) Williams
@ 2017-01-04  8:06 ` Yuanhan Liu
  1 sibling, 0 replies; 3+ messages in thread
From: Yuanhan Liu @ 2017-01-04  8:06 UTC (permalink / raw)
  To: Charles (Chas) Williams; +Cc: dev, mtetsuyah, stable

On Tue, Jan 03, 2017 at 11:22:42AM -0500, Charles (Chas) Williams wrote:
> If you create a vhost server device, it doesn't create the actual datagram
> socket until you call .dev_start().  If you call .dev_stop() is also
> deletes those sockets.  For QEMU clients, this is a problem since QEMU
> doesn't know how to re-attach to datagram sockets that have gone away.
> 
> To fix this, register and unregister the datagram sockets during device
> creation and removal.
> 
> Fixes: ee584e9710b9 ("vhost: add driver on top of the library")

Both patches applied to dpdk-next-virtio. Thanks!

Note that we prefer a title of "prefix: fix ..." for bug fixing patch.
For this reason, I have changed the title for you while apply:

    net/vhost: fix socket file being deleted on dev stop

Also, stable is cc'ed.

	--yliu

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

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

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-01-03 16:22 [PATCH v4 1/2] net/vhost: create datagram sockets immediately Charles (Chas) Williams
2017-01-03 16:22 ` [PATCH v4 2/2] net/vhost: emulate device start/stop behavior Charles (Chas) Williams
2017-01-04  8:06 ` [PATCH v4 1/2] net/vhost: create datagram sockets immediately Yuanhan Liu

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.