[dpdk-dev] [PATCH] net/vdev_netvsc: handle removal of associated pci device

Stephen Hemminger stephen at networkplumber.org
Wed Aug 19 19:53:33 CEST 2020


The vdev_netvsc was not detecting when the associated PCI device
(SRIOV) was removed. Because of that it would keep feeding the
same (removed) device to failsafe PMD which would then unsuccessfully
try and probe for it.

Change to use a mark/sweep method to detect that PCI device was
removed, and also only tell failsafe about new PCI devices.
Vdev_netvsc does not have to keep stuffing the pipe with the
same already existing PCI device.

Fixes: e7dc5d7becc5 ("net/vdev_netvsc: implement core functionality")
Cc: matan at mellanox.com, stable at dpdk.org
Signed-off-by: Stephen Hemminger <stephen at networkplumber.org>
---
 drivers/net/vdev_netvsc/vdev_netvsc.c | 39 +++++++++++++++++++++++----
 1 file changed, 34 insertions(+), 5 deletions(-)

diff --git a/drivers/net/vdev_netvsc/vdev_netvsc.c b/drivers/net/vdev_netvsc/vdev_netvsc.c
index 1ecb0b3e6a34..80a3158012ce 100644
--- a/drivers/net/vdev_netvsc/vdev_netvsc.c
+++ b/drivers/net/vdev_netvsc/vdev_netvsc.c
@@ -66,6 +66,7 @@ struct vdev_netvsc_ctx {
 	char devargs[256];		   /**< Fail-safe device arguments. */
 	char if_name[IF_NAMESIZE];	   /**< NetVSC netdevice name. */
 	unsigned int if_index;		   /**< NetVSC netdevice index. */
+	int pci_found;			   /**< Device detection */
 	struct rte_ether_addr if_addr;	   /**< NetVSC MAC address. */
 	int pipe[2];			   /**< Fail-safe communication pipe. */
 	char yield[256];		   /**< PCI sub-device arguments. */
@@ -405,11 +406,18 @@ vdev_netvsc_device_probe(const struct if_nameindex *iface,
 	len = strlen(addr);
 	if (!len)
 		return 0;
+
+	ctx->pci_found = 1;
+
+	/* Skip if this is same device already sent to failsafe */
+	if (strcmp(addr, ctx->yield) == 0)
+		return 0;
+
+	DRV_LOG(DEBUG, "associating PCI device \"%s\" with NetVSC"
+		" interface \"%s\" (index %u)", addr, ctx->if_name,
+		ctx->if_index);
+
 	/* Send PCI device argument to fail-safe PMD instance. */
-	if (strcmp(addr, ctx->yield))
-		DRV_LOG(DEBUG, "associating PCI device \"%s\" with NetVSC"
-			" interface \"%s\" (index %u)", addr, ctx->if_name,
-			ctx->if_index);
 	memmove(buf, addr, len + 1);
 	addr = buf;
 	buf[len] = '\n';
@@ -452,12 +460,33 @@ vdev_netvsc_alarm(__rte_unused void *arg)
 	struct vdev_netvsc_ctx *ctx;
 	int ret;
 
+	/* 1st pass: clear PCI flag on all devices */
+	LIST_FOREACH(ctx, &vdev_netvsc_ctx_list, entry) {
+		ctx->pci_found = 0;
+	}
+
+	/* 2nd pass: scan all system devices to look for changes to this device */
 	LIST_FOREACH(ctx, &vdev_netvsc_ctx_list, entry) {
 		ret = vdev_netvsc_foreach_iface(vdev_netvsc_device_probe, 0,
 		      ctx);
-		if (ret < 0)
+
+		if (ret < 0) {
+			DRV_LOG(NOTICE, "can not scan devices for %s\n",
+				ctx->if_name);
 			break;
+		}
 	}
+
+	/* 3rd pass: detect PCI removal */
+	LIST_FOREACH(ctx, &vdev_netvsc_ctx_list, entry) {
+		if (!ctx->pci_found && ctx->yield[0]) {
+			DRV_LOG(DEBUG, "disassociating PCI device \"%s\" from NetVSC"
+				" interface \"%s\" (index %u)", ctx->yield, ctx->if_name,
+				ctx->if_index);
+			ctx->yield[0] = '\0';
+		}
+	}
+
 	if (!vdev_netvsc_ctx_count)
 		return;
 	ret = rte_eal_alarm_set(VDEV_NETVSC_PROBE_MS * 1000,
-- 
2.27.0



More information about the dev mailing list