From 11313c2090fb48729d09e2f629685ef409d8dc14 Mon Sep 17 00:00:00 2001 From: Jim Harris Date: Thu, 15 Sep 2022 18:54:26 +0000 Subject: [PATCH] env_dpdk: move dpdk pci code to pci_dpdk.c/h Signed-off-by: Jim Harris Change-Id: I54489903f48a8a2e500f64c2e7f8530eed1e6882 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/14548 Reviewed-by: Aleksey Marchuk Reviewed-by: Konrad Sztyber Tested-by: SPDK CI Jenkins --- lib/env_dpdk/Makefile | 2 +- lib/env_dpdk/env_internal.h | 2 - lib/env_dpdk/memory.c | 1 + lib/env_dpdk/pci.c | 251 +----------------------------------- lib/env_dpdk/pci_dpdk.c | 225 ++++++++++++++++++++++++++++++++ lib/env_dpdk/pci_dpdk.h | 51 ++++++++ 6 files changed, 279 insertions(+), 253 deletions(-) create mode 100644 lib/env_dpdk/pci_dpdk.c create mode 100644 lib/env_dpdk/pci_dpdk.h diff --git a/lib/env_dpdk/Makefile b/lib/env_dpdk/Makefile index 70b8f6b2b..e9827eaea 100644 --- a/lib/env_dpdk/Makefile +++ b/lib/env_dpdk/Makefile @@ -12,7 +12,7 @@ SO_MINOR := 0 CFLAGS += $(ENV_CFLAGS) C_SRCS = env.c memory.c pci.c init.c threads.c C_SRCS += pci_ioat.c pci_virtio.c pci_vmd.c pci_idxd.c -C_SRCS += pci_event.c sigbus_handler.c +C_SRCS += pci_event.c sigbus_handler.c pci_dpdk.c LIBNAME = env_dpdk SPDK_MAP_FILE = $(abspath $(CURDIR)/spdk_env_dpdk.map) diff --git a/lib/env_dpdk/env_internal.h b/lib/env_dpdk/env_internal.h index d38133d2c..4e6145e7b 100644 --- a/lib/env_dpdk/env_internal.h +++ b/lib/env_dpdk/env_internal.h @@ -35,8 +35,6 @@ int vtophys_init(void); struct rte_pci_device; -uint64_t dpdk_pci_device_vtophys(struct rte_pci_device *dev, uint64_t vaddr); - /** * Report a DMA-capable PCI device to the vtophys translation code. * Increases the refcount of active DMA-capable devices managed by SPDK. diff --git a/lib/env_dpdk/memory.c b/lib/env_dpdk/memory.c index 3f6885f0c..208a6a763 100644 --- a/lib/env_dpdk/memory.c +++ b/lib/env_dpdk/memory.c @@ -6,6 +6,7 @@ #include "spdk/stdinc.h" #include "env_internal.h" +#include "pci_dpdk.h" #include #include diff --git a/lib/env_dpdk/pci.c b/lib/env_dpdk/pci.c index 09b7eb5e6..9538754e7 100644 --- a/lib/env_dpdk/pci.c +++ b/lib/env_dpdk/pci.c @@ -4,14 +4,13 @@ */ #include "env_internal.h" +#include "pci_dpdk.h" #include -#include #include #include "spdk/env.h" #include "spdk/log.h" #include "spdk/string.h" -#include "spdk/assert.h" #define SYSFS_PCI_DRIVERS "/sys/bus/pci/drivers" @@ -40,44 +39,6 @@ static TAILQ_HEAD(, spdk_pci_driver) g_pci_drivers = TAILQ_HEAD_INITIALIZER(g_pc static TAILQ_HEAD(, spdk_pci_device_provider) g_pci_device_providers = TAILQ_HEAD_INITIALIZER(g_pci_device_providers); -struct spdk_pci_driver { - uint8_t driver_buf[256]; - struct rte_pci_driver *driver; - - const char *name; - const struct spdk_pci_id *id_table; - uint32_t drv_flags; - - spdk_pci_enum_cb cb_fn; - void *cb_arg; - TAILQ_ENTRY(spdk_pci_driver) tailq; -}; -SPDK_STATIC_ASSERT(offsetof(struct spdk_pci_driver, driver_buf) == 0, "driver_buf must be first"); -SPDK_STATIC_ASSERT(offsetof(struct spdk_pci_driver, driver) >= sizeof(struct rte_pci_driver), - "driver_buf not big enough"); - -const char *dpdk_pci_device_get_name(struct rte_pci_device *); -struct rte_devargs *dpdk_pci_device_get_devargs(struct rte_pci_device *); -void dpdk_pci_device_copy_identifiers(struct rte_pci_device *_dev, struct spdk_pci_device *dev); -int dpdk_pci_device_map_bar(struct rte_pci_device *dev, uint32_t bar, - void **mapped_addr, uint64_t *phys_addr, uint64_t *size); -int dpdk_pci_device_read_config(struct rte_pci_device *dev, void *value, uint32_t len, - uint32_t offset); -int dpdk_pci_device_write_config(struct rte_pci_device *dev, void *value, uint32_t len, - uint32_t offset); -int dpdk_pci_driver_register(struct spdk_pci_driver *driver, - int (*probe_fn)(struct rte_pci_driver *driver, struct rte_pci_device *device), - int (*remove_fn)(struct rte_pci_device *device)); -int dpdk_pci_device_enable_interrupt(struct rte_pci_device *rte_dev); -int dpdk_pci_device_disable_interrupt(struct rte_pci_device *rte_dev); -int dpdk_pci_device_get_interrupt_efd(struct rte_pci_device *rte_dev); -void dpdk_bus_scan(void); -int dpdk_bus_probe(void); -struct rte_devargs *dpdk_device_get_devargs(struct rte_device *dev); -void dpdk_device_set_devargs(struct rte_device *dev, struct rte_devargs *devargs); -const char *dpdk_device_get_name(struct rte_device *dev); -bool dpdk_device_scan_allowed(struct rte_device *dev); - int pci_device_init(struct rte_pci_driver *driver, struct rte_pci_device *device); int pci_device_fini(struct rte_pci_device *device); @@ -1172,213 +1133,3 @@ spdk_pci_device_allow(struct spdk_pci_addr *pci_addr) return 0; } - -uint64_t -dpdk_pci_device_vtophys(struct rte_pci_device *dev, uint64_t vaddr) -{ - struct rte_mem_resource *res; - uint64_t paddr; - unsigned r; - - for (r = 0; r < PCI_MAX_RESOURCE; r++) { - res = &dev->mem_resource[r]; - if (res->phys_addr && vaddr >= (uint64_t)res->addr && - vaddr < (uint64_t)res->addr + res->len) { - paddr = res->phys_addr + (vaddr - (uint64_t)res->addr); - return paddr; - } - } - - return SPDK_VTOPHYS_ERROR; -} - -const char * -dpdk_pci_device_get_name(struct rte_pci_device *rte_dev) -{ - return rte_dev->name; -} - -struct rte_devargs * -dpdk_pci_device_get_devargs(struct rte_pci_device *rte_dev) -{ - return rte_dev->device.devargs; -} - -void -dpdk_pci_device_copy_identifiers(struct rte_pci_device *_dev, struct spdk_pci_device *dev) -{ - dev->addr.domain = _dev->addr.domain; - dev->addr.bus = _dev->addr.bus; - dev->addr.dev = _dev->addr.devid; - dev->addr.func = _dev->addr.function; - dev->id.class_id = _dev->id.class_id; - dev->id.vendor_id = _dev->id.vendor_id; - dev->id.device_id = _dev->id.device_id; - dev->id.subvendor_id = _dev->id.subsystem_vendor_id; - dev->id.subdevice_id = _dev->id.subsystem_device_id; - dev->socket_id = _dev->device.numa_node; -} - -int -dpdk_pci_device_map_bar(struct rte_pci_device *dev, uint32_t bar, - void **mapped_addr, uint64_t *phys_addr, uint64_t *size) -{ - *mapped_addr = dev->mem_resource[bar].addr; - *phys_addr = (uint64_t)dev->mem_resource[bar].phys_addr; - *size = (uint64_t)dev->mem_resource[bar].len; - - return 0; -} - -int -dpdk_pci_device_read_config(struct rte_pci_device *dev, void *value, uint32_t len, uint32_t offset) -{ - int rc; - - rc = rte_pci_read_config(dev, value, len, offset); - - return (rc > 0 && (uint32_t) rc == len) ? 0 : -1; -} - -int -dpdk_pci_device_write_config(struct rte_pci_device *dev, void *value, uint32_t len, uint32_t offset) -{ - int rc; - - rc = rte_pci_write_config(dev, value, len, offset); - -#ifdef __FreeBSD__ - /* DPDK returns 0 on success and -1 on failure */ - return rc; -#endif - return (rc > 0 && (uint32_t) rc == len) ? 0 : -1; -} - -/* translate spdk_pci_driver to an rte_pci_driver and register it to dpdk */ -int -dpdk_pci_driver_register(struct spdk_pci_driver *driver, - int (*probe_fn)(struct rte_pci_driver *driver, struct rte_pci_device *device), - int (*remove_fn)(struct rte_pci_device *device)) -{ - unsigned pci_id_count = 0; - struct rte_pci_id *rte_id_table; - char *rte_name; - size_t rte_name_len; - uint32_t rte_flags; - - assert(driver->id_table); - while (driver->id_table[pci_id_count].vendor_id) { - pci_id_count++; - } - assert(pci_id_count > 0); - - rte_id_table = calloc(pci_id_count + 1, sizeof(*rte_id_table)); - if (!rte_id_table) { - return -ENOMEM; - } - - while (pci_id_count > 0) { - struct rte_pci_id *rte_id = &rte_id_table[pci_id_count - 1]; - const struct spdk_pci_id *spdk_id = &driver->id_table[pci_id_count - 1]; - - rte_id->class_id = spdk_id->class_id; - rte_id->vendor_id = spdk_id->vendor_id; - rte_id->device_id = spdk_id->device_id; - rte_id->subsystem_vendor_id = spdk_id->subvendor_id; - rte_id->subsystem_device_id = spdk_id->subdevice_id; - pci_id_count--; - } - - assert(driver->name); - rte_name_len = strlen(driver->name) + strlen("spdk_") + 1; - rte_name = calloc(rte_name_len, 1); - if (!rte_name) { - free(rte_id_table); - return -ENOMEM; - } - - snprintf(rte_name, rte_name_len, "spdk_%s", driver->name); - driver->driver->driver.name = rte_name; - driver->driver->id_table = rte_id_table; - - rte_flags = 0; - if (driver->drv_flags & SPDK_PCI_DRIVER_NEED_MAPPING) { - rte_flags |= RTE_PCI_DRV_NEED_MAPPING; - } - if (driver->drv_flags & SPDK_PCI_DRIVER_WC_ACTIVATE) { - rte_flags |= RTE_PCI_DRV_WC_ACTIVATE; - } - driver->driver->drv_flags = rte_flags; - - driver->driver->probe = probe_fn; - driver->driver->remove = remove_fn; - - rte_pci_register(driver->driver); - return 0; -} - -int -dpdk_pci_device_enable_interrupt(struct rte_pci_device *rte_dev) -{ -#if RTE_VERSION < RTE_VERSION_NUM(21, 11, 0, 0) - return rte_intr_enable(&rte_dev->intr_handle); -#else - return rte_intr_enable(rte_dev->intr_handle); -#endif -} - -int -dpdk_pci_device_disable_interrupt(struct rte_pci_device *rte_dev) -{ -#if RTE_VERSION < RTE_VERSION_NUM(21, 11, 0, 0) - return rte_intr_disable(&rte_dev->intr_handle); -#else - return rte_intr_disable(rte_dev->intr_handle); -#endif -} - -int -dpdk_pci_device_get_interrupt_efd(struct rte_pci_device *rte_dev) -{ -#if RTE_VERSION < RTE_VERSION_NUM(21, 11, 0, 0) - return rte_dev->intr_handle.fd; -#else - return rte_intr_fd_get(rte_dev->intr_handle); -#endif -} - -int -dpdk_bus_probe(void) -{ - return rte_bus_probe(); -} - -void -dpdk_bus_scan(void) -{ - rte_bus_scan(); -} - -struct rte_devargs * -dpdk_device_get_devargs(struct rte_device *dev) -{ - return dev->devargs; -} - -void -dpdk_device_set_devargs(struct rte_device *dev, struct rte_devargs *devargs) -{ - dev->devargs = devargs; -} - -const char * -dpdk_device_get_name(struct rte_device *dev) -{ - return dev->name; -} - -bool -dpdk_device_scan_allowed(struct rte_device *dev) -{ - return dev->bus->conf.scan_mode == RTE_BUS_SCAN_ALLOWLIST; -} diff --git a/lib/env_dpdk/pci_dpdk.c b/lib/env_dpdk/pci_dpdk.c new file mode 100644 index 000000000..0f8851a95 --- /dev/null +++ b/lib/env_dpdk/pci_dpdk.c @@ -0,0 +1,225 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) Intel Corporation. + * All rights reserved. + */ + +#include +#include +#include "pci_dpdk.h" +#include +#include "spdk/assert.h" + +SPDK_STATIC_ASSERT(offsetof(struct spdk_pci_driver, driver_buf) == 0, "driver_buf must be first"); +SPDK_STATIC_ASSERT(offsetof(struct spdk_pci_driver, driver) >= sizeof(struct rte_pci_driver), + "driver_buf not big enough"); + +uint64_t +dpdk_pci_device_vtophys(struct rte_pci_device *dev, uint64_t vaddr) +{ + struct rte_mem_resource *res; + uint64_t paddr; + unsigned r; + + for (r = 0; r < PCI_MAX_RESOURCE; r++) { + res = &dev->mem_resource[r]; + if (res->phys_addr && vaddr >= (uint64_t)res->addr && + vaddr < (uint64_t)res->addr + res->len) { + paddr = res->phys_addr + (vaddr - (uint64_t)res->addr); + return paddr; + } + } + + return SPDK_VTOPHYS_ERROR; +} + +const char * +dpdk_pci_device_get_name(struct rte_pci_device *rte_dev) +{ + return rte_dev->name; +} + +struct rte_devargs * +dpdk_pci_device_get_devargs(struct rte_pci_device *rte_dev) +{ + return rte_dev->device.devargs; +} + +void +dpdk_pci_device_copy_identifiers(struct rte_pci_device *_dev, struct spdk_pci_device *dev) +{ + dev->addr.domain = _dev->addr.domain; + dev->addr.bus = _dev->addr.bus; + dev->addr.dev = _dev->addr.devid; + dev->addr.func = _dev->addr.function; + dev->id.class_id = _dev->id.class_id; + dev->id.vendor_id = _dev->id.vendor_id; + dev->id.device_id = _dev->id.device_id; + dev->id.subvendor_id = _dev->id.subsystem_vendor_id; + dev->id.subdevice_id = _dev->id.subsystem_device_id; + dev->socket_id = _dev->device.numa_node; +} + +int +dpdk_pci_device_map_bar(struct rte_pci_device *dev, uint32_t bar, + void **mapped_addr, uint64_t *phys_addr, uint64_t *size) +{ + *mapped_addr = dev->mem_resource[bar].addr; + *phys_addr = (uint64_t)dev->mem_resource[bar].phys_addr; + *size = (uint64_t)dev->mem_resource[bar].len; + + return 0; +} + +int +dpdk_pci_device_read_config(struct rte_pci_device *dev, void *value, uint32_t len, uint32_t offset) +{ + int rc; + + rc = rte_pci_read_config(dev, value, len, offset); + + return (rc > 0 && (uint32_t) rc == len) ? 0 : -1; +} + +int +dpdk_pci_device_write_config(struct rte_pci_device *dev, void *value, uint32_t len, uint32_t offset) +{ + int rc; + + rc = rte_pci_write_config(dev, value, len, offset); + +#ifdef __FreeBSD__ + /* DPDK returns 0 on success and -1 on failure */ + return rc; +#endif + return (rc > 0 && (uint32_t) rc == len) ? 0 : -1; +} + +/* translate spdk_pci_driver to an rte_pci_driver and register it to dpdk */ +int +dpdk_pci_driver_register(struct spdk_pci_driver *driver, + int (*probe_fn)(struct rte_pci_driver *driver, struct rte_pci_device *device), + int (*remove_fn)(struct rte_pci_device *device)) + +{ + unsigned pci_id_count = 0; + struct rte_pci_id *rte_id_table; + char *rte_name; + size_t rte_name_len; + uint32_t rte_flags; + + assert(driver->id_table); + while (driver->id_table[pci_id_count].vendor_id) { + pci_id_count++; + } + assert(pci_id_count > 0); + + rte_id_table = calloc(pci_id_count + 1, sizeof(*rte_id_table)); + if (!rte_id_table) { + return -ENOMEM; + } + + while (pci_id_count > 0) { + struct rte_pci_id *rte_id = &rte_id_table[pci_id_count - 1]; + const struct spdk_pci_id *spdk_id = &driver->id_table[pci_id_count - 1]; + + rte_id->class_id = spdk_id->class_id; + rte_id->vendor_id = spdk_id->vendor_id; + rte_id->device_id = spdk_id->device_id; + rte_id->subsystem_vendor_id = spdk_id->subvendor_id; + rte_id->subsystem_device_id = spdk_id->subdevice_id; + pci_id_count--; + } + + assert(driver->name); + rte_name_len = strlen(driver->name) + strlen("spdk_") + 1; + rte_name = calloc(rte_name_len, 1); + if (!rte_name) { + free(rte_id_table); + return -ENOMEM; + } + + snprintf(rte_name, rte_name_len, "spdk_%s", driver->name); + driver->driver->driver.name = rte_name; + driver->driver->id_table = rte_id_table; + + rte_flags = 0; + if (driver->drv_flags & SPDK_PCI_DRIVER_NEED_MAPPING) { + rte_flags |= RTE_PCI_DRV_NEED_MAPPING; + } + if (driver->drv_flags & SPDK_PCI_DRIVER_WC_ACTIVATE) { + rte_flags |= RTE_PCI_DRV_WC_ACTIVATE; + } + driver->driver->drv_flags = rte_flags; + + driver->driver->probe = probe_fn; + driver->driver->remove = remove_fn; + + rte_pci_register(driver->driver); + return 0; +} + +int +dpdk_pci_device_enable_interrupt(struct rte_pci_device *rte_dev) +{ +#if RTE_VERSION < RTE_VERSION_NUM(21, 11, 0, 0) + return rte_intr_enable(&rte_dev->intr_handle); +#else + return rte_intr_enable(rte_dev->intr_handle); +#endif +} + +int +dpdk_pci_device_disable_interrupt(struct rte_pci_device *rte_dev) +{ +#if RTE_VERSION < RTE_VERSION_NUM(21, 11, 0, 0) + return rte_intr_disable(&rte_dev->intr_handle); +#else + return rte_intr_disable(rte_dev->intr_handle); +#endif +} + +int +dpdk_pci_device_get_interrupt_efd(struct rte_pci_device *rte_dev) +{ +#if RTE_VERSION < RTE_VERSION_NUM(21, 11, 0, 0) + return rte_dev->intr_handle.fd; +#else + return rte_intr_fd_get(rte_dev->intr_handle); +#endif +} + +int +dpdk_bus_probe(void) +{ + return rte_bus_probe(); +} + +void +dpdk_bus_scan(void) +{ + rte_bus_scan(); +} + +struct rte_devargs * +dpdk_device_get_devargs(struct rte_device *dev) +{ + return dev->devargs; +} + +void +dpdk_device_set_devargs(struct rte_device *dev, struct rte_devargs *devargs) +{ + dev->devargs = devargs; +} + +const char * +dpdk_device_get_name(struct rte_device *dev) +{ + return dev->name; +} + +bool +dpdk_device_scan_allowed(struct rte_device *dev) +{ + return dev->bus->conf.scan_mode == RTE_BUS_SCAN_ALLOWLIST; +} diff --git a/lib/env_dpdk/pci_dpdk.h b/lib/env_dpdk/pci_dpdk.h new file mode 100644 index 000000000..0dfa19e8d --- /dev/null +++ b/lib/env_dpdk/pci_dpdk.h @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) Intel Corporation. + * All rights reserved. + */ + +#ifndef SPDK_PCI_DPDK_H +#define SPDK_PCI_DPDK_H + +#include "spdk/env.h" + +struct spdk_pci_driver { + uint8_t driver_buf[256]; + struct rte_pci_driver *driver; + + const char *name; + const struct spdk_pci_id *id_table; + uint32_t drv_flags; + + spdk_pci_enum_cb cb_fn; + void *cb_arg; + TAILQ_ENTRY(spdk_pci_driver) tailq; +}; + +struct rte_pci_device; +struct rte_pci_driver; +struct rte_device; + +uint64_t dpdk_pci_device_vtophys(struct rte_pci_device *dev, uint64_t vaddr); +const char *dpdk_pci_device_get_name(struct rte_pci_device *); +struct rte_devargs *dpdk_pci_device_get_devargs(struct rte_pci_device *); +void dpdk_pci_device_copy_identifiers(struct rte_pci_device *_dev, struct spdk_pci_device *dev); +int dpdk_pci_device_map_bar(struct rte_pci_device *dev, uint32_t bar, + void **mapped_addr, uint64_t *phys_addr, uint64_t *size); +int dpdk_pci_device_read_config(struct rte_pci_device *dev, void *value, uint32_t len, + uint32_t offset); +int dpdk_pci_device_write_config(struct rte_pci_device *dev, void *value, uint32_t len, + uint32_t offset); +int dpdk_pci_driver_register(struct spdk_pci_driver *driver, + int (*probe_fn)(struct rte_pci_driver *driver, struct rte_pci_device *device), + int (*remove_fn)(struct rte_pci_device *device)); +int dpdk_pci_device_enable_interrupt(struct rte_pci_device *rte_dev); +int dpdk_pci_device_disable_interrupt(struct rte_pci_device *rte_dev); +int dpdk_pci_device_get_interrupt_efd(struct rte_pci_device *rte_dev); +void dpdk_bus_scan(void); +int dpdk_bus_probe(void); +struct rte_devargs *dpdk_device_get_devargs(struct rte_device *dev); +void dpdk_device_set_devargs(struct rte_device *dev, struct rte_devargs *devargs); +const char *dpdk_device_get_name(struct rte_device *dev); +bool dpdk_device_scan_allowed(struct rte_device *dev); + +#endif /* ifndef SPDK_PCI_DPDK_H */