From 1c6cd96ee421465f3f87a77d6b59fcbfabdafc67 Mon Sep 17 00:00:00 2001 From: Cunyin Chang Date: Tue, 15 Nov 2016 08:37:12 +0800 Subject: [PATCH] env_dpdk: NVMe and IOAT drivers are always registered. Change-Id: I46ea311e9d8972641c4c4c6d764955847b1f9786 Signed-off-by: Cunyin Chang --- lib/env_dpdk/pci.c | 148 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 122 insertions(+), 26 deletions(-) diff --git a/lib/env_dpdk/pci.c b/lib/env_dpdk/pci.c index dd3edec6b..5b96704fb 100644 --- a/lib/env_dpdk/pci.c +++ b/lib/env_dpdk/pci.c @@ -44,9 +44,14 @@ #include #include +#include #include #include +#if RTE_VERSION < RTE_VERSION_NUM(16, 11, 0, 0) +#include +#endif + #define spdk_pci_device rte_pci_device #ifdef __FreeBSD__ @@ -63,8 +68,9 @@ struct spdk_pci_enum_ctx { struct rte_pci_driver driver; - spdk_pci_enum_cb enum_cb; - void *enum_ctx; + spdk_pci_enum_cb cb_fn; + void *cb_arg; + pthread_mutex_t mtx; }; static struct rte_pci_id nvme_pci_driver_id[] = { @@ -139,6 +145,16 @@ spdk_pci_device_init(struct rte_pci_driver *driver, { struct spdk_pci_enum_ctx *ctx = (struct spdk_pci_enum_ctx *)driver; + if (!ctx->cb_fn) { +#if RTE_VERSION >= RTE_VERSION_NUM(16, 11, 0, 0) + rte_eal_pci_unmap_device(device); +#endif + + /* Return a positive value to indicate that this device does not belong to this driver, but + * this isn't an error. */ + return 1; + } + if (device->kdrv == RTE_KDRV_VFIO) { /* * TODO: This is a workaround for an issue where the device is not ready after VFIO reset. @@ -147,7 +163,7 @@ spdk_pci_device_init(struct rte_pci_driver *driver, usleep(500 * 1000); } - return ctx->enum_cb(ctx->enum_ctx, (struct spdk_pci_device *)device); + return ctx->cb_fn(ctx->cb_arg, (struct spdk_pci_device *)device); } static int @@ -156,44 +172,124 @@ spdk_pci_device_fini(struct rte_pci_device *device) return 0; } +static struct spdk_pci_enum_ctx g_nvme_pci_drv = { + .driver = { + .drv_flags = RTE_PCI_DRV_NEED_MAPPING, + .id_table = nvme_pci_driver_id, +#if RTE_VERSION >= RTE_VERSION_NUM(16, 11, 0, 0) + .probe = spdk_pci_device_init, + .remove = spdk_pci_device_fini, +#else + .devinit = spdk_pci_device_init, + .devuninit = spdk_pci_device_fini, +#endif + }, + + .cb_fn = NULL, + .cb_arg = NULL, + .mtx = PTHREAD_MUTEX_INITIALIZER, +}; + +#if RTE_VERSION >= RTE_VERSION_NUM(16, 11, 0, 0) +RTE_PMD_REGISTER_PCI(spdk_nvme, g_nvme_pci_drv.driver); +#else +static int +spdk_nvme_drv_register(const char *name __rte_unused, const char *params __rte_unused) +{ + rte_eal_pci_register(&g_nvme_pci_drv.driver); + + return 0; +} + +static struct rte_driver g_nvme_drv = { + .type = PMD_PDEV, + .init = spdk_nvme_drv_register, +}; + +PMD_REGISTER_DRIVER(g_nvme_drv, spdk_nvme); +#endif + +static struct spdk_pci_enum_ctx g_ioat_pci_drv = { + .driver = { + .drv_flags = RTE_PCI_DRV_NEED_MAPPING, + .id_table = ioat_driver_id, +#if RTE_VERSION >= RTE_VERSION_NUM(16, 11, 0, 0) + .probe = spdk_pci_device_init, + .remove = spdk_pci_device_fini, +#else + .devinit = spdk_pci_device_init, + .devuninit = spdk_pci_device_fini, +#endif + }, + + .cb_fn = NULL, + .cb_arg = NULL, + .mtx = PTHREAD_MUTEX_INITIALIZER, +}; + +#if RTE_VERSION >= RTE_VERSION_NUM(16, 11, 0, 0) +RTE_PMD_REGISTER_PCI(spdk_ioat, g_ioat_pci_drv.driver); +#else +static int +spdk_ioat_drv_register(const char *name __rte_unused, const char *params __rte_unused) +{ + rte_eal_pci_register(&g_ioat_pci_drv.driver); + + return 0; +} + +static struct rte_driver g_ioat_drv = { + .type = PMD_PDEV, + .init = spdk_ioat_drv_register, +}; + +PMD_REGISTER_DRIVER(g_ioat_drv, spdk_ioat); +#endif + +/* Note: You can call spdk_pci_enumerate from more than one thread + * simultaneously safely, but you cannot call spdk_pci_enumerate + * and rte_eal_pci_probe simultaneously. +*/ int spdk_pci_enumerate(enum spdk_pci_device_type type, spdk_pci_enum_cb enum_cb, void *enum_ctx) { - struct spdk_pci_enum_ctx ctx = {}; - int rc; - const char *name; + struct spdk_pci_enum_ctx *ctx; if (type == SPDK_PCI_DEVICE_NVME) { - name = "SPDK NVMe"; - ctx.driver.id_table = nvme_pci_driver_id; + ctx = &g_nvme_pci_drv; } else if (type == SPDK_PCI_DEVICE_IOAT) { - name = "SPDK IOAT"; - ctx.driver.id_table = ioat_driver_id; + ctx = &g_ioat_pci_drv; } else { return -1; } - ctx.enum_cb = enum_cb; - ctx.enum_ctx = enum_ctx; - ctx.driver.drv_flags = RTE_PCI_DRV_NEED_MAPPING; -#if RTE_VERSION >= RTE_VERSION_NUM(16, 11, 0, 0) - ctx.driver.probe = spdk_pci_device_init; - ctx.driver.remove = spdk_pci_device_fini; - ctx.driver.driver.name = name; -#else - ctx.driver.devinit = spdk_pci_device_init; - ctx.driver.devuninit = spdk_pci_device_fini; - ctx.driver.name = name; -#endif + pthread_mutex_lock(&ctx->mtx); - rte_eal_pci_register(&ctx.driver); - rc = rte_eal_pci_probe(); - rte_eal_pci_unregister(&ctx.driver); + ctx->cb_fn = enum_cb; + ctx->cb_arg = enum_ctx; - return rc; + if (rte_eal_pci_scan() != 0) { + ctx->cb_arg = NULL; + ctx->cb_fn = NULL; + pthread_mutex_unlock(&ctx->mtx); + return -1; + } + + if (rte_eal_pci_probe() != 0) { + ctx->cb_arg = NULL; + ctx->cb_fn = NULL; + pthread_mutex_unlock(&ctx->mtx); + return -1; + } + + ctx->cb_arg = NULL; + ctx->cb_fn = NULL; + pthread_mutex_unlock(&ctx->mtx); + + return 0; } int