From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 7F565460E2; Tue, 28 Jan 2025 02:35:30 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 9916240E09; Tue, 28 Jan 2025 02:35:29 +0100 (CET) Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by mails.dpdk.org (Postfix) with ESMTP id 543B340144 for ; Tue, 28 Jan 2025 02:35:27 +0100 (CET) Received: by linux.microsoft.com (Postfix, from userid 1202) id B7F592037171; Mon, 27 Jan 2025 17:35:26 -0800 (PST) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com B7F592037171 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxonhyperv.com; s=default; t=1738028126; bh=tHNZTdGs6/2E8FdM4ZwaV1hXRVMiX8kfK0j0fZ4ox1o=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DvqHjuparzPggjCogESmUUC7yig4mzGYpbT/2vwdzV0VlbDdIlr+JfZHJiCVowUDT 9d1Y243H0CUbtwsbDW1mJqunxbvCV5BKGFb9COG2rHyeLUQdFInfP70sOFFPskUYnr 56DnGZIwVMif6GoAuaBQyJJXGP13LW08uyB2GN4s= From: longli@linuxonhyperv.com To: Ferruh Yigit , Andrew Rybchenko , Wei Hu Cc: dev@dpdk.org, Long Li Subject: [PATCH 4/4] net/netvsc: cache device parameters for hot plug events Date: Mon, 27 Jan 2025 17:35:06 -0800 Message-Id: <1738028106-25239-4-git-send-email-longli@linuxonhyperv.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1738028106-25239-1-git-send-email-longli@linuxonhyperv.com> References: <1738028106-25239-1-git-send-email-longli@linuxonhyperv.com> X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org From: Long Li If a device is hot removed and hot plugged, it needs the same driver parameters that are passed to EAL. However, during device removal, all EAL driver parameters are freed as part of the cleanup. Cache those driver parameters for future hot plug events. Because we don't know which device will show up, cache all the PCI driver parameters. Signed-off-by: Long Li --- drivers/net/netvsc/hn_ethdev.c | 107 +++++++++++++++++++++++++++++---- drivers/net/netvsc/hn_var.h | 1 - drivers/net/netvsc/hn_vf.c | 4 -- 3 files changed, 94 insertions(+), 18 deletions(-) diff --git a/drivers/net/netvsc/hn_ethdev.c b/drivers/net/netvsc/hn_ethdev.c index f848157b49..afbbccd822 100644 --- a/drivers/net/netvsc/hn_ethdev.c +++ b/drivers/net/netvsc/hn_ethdev.c @@ -95,6 +95,16 @@ static const uint8_t rss_default_key[NDIS_HASH_KEYSIZE_TOEPLITZ] = { 0x06, 0x3c, 0x25, 0xf3, 0xfc, 0x1f, 0xdc, 0x2a, }; +static rte_spinlock_t netvsc_lock = RTE_SPINLOCK_INITIALIZER; +struct da_cache { + LIST_ENTRY(da_cache) list; + char name[RTE_DEV_NAME_MAX_LEN]; + char *drv_str; +}; + +LIST_HEAD(da_cache_list, da_cache) da_cache_list; +static unsigned int da_cache_usage; + static struct rte_eth_dev * eth_dev_vmbus_allocate(struct rte_vmbus_device *dev, size_t private_data_size) { @@ -623,16 +633,21 @@ static void netvsc_hotplug_retry(void *args) RTE_DIM(eth_addr.addr_bytes)); if (rte_is_same_ether_addr(ð_addr, dev->data->mac_addrs)) { + struct da_cache *cache; + + LIST_FOREACH(cache, &da_cache_list, list) { + if (strcmp(cache->name, d->name) == 0) + break; + } + PMD_DRV_LOG(NOTICE, - "Found matching MAC address, adding device %s network name %s", - d->name, dir->d_name); + "Found matching MAC address, adding device %s network name %s args %s", + d->name, dir->d_name, cache ? cache->drv_str : ""); /* If this device has been hot removed from this * parent device, restore its args. */ - ret = rte_eal_hotplug_add(d->bus->name, d->name, - hv->vf_devargs ? - hv->vf_devargs : ""); + ret = rte_eal_hotplug_add(d->bus->name, d->name, cache ? cache->drv_str : ""); if (ret) { PMD_DRV_LOG(ERR, "Failed to add PCI device %s", @@ -1409,9 +1424,6 @@ eth_hn_dev_uninit(struct rte_eth_dev *eth_dev) ret_stop = hn_dev_stop(eth_dev); hn_dev_close(eth_dev); - free(hv->vf_devargs); - hv->vf_devargs = NULL; - hn_detach(hv); hn_chim_uninit(eth_dev); rte_vmbus_chan_close(hv->channels[0]); @@ -1423,6 +1435,61 @@ eth_hn_dev_uninit(struct rte_eth_dev *eth_dev) return ret_stop; } +static int populate_cache_list(void) +{ + int ret; + struct rte_devargs *da; + + rte_spinlock_lock(&netvsc_lock); + da_cache_usage++; + if (da_cache_usage > 1) { + ret = 0; + goto out; + } + + LIST_INIT(&da_cache_list); + RTE_EAL_DEVARGS_FOREACH("pci", da) { + struct da_cache *cache; + + cache = rte_zmalloc("NETVSC-HOTADD", sizeof(*cache), rte_mem_page_size()); + if (!cache) { + ret = -ENOMEM; + goto out; + } + + strncpy(cache->name, da->name, sizeof(da->name)); + cache->drv_str = strdup(da->drv_str); + if (!cache->drv_str) { + rte_free(cache); + ret = -ENOMEM; + goto out; + } + + LIST_INSERT_HEAD(&da_cache_list, cache, list); + } +out: + rte_spinlock_unlock(&netvsc_lock); + return ret; +} + +static void remove_cache_list(void) +{ + struct da_cache *cache; + + rte_spinlock_lock(&netvsc_lock); + da_cache_usage--; + if (da_cache_usage) + goto out; + + LIST_FOREACH(cache, &da_cache_list, list) { + LIST_REMOVE(cache, list); + free(cache->drv_str); + rte_free(cache); + } +out: + rte_spinlock_unlock(&netvsc_lock); +} + static int eth_hn_probe(struct rte_vmbus_driver *drv __rte_unused, struct rte_vmbus_device *dev) { @@ -1431,24 +1498,35 @@ static int eth_hn_probe(struct rte_vmbus_driver *drv __rte_unused, PMD_INIT_FUNC_TRACE(); + ret = populate_cache_list(); + if (ret) + return ret; + ret = rte_dev_event_monitor_start(); if (ret) { PMD_DRV_LOG(ERR, "Failed to start device event monitoring"); - return ret; + goto fail; } eth_dev = eth_dev_vmbus_allocate(dev, sizeof(struct hn_data)); - if (!eth_dev) - return -ENOMEM; + if (!eth_dev) { + rte_dev_event_monitor_stop(); + ret = -ENOMEM; + goto fail; + } ret = eth_hn_dev_init(eth_dev); if (ret) { eth_dev_vmbus_release(eth_dev); rte_dev_event_monitor_stop(); - } else { - rte_eth_dev_probing_finish(eth_dev); + goto fail; } + rte_eth_dev_probing_finish(eth_dev); + return 0; + +fail: + remove_cache_list(); return ret; } @@ -1469,6 +1547,9 @@ static int eth_hn_remove(struct rte_vmbus_device *dev) eth_dev_vmbus_release(eth_dev); rte_dev_event_monitor_stop(); + + remove_cache_list(); + return 0; } diff --git a/drivers/net/netvsc/hn_var.h b/drivers/net/netvsc/hn_var.h index 0f638bc5fd..d2263e03e8 100644 --- a/drivers/net/netvsc/hn_var.h +++ b/drivers/net/netvsc/hn_var.h @@ -184,7 +184,6 @@ struct hn_data { rte_spinlock_t hotadd_lock; LIST_HEAD(hotadd_list, hv_hotadd_context) hotadd_list; - char *vf_devargs; }; static inline struct vmbus_channel * diff --git a/drivers/net/netvsc/hn_vf.c b/drivers/net/netvsc/hn_vf.c index 4ff766ec8b..d922e685f4 100644 --- a/drivers/net/netvsc/hn_vf.c +++ b/drivers/net/netvsc/hn_vf.c @@ -130,10 +130,6 @@ static void hn_remove_delayed(void *args) PMD_DRV_LOG(ERR, "rte_eth_dev_stop failed port_id=%u ret=%d", 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) PMD_DRV_LOG(ERR, "rte_eth_dev_close failed port_id=%u ret=%d", -- 2.34.1