From 6c75f0a2663d463bc98597a5feaf2cb857cb2fd5 Mon Sep 17 00:00:00 2001 From: Jim Harris Date: Tue, 20 Apr 2021 12:20:08 -0700 Subject: [PATCH] env_dpdk: save hotplug timeout timestamps separate from rte_devargs DPDK recently clarified some semantics on the rte_devargs 'data' and 'args' fields. This actually breaks our use of the 'data' field to store the 2 second timeout timestamp for delaying attach to newly inserted devices. Investigating this further, it does not seem our use of the 'data' field was valid - it just happened to work until now. We could use the 'args' field now. But knowing whether to use 'args' or 'data' would then be dependent on the DPDK version. We cannot use RTE_VERSION_NUM to decide, because this is a compile time decision, and it is possible in shared library use cases that we could actually link and execute against a different version of DPDK than we built against. So instead we will create our own env_devargs structure that will store these allowed_at timestamps. Currently it's just a linked list (which is exactly how DPDK does it) - we could make it more optimal with a hash table down the road, but this code only executes when we are doing PCI enumeration so it is not performance critical. Fixes #1904. Signed-off-by: Jim Harris Change-Id: I3ee5d65ba90635b5a96b97dd0f4ab72a093fe8f7 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/7506 Community-CI: Broadcom CI Community-CI: Mellanox Build Bot Tested-by: SPDK CI Jenkins Reviewed-by: Aleksey Marchuk Reviewed-by: Ben Walker Reviewed-by: Shuhei Matsumoto Reviewed-by: Changpeng Liu Reviewed-by: --- examples/vmd/led/Makefile | 2 +- examples/vmd/lsvmd/Makefile | 2 +- lib/env_dpdk/pci.c | 48 +++++++++++++++++++++++++++++++++++-- 3 files changed, 48 insertions(+), 4 deletions(-) diff --git a/examples/vmd/led/Makefile b/examples/vmd/led/Makefile index 0fa807bbc5..518eedfb3b 100644 --- a/examples/vmd/led/Makefile +++ b/examples/vmd/led/Makefile @@ -39,6 +39,6 @@ APP = led C_SRCS := led.c -SPDK_LIB_LIST = vmd log +SPDK_LIB_LIST = vmd log util include $(SPDK_ROOT_DIR)/mk/spdk.app.mk diff --git a/examples/vmd/lsvmd/Makefile b/examples/vmd/lsvmd/Makefile index 96fde0773f..4b41a36a64 100644 --- a/examples/vmd/lsvmd/Makefile +++ b/examples/vmd/lsvmd/Makefile @@ -39,6 +39,6 @@ APP = lsvmd C_SRCS := lsvmd.c -SPDK_LIB_LIST = vmd log +SPDK_LIB_LIST = vmd log util include $(SPDK_ROOT_DIR)/mk/spdk.app.mk diff --git a/lib/env_dpdk/pci.c b/lib/env_dpdk/pci.c index f01717787d..84bc3b85aa 100644 --- a/lib/env_dpdk/pci.c +++ b/lib/env_dpdk/pci.c @@ -37,6 +37,7 @@ #include #include "spdk/env.h" #include "spdk/log.h" +#include "spdk/string.h" #define SYSFS_PCI_DRIVERS "/sys/bus/pci/drivers" @@ -63,6 +64,28 @@ static TAILQ_HEAD(, spdk_pci_device) g_pci_hotplugged_devices = TAILQ_HEAD_INITIALIZER(g_pci_hotplugged_devices); static TAILQ_HEAD(, spdk_pci_driver) g_pci_drivers = TAILQ_HEAD_INITIALIZER(g_pci_drivers); +struct env_devargs { + struct rte_bus *bus; + char name[128]; + uint64_t allowed_at; + TAILQ_ENTRY(env_devargs) link; +}; +static TAILQ_HEAD(, env_devargs) g_env_devargs = TAILQ_HEAD_INITIALIZER(g_env_devargs); + +static struct env_devargs * +find_env_devargs(struct rte_bus *bus, const char *name) +{ + struct env_devargs *da; + + TAILQ_FOREACH(da, &g_env_devargs, link) { + if (bus == da->bus && !strcmp(name, da->name)) { + return da; + } + } + + return NULL; +} + static int map_bar_rte(struct spdk_pci_device *device, uint32_t bar, void **mapped_addr, uint64_t *phys_addr, uint64_t *size) @@ -460,13 +483,34 @@ pci_device_init(struct rte_pci_driver *_drv, static void set_allowed_at(struct rte_devargs *rte_da, uint64_t tsc) { - rte_da->data = (void *)(tsc); + struct env_devargs *env_da; + + env_da = find_env_devargs(rte_da->bus, rte_da->name); + if (env_da == NULL) { + env_da = calloc(1, sizeof(*env_da)); + if (env_da == NULL) { + SPDK_ERRLOG("could not set_allowed_at for device %s\n", rte_da->name); + return; + } + env_da->bus = rte_da->bus; + spdk_strcpy_pad(env_da->name, rte_da->name, sizeof(env_da->name), 0); + TAILQ_INSERT_TAIL(&g_env_devargs, env_da, link); + } + + env_da->allowed_at = tsc; } static uint64_t get_allowed_at(struct rte_devargs *rte_da) { - return (uint64_t)rte_da->data; + struct env_devargs *env_da; + + env_da = find_env_devargs(rte_da->bus, rte_da->name); + if (env_da) { + return env_da->allowed_at; + } else { + return 0; + } } int