patch 'net/netvsc: fix hot adding multiple VF PCI devices' has been queued to stable release 21.11.2
Kevin Traynor
ktraynor at redhat.com
Wed May 25 18:27:54 CEST 2022
Hi,
FYI, your patch has been queued to stable release 21.11.2
Note it hasn't been pushed to http://dpdk.org/browse/dpdk-stable yet.
It will be pushed if I get no objections before 05/30/22. So please
shout if anyone has objections.
Also note that after the patch there's a diff of the upstream commit vs the
patch applied to the branch. This will indicate if there was any rebasing
needed to apply to the stable branch. If there were code changes for rebasing
(ie: not only metadata diffs), please double check that the rebase was
correctly done.
Queued patches are on a temporary branch at:
https://github.com/kevintraynor/dpdk-stable
This queued commit can be viewed at:
https://github.com/kevintraynor/dpdk-stable/commit/8ab93b06bcf03b86b7d1c021350736568e85e690
Thanks.
Kevin
---
>From 8ab93b06bcf03b86b7d1c021350736568e85e690 Mon Sep 17 00:00:00 2001
From: Long Li <longli at microsoft.com>
Date: Thu, 24 Mar 2022 10:46:17 -0700
Subject: [PATCH] net/netvsc: fix hot adding multiple VF PCI devices
[ upstream commit 7fc4c0997b046e2874a9806431b3d267bb684b41 ]
This patch fixes two issues with hot removing/adding a VF PCI device:
1. The original device argument is lost when it's hot added
2. If there are multiple VFs hot adding at the same time, some of the
VFs may not get added successfully because only one single VF status
is stored in the netvsc.
Fix these by storing the original device arguments and maintain a list
of hot add contexts to deal with multiple VF devices.
Fixes: a2a23a794b ("net/netvsc: support VF device hot add/remove")
Signed-off-by: Long Li <longli at microsoft.com>
---
drivers/net/netvsc/hn_ethdev.c | 78 +++++++++++++++++++++++++++-------
drivers/net/netvsc/hn_var.h | 12 +++++-
drivers/net/netvsc/hn_vf.c | 4 ++
3 files changed, 77 insertions(+), 17 deletions(-)
diff --git a/drivers/net/netvsc/hn_ethdev.c b/drivers/net/netvsc/hn_ethdev.c
index 8a950403ac..0a357d3645 100644
--- a/drivers/net/netvsc/hn_ethdev.c
+++ b/drivers/net/netvsc/hn_ethdev.c
@@ -555,7 +555,8 @@ static void netvsc_hotplug_retry(void *args)
{
int ret;
- struct hn_data *hv = args;
+ struct hv_hotadd_context *hot_ctx = args;
+ struct hn_data *hv = hot_ctx->hv;
struct rte_eth_dev *dev = &rte_eth_devices[hv->port_id];
- struct rte_devargs *d = &hv->devargs;
+ struct rte_devargs *d = &hot_ctx->da;
char buf[256];
@@ -567,8 +568,11 @@ static void netvsc_hotplug_retry(void *args)
PMD_DRV_LOG(DEBUG, "%s: retry count %d",
- __func__, hv->eal_hot_plug_retry);
+ __func__, hot_ctx->eal_hot_plug_retry);
- if (hv->eal_hot_plug_retry++ > NETVSC_MAX_HOTADD_RETRY)
- return;
+ if (hot_ctx->eal_hot_plug_retry++ > NETVSC_MAX_HOTADD_RETRY) {
+ PMD_DRV_LOG(NOTICE, "Failed to parse PCI device retry=%d",
+ hot_ctx->eal_hot_plug_retry);
+ goto free_hotadd_ctx;
+ }
snprintf(buf, sizeof(buf), "/sys/bus/pci/devices/%s/net", d->name);
@@ -603,5 +607,5 @@ static void netvsc_hotplug_retry(void *args)
if (req.ifr_hwaddr.sa_family != ARPHRD_ETHER) {
closedir(di);
- return;
+ goto free_hotadd_ctx;
}
memcpy(eth_addr.addr_bytes, req.ifr_hwaddr.sa_data,
@@ -612,6 +616,11 @@ static void netvsc_hotplug_retry(void *args)
"Found matching MAC address, adding device %s network name %s",
d->name, dir->d_name);
+
+ /* If this device has been hot removed from this
+ * parent device, restore its args.
+ */
ret = rte_eal_hotplug_add(d->bus->name, d->name,
- d->args);
+ hv->vf_devargs ?
+ hv->vf_devargs : "");
if (ret) {
PMD_DRV_LOG(ERR,
@@ -625,10 +634,18 @@ static void netvsc_hotplug_retry(void *args)
*/
closedir(di);
- return;
+ goto free_hotadd_ctx;
}
closedir(di);
retry:
/* The device is still being initialized, retry after 1 second */
- rte_eal_alarm_set(1000000, netvsc_hotplug_retry, hv);
+ rte_eal_alarm_set(1000000, netvsc_hotplug_retry, hot_ctx);
+ return;
+
+free_hotadd_ctx:
+ rte_spinlock_lock(&hv->hotadd_lock);
+ LIST_REMOVE(hot_ctx, list);
+ rte_spinlock_unlock(&hv->hotadd_lock);
+
+ rte_free(hot_ctx);
}
@@ -638,5 +655,6 @@ netvsc_hotadd_callback(const char *device_name, enum rte_dev_event_type type,
{
struct hn_data *hv = arg;
- struct rte_devargs *d = &hv->devargs;
+ struct hv_hotadd_context *hot_ctx;
+ struct rte_devargs *d;
int ret;
@@ -650,9 +668,20 @@ netvsc_hotadd_callback(const char *device_name, enum rte_dev_event_type type,
break;
+ hot_ctx = rte_zmalloc("NETVSC-HOTADD", sizeof(*hot_ctx),
+ rte_mem_page_size());
+
+ if (!hot_ctx) {
+ PMD_DRV_LOG(ERR, "Failed to allocate hotadd context");
+ return;
+ }
+
+ hot_ctx->hv = hv;
+ d = &hot_ctx->da;
+
ret = rte_devargs_parse(d, device_name);
if (ret) {
PMD_DRV_LOG(ERR,
"devargs parsing failed ret=%d", ret);
- return;
+ goto free_ctx;
}
@@ -661,6 +690,9 @@ netvsc_hotadd_callback(const char *device_name, enum rte_dev_event_type type,
* PCI device is a VF device
*/
- hv->eal_hot_plug_retry = 0;
- rte_eal_alarm_set(1000000, netvsc_hotplug_retry, hv);
+ rte_spinlock_lock(&hv->hotadd_lock);
+ LIST_INSERT_HEAD(&hv->hotadd_list, hot_ctx, list);
+ rte_spinlock_unlock(&hv->hotadd_lock);
+ rte_eal_alarm_set(1000000, netvsc_hotplug_retry, hot_ctx);
+ return;
}
@@ -668,6 +700,8 @@ netvsc_hotadd_callback(const char *device_name, enum rte_dev_event_type type,
* sent from VSP
*/
-
+free_ctx:
+ rte_free(hot_ctx);
break;
+
default:
break;
@@ -1004,4 +1038,5 @@ hn_dev_close(struct rte_eth_dev *dev)
int ret;
struct hn_data *hv = dev->data->dev_private;
+ struct hv_hotadd_context *hot_ctx;
PMD_INIT_FUNC_TRACE();
@@ -1009,5 +1044,12 @@ hn_dev_close(struct rte_eth_dev *dev)
return 0;
- rte_eal_alarm_cancel(netvsc_hotplug_retry, &hv->devargs);
+ rte_spinlock_lock(&hv->hotadd_lock);
+ while (!LIST_EMPTY(&hv->hotadd_list)) {
+ hot_ctx = LIST_FIRST(&hv->hotadd_list);
+ rte_eal_alarm_cancel(netvsc_hotplug_retry, hot_ctx);
+ LIST_REMOVE(hot_ctx, list);
+ rte_free(hot_ctx);
+ }
+ rte_spinlock_unlock(&hv->hotadd_lock);
ret = hn_vf_close(dev);
@@ -1098,4 +1140,7 @@ eth_hn_dev_init(struct rte_eth_dev *eth_dev)
PMD_INIT_FUNC_TRACE();
+ rte_spinlock_init(&hv->hotadd_lock);
+ LIST_INIT(&hv->hotadd_list);
+
vmbus = container_of(device, struct rte_vmbus_device, device);
eth_dev->dev_ops = &hn_eth_dev_ops;
@@ -1222,4 +1267,7 @@ eth_hn_dev_uninit(struct rte_eth_dev *eth_dev)
hn_dev_close(eth_dev);
+ free(hv->vf_devargs);
+ hv->vf_devargs = NULL;
+
hn_detach(hv);
hn_chim_uninit(eth_dev);
diff --git a/drivers/net/netvsc/hn_var.h b/drivers/net/netvsc/hn_var.h
index fbb3995507..416c042a27 100644
--- a/drivers/net/netvsc/hn_var.h
+++ b/drivers/net/netvsc/hn_var.h
@@ -127,4 +127,11 @@ struct hn_vf_ctx {
};
+struct hv_hotadd_context {
+ LIST_ENTRY(hv_hotadd_context) list;
+ struct hn_data *hv;
+ struct rte_devargs da;
+ int eal_hot_plug_retry;
+};
+
struct hn_data {
struct rte_vmbus_device *vmbus;
@@ -176,6 +183,7 @@ struct hn_data {
struct vmbus_channel *channels[HN_MAX_CHANNELS];
- struct rte_devargs devargs;
- int eal_hot_plug_retry;
+ rte_spinlock_t hotadd_lock;
+ LIST_HEAD(hotadd_list, hv_hotadd_context) hotadd_list;
+ char *vf_devargs;
};
diff --git a/drivers/net/netvsc/hn_vf.c b/drivers/net/netvsc/hn_vf.c
index ebb9c60147..62948bf889 100644
--- a/drivers/net/netvsc/hn_vf.c
+++ b/drivers/net/netvsc/hn_vf.c
@@ -130,4 +130,8 @@ static void hn_remove_delayed(void *args)
port_id, ret);
+ /* Record the device parameters for possible hotplug events */
+ if (dev->devargs && dev->devargs->args)
+ hv->vf_devargs = strdup(dev->devargs->args);
+
ret = rte_eth_dev_close(port_id);
if (ret)
--
2.34.3
---
Diff of the applied patch vs upstream commit (please double-check if non-empty:
---
--- - 2022-05-25 17:26:58.703712477 +0100
+++ 0002-net-netvsc-fix-hot-adding-multiple-VF-PCI-devices.patch 2022-05-25 17:26:58.529828276 +0100
@@ -1 +1 @@
-From 7fc4c0997b046e2874a9806431b3d267bb684b41 Mon Sep 17 00:00:00 2001
+From 8ab93b06bcf03b86b7d1c021350736568e85e690 Mon Sep 17 00:00:00 2001
@@ -5,0 +6,2 @@
+[ upstream commit 7fc4c0997b046e2874a9806431b3d267bb684b41 ]
+
@@ -16 +17,0 @@
-Cc: stable at dpdk.org
More information about the stable
mailing list