From f038354efa4889f5cd96f8a1ca2d06b30d604b6b Mon Sep 17 00:00:00 2001 From: Seth Howell Date: Tue, 10 Dec 2019 13:12:55 -0700 Subject: [PATCH] lib/nvmf: enable pluggable NVMe-oF transports. Change-Id: If1fd7d6c2385f42ca32dea0f8ecb528a60778d40 Signed-off-by: Seth Howell Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/477504 Tested-by: SPDK CI Jenkins Reviewed-by: Jim Harris Reviewed-by: Ben Walker Reviewed-by: Shuhei Matsumoto --- include/spdk/nvmf.h | 19 ++++++++++++ lib/nvmf/fc.c | 1 + lib/nvmf/rdma.c | 2 ++ lib/nvmf/tcp.c | 3 ++ lib/nvmf/transport.c | 48 ++++++++++++++++++++--------- lib/nvmf/transport.h | 5 ++- test/unit/lib/nvmf/rdma.c/rdma_ut.c | 3 -- test/unit/lib/nvmf/tcp.c/tcp_ut.c | 1 + 8 files changed, 62 insertions(+), 20 deletions(-) diff --git a/include/spdk/nvmf.h b/include/spdk/nvmf.h index fd00bb5e00..dcae3da576 100644 --- a/include/spdk/nvmf.h +++ b/include/spdk/nvmf.h @@ -1146,6 +1146,25 @@ spdk_nvmf_transport_poll_group_free_stat(struct spdk_nvmf_transport *transport, */ void spdk_nvmf_rdma_init_hooks(struct spdk_nvme_rdma_hooks *hooks); +/** + * Register the operations for a given transport type. + * + * This function should be invoked by referencing the macro + * SPDK_NVMF_TRANSPORT_REGISTER macro in the transport's .c file. + * + * \param ops The operations associated with an NVMe-oF transport. + */ +void spdk_nvmf_transport_register(const struct spdk_nvmf_transport_ops *ops); + +/* + * Macro used to register new transports. + */ +#define SPDK_NVMF_TRANSPORT_REGISTER(name, transport_ops) \ +static void __attribute__((constructor)) spdk_nvmf_transport_register_##name(void) \ +{ \ + spdk_nvmf_transport_register(transport_ops); \ +}\ + #ifdef __cplusplus } #endif diff --git a/lib/nvmf/fc.c b/lib/nvmf/fc.c index b78a3a1c52..d573d3e838 100644 --- a/lib/nvmf/fc.c +++ b/lib/nvmf/fc.c @@ -3950,5 +3950,6 @@ done: return err; } +SPDK_NVMF_TRANSPORT_REGISTER(fc, &spdk_nvmf_transport_fc); SPDK_LOG_REGISTER_COMPONENT("nvmf_fc_adm_api", SPDK_LOG_NVMF_FC_ADM_API); SPDK_LOG_REGISTER_COMPONENT("nvmf_fc", SPDK_LOG_NVMF_FC) diff --git a/lib/nvmf/rdma.c b/lib/nvmf/rdma.c index ee4db486e0..8781a90913 100644 --- a/lib/nvmf/rdma.c +++ b/lib/nvmf/rdma.c @@ -52,6 +52,7 @@ #include "spdk_internal/log.h" struct spdk_nvme_rdma_hooks g_nvmf_hooks = {}; +const struct spdk_nvmf_transport_ops spdk_nvmf_transport_rdma; /* RDMA Connection Resource Defaults @@ -4110,4 +4111,5 @@ const struct spdk_nvmf_transport_ops spdk_nvmf_transport_rdma = { .poll_group_free_stat = spdk_nvmf_rdma_poll_group_free_stat, }; +SPDK_NVMF_TRANSPORT_REGISTER(rdma, &spdk_nvmf_transport_rdma); SPDK_LOG_REGISTER_COMPONENT("rdma", SPDK_LOG_RDMA) diff --git a/lib/nvmf/tcp.c b/lib/nvmf/tcp.c index 0624089955..f54c7e114b 100644 --- a/lib/nvmf/tcp.c +++ b/lib/nvmf/tcp.c @@ -58,6 +58,8 @@ #define SPDK_NVMF_TCP_DEFAULT_MAX_SOCK_PRIORITY 6 #define SPDK_NVMF_TCP_RECV_BUF_SIZE_FACTOR 4 +const struct spdk_nvmf_transport_ops spdk_nvmf_transport_tcp; + /* spdk nvmf related structure */ enum spdk_nvmf_tcp_req_state { @@ -2772,4 +2774,5 @@ const struct spdk_nvmf_transport_ops spdk_nvmf_transport_tcp = { .qpair_set_sqsize = spdk_nvmf_tcp_qpair_set_sq_size, }; +SPDK_NVMF_TRANSPORT_REGISTER(tcp, &spdk_nvmf_transport_tcp); SPDK_LOG_REGISTER_COMPONENT("nvmf_tcp", SPDK_LOG_NVMF_TCP) diff --git a/lib/nvmf/transport.c b/lib/nvmf/transport.c index cd087b497e..3bffc7b0ae 100644 --- a/lib/nvmf/transport.c +++ b/lib/nvmf/transport.c @@ -42,31 +42,51 @@ #include "spdk/queue.h" #include "spdk/util.h" -static const struct spdk_nvmf_transport_ops *const g_transport_ops[] = { -#ifdef SPDK_CONFIG_RDMA - &spdk_nvmf_transport_rdma, -#endif - &spdk_nvmf_transport_tcp, -#ifdef SPDK_CONFIG_FC - &spdk_nvmf_transport_fc, -#endif +#define MAX_MEMPOOL_NAME_LENGTH 40 + +struct nvmf_transport_ops_list_element { + struct spdk_nvmf_transport_ops ops; + TAILQ_ENTRY(nvmf_transport_ops_list_element) link; }; -#define NUM_TRANSPORTS (SPDK_COUNTOF(g_transport_ops)) -#define MAX_MEMPOOL_NAME_LENGTH 40 +TAILQ_HEAD(nvmf_transport_ops_list, nvmf_transport_ops_list_element) +g_spdk_nvmf_transport_ops = TAILQ_HEAD_INITIALIZER(g_spdk_nvmf_transport_ops); static inline const struct spdk_nvmf_transport_ops * spdk_nvmf_get_transport_ops(const char *transport_name) { - size_t i; - for (i = 0; i != NUM_TRANSPORTS; i++) { - if (strcasecmp(transport_name, g_transport_ops[i]->name) == 0) { - return g_transport_ops[i]; + struct nvmf_transport_ops_list_element *ops; + TAILQ_FOREACH(ops, &g_spdk_nvmf_transport_ops, link) { + if (strcasecmp(transport_name, ops->ops.name) == 0) { + return &ops->ops; } } return NULL; } +void +spdk_nvmf_transport_register(const struct spdk_nvmf_transport_ops *ops) +{ + struct nvmf_transport_ops_list_element *new_ops; + + if (spdk_nvmf_get_transport_ops(ops->name) != NULL) { + SPDK_ERRLOG("Double registering nvmf transport type %s.\n", ops->name); + assert(false); + return; + } + + new_ops = calloc(1, sizeof(*new_ops)); + if (new_ops == NULL) { + SPDK_ERRLOG("Unable to allocate memory to register new transport type %s.\n", ops->name); + assert(false); + return; + } + + new_ops->ops = *ops; + + TAILQ_INSERT_TAIL(&g_spdk_nvmf_transport_ops, new_ops, link); +} + const struct spdk_nvmf_transport_opts * spdk_nvmf_get_transport_opts(struct spdk_nvmf_transport *transport) { diff --git a/lib/nvmf/transport.h b/lib/nvmf/transport.h index 0ec3f6d7cb..884bd13ce3 100644 --- a/lib/nvmf/transport.h +++ b/lib/nvmf/transport.h @@ -91,8 +91,7 @@ int spdk_nvmf_transport_qpair_get_listen_trid(struct spdk_nvmf_qpair *qpair, struct spdk_nvme_transport_id *trid); int spdk_nvmf_transport_qpair_set_sqsize(struct spdk_nvmf_qpair *qpair); -extern const struct spdk_nvmf_transport_ops spdk_nvmf_transport_rdma; -extern const struct spdk_nvmf_transport_ops spdk_nvmf_transport_tcp; -extern const struct spdk_nvmf_transport_ops spdk_nvmf_transport_fc; +bool spdk_nvmf_transport_opts_init(const char *transport_name, + struct spdk_nvmf_transport_opts *opts); #endif /* SPDK_NVMF_TRANSPORT_H */ diff --git a/test/unit/lib/nvmf/rdma.c/rdma_ut.c b/test/unit/lib/nvmf/rdma.c/rdma_ut.c index ff510a2641..41e4b3f130 100644 --- a/test/unit/lib/nvmf/rdma.c/rdma_ut.c +++ b/test/unit/lib/nvmf/rdma.c/rdma_ut.c @@ -53,9 +53,6 @@ struct spdk_nvmf_transport_opts g_rdma_ut_transport_opts = { .num_shared_buffers = SPDK_NVMF_RDMA_DEFAULT_NUM_SHARED_BUFFERS, }; -const struct spdk_nvmf_transport_ops spdk_nvmf_transport_tcp; -const struct spdk_nvmf_transport_ops spdk_nvmf_transport_fc; - SPDK_LOG_REGISTER_COMPONENT("nvmf", SPDK_LOG_NVMF) DEFINE_STUB(spdk_mem_map_set_translation, int, (struct spdk_mem_map *map, uint64_t vaddr, uint64_t size, uint64_t translation), 0); diff --git a/test/unit/lib/nvmf/tcp.c/tcp_ut.c b/test/unit/lib/nvmf/tcp.c/tcp_ut.c index f729d95e61..b5046d1b34 100644 --- a/test/unit/lib/nvmf/tcp.c/tcp_ut.c +++ b/test/unit/lib/nvmf/tcp.c/tcp_ut.c @@ -190,6 +190,7 @@ DEFINE_STUB_V(spdk_nvmf_ns_reservation_request, (void *ctx)); DEFINE_STUB_V(spdk_nvme_trid_populate_transport, (struct spdk_nvme_transport_id *trid, enum spdk_nvme_transport_type trtype)); +DEFINE_STUB_V(spdk_nvmf_transport_register, (const struct spdk_nvmf_transport_ops *ops)); struct spdk_trace_histories *g_trace_histories;