diff --git a/app/nvmf_tgt/conf.c b/app/nvmf_tgt/conf.c index d8a51f30b..d5bb7f956 100644 --- a/app/nvmf_tgt/conf.c +++ b/app/nvmf_tgt/conf.c @@ -790,10 +790,5 @@ spdk_nvmf_parse_subsystem_for_rpc(const char *name, } } - ret = spdk_nvmf_acceptor_init(); - if (ret < 0) { - SPDK_ERRLOG("spdk_nvmf_acceptor_start() failed\n"); - return -1; - } return 0; } diff --git a/app/nvmf_tgt/nvmf_tgt.c b/app/nvmf_tgt/nvmf_tgt.c index 624bfde5b..119fb4cf1 100644 --- a/app/nvmf_tgt/nvmf_tgt.c +++ b/app/nvmf_tgt/nvmf_tgt.c @@ -126,7 +126,6 @@ shutdown_subsystems(void) static void acceptor_poller_unregistered_event(struct spdk_event *event) { - spdk_nvmf_acceptor_fini(); spdk_nvmf_transport_fini(); shutdown_subsystems(); } @@ -333,12 +332,6 @@ spdk_nvmf_startup(spdk_event_t event) goto initialize_error; } - rc = spdk_nvmf_acceptor_init(); - if (rc < 0) { - SPDK_ERRLOG("spdk_nvmf_acceptor_start() failed\n"); - goto initialize_error; - } - spdk_poller_register(&g_acceptor_poller, acceptor_poll, NULL, g_spdk_nvmf_tgt_conf.acceptor_lcore, NULL, ACCEPT_TIMEOUT_US); diff --git a/lib/nvmf/rdma.c b/lib/nvmf/rdma.c index 6c8ddb8a8..f15ec3931 100644 --- a/lib/nvmf/rdma.c +++ b/lib/nvmf/rdma.c @@ -73,7 +73,6 @@ struct spdk_nvmf_rdma_request { uint8_t *buf; TAILQ_ENTRY(spdk_nvmf_rdma_request) link; - }; struct spdk_nvmf_rdma_conn { @@ -141,18 +140,19 @@ struct spdk_nvmf_rdma_listen_addr { char *traddr; char *trsvcid; struct rdma_cm_id *id; + struct ibv_device_attr attr; TAILQ_ENTRY(spdk_nvmf_rdma_listen_addr) link; }; struct spdk_nvmf_rdma { - struct rdma_event_channel *acceptor_event_channel; + struct rdma_event_channel *event_channel; - uint16_t max_queue_depth; - uint32_t max_io_size; - uint32_t in_capsule_data_size; - uint32_t num_devices_found; + pthread_mutex_t lock; + + uint16_t max_queue_depth; + uint32_t max_io_size; + uint32_t in_capsule_data_size; - pthread_mutex_t lock; TAILQ_HEAD(, spdk_nvmf_rdma_listen_addr) listen_addrs; }; @@ -621,7 +621,7 @@ static int nvmf_rdma_connect(struct rdma_cm_event *event) { struct spdk_nvmf_rdma_conn *rdma_conn = NULL; - struct ibv_device_attr ibdev_attr; + struct spdk_nvmf_rdma_listen_addr *addr; struct rdma_conn_param *rdma_param = NULL; struct rdma_conn_param ctrlr_event_data; const struct spdk_nvmf_rdma_request_private_data *private_data = NULL; @@ -631,8 +631,6 @@ nvmf_rdma_connect(struct rdma_cm_event *event) uint16_t max_rw_depth; int rc; - - /* Check to make sure we know about this rdma device */ if (event->id == NULL) { SPDK_ERRLOG("connect request: missing cm_id\n"); goto err0; @@ -645,6 +643,10 @@ nvmf_rdma_connect(struct rdma_cm_event *event) SPDK_TRACELOG(SPDK_TRACE_RDMA, "Connect Recv on fabric intf name %s, dev_name %s\n", event->id->verbs->device->name, event->id->verbs->device->dev_name); + addr = event->listen_id->context; + SPDK_TRACELOG(SPDK_TRACE_RDMA, "Listen Id was %p with verbs %p. ListenAddr: %p\n", + event->listen_id, event->listen_id->verbs, addr); + /* Figure out the supported queue depth. This is a multi-step process * that takes into account hardware maximums, host provided values, * and our target's internal memory limits */ @@ -657,17 +659,11 @@ nvmf_rdma_connect(struct rdma_cm_event *event) SPDK_TRACELOG(SPDK_TRACE_RDMA, "Target Max Queue Depth: %d\n", g_rdma.max_queue_depth); /* Next check the local NIC's hardware limitations */ - rc = ibv_query_device(event->id->verbs, &ibdev_attr); - if (rc) { - SPDK_ERRLOG("Failed to query RDMA device attributes\n"); - sts = SPDK_NVME_SC_INTERNAL_DEVICE_ERROR; - goto err1; - } SPDK_TRACELOG(SPDK_TRACE_RDMA, "Local NIC Max Send/Recv Queue Depth: %d Max Read/Write Queue Depth: %d\n", - ibdev_attr.max_qp_wr, ibdev_attr.max_qp_rd_atom); - max_queue_depth = nvmf_min(max_queue_depth, ibdev_attr.max_qp_wr); - max_rw_depth = nvmf_min(max_rw_depth, ibdev_attr.max_qp_rd_atom); + addr->attr.max_qp_wr, addr->attr.max_qp_rd_atom); + max_queue_depth = nvmf_min(max_queue_depth, addr->attr.max_qp_wr); + max_rw_depth = nvmf_min(max_rw_depth, addr->attr.max_qp_rd_atom); /* Next check the remote NIC's hardware limitations */ rdma_param = &event->param.conn; @@ -910,7 +906,7 @@ spdk_nvmf_rdma_acceptor_poll(void) int rc; struct spdk_nvmf_rdma_conn *rdma_conn, *tmp; - if (g_rdma.acceptor_event_channel == NULL) { + if (g_rdma.event_channel == NULL) { return; } @@ -929,7 +925,7 @@ spdk_nvmf_rdma_acceptor_poll(void) } while (1) { - rc = rdma_get_cm_event(g_rdma.acceptor_event_channel, &event); + rc = rdma_get_cm_event(g_rdma.event_channel, &event); if (rc == 0) { SPDK_TRACELOG(SPDK_TRACE_RDMA, "Acceptor Event: %s\n", CM_EVENT_STR[event->event]); @@ -968,92 +964,6 @@ spdk_nvmf_rdma_acceptor_poll(void) } } -static int -spdk_nvmf_rdma_acceptor_init(void) -{ - struct sockaddr_in addr; - int rc; - struct spdk_nvmf_rdma_listen_addr *listen_addr, *tmp; - - if (g_rdma.num_devices_found == 0) { - return 0; - } - if (g_rdma.acceptor_event_channel == NULL) { - /* create an event channel with rdmacm to receive - connection oriented requests and notifications */ - g_rdma.acceptor_event_channel = rdma_create_event_channel(); - if (g_rdma.acceptor_event_channel == NULL) { - SPDK_ERRLOG("rdma_create_event_channel() failed\n"); - return -1; - } - rc = fcntl(g_rdma.acceptor_event_channel->fd, F_SETFL, O_NONBLOCK); - if (rc < 0) { - SPDK_ERRLOG("fcntl to set fd to non-blocking failed\n"); - goto create_id_error; - } - } - - pthread_mutex_lock(&g_rdma.lock); - TAILQ_FOREACH_SAFE(listen_addr, &g_rdma.listen_addrs, link, tmp) { - if (listen_addr->id) { - continue; - } - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = inet_addr(listen_addr->traddr); - addr.sin_port = htons((uint16_t)strtoul(listen_addr->trsvcid, NULL, 10)); - - rc = rdma_create_id(g_rdma.acceptor_event_channel, &listen_addr->id, NULL, - RDMA_PS_TCP); - if (rc < 0) { - SPDK_ERRLOG("rdma_create_id() failed\n"); - goto listen_error; - } - - rc = rdma_bind_addr(listen_addr->id, (struct sockaddr *)&addr); - if (rc < 0) { - SPDK_ERRLOG("rdma_bind_addr() failed\n"); - goto listen_error; - } - - rc = rdma_listen(listen_addr->id, 10); /* 10 = backlog */ - if (rc < 0) { - SPDK_ERRLOG("rdma_listen() failed\n"); - goto listen_error; - } - SPDK_NOTICELOG("*** NVMf Target Listening on %s port %d ***\n", - listen_addr->traddr, ntohs(rdma_get_src_port(listen_addr->id))); - } - - pthread_mutex_unlock(&g_rdma.lock); - return 0; - -listen_error: - TAILQ_FOREACH_SAFE(listen_addr, &g_rdma.listen_addrs, link, tmp) { - if (listen_addr->id) { - rdma_destroy_id(listen_addr->id); - } - } - pthread_mutex_unlock(&g_rdma.lock); - -create_id_error: - rdma_destroy_event_channel(g_rdma.acceptor_event_channel); - return -1; -} - -static void -spdk_nvmf_rdma_acceptor_fini(void) -{ - struct spdk_nvmf_rdma_listen_addr *listen_addr, *tmp; - - pthread_mutex_lock(&g_rdma.lock); - TAILQ_FOREACH_SAFE(listen_addr, &g_rdma.listen_addrs, link, tmp) { - TAILQ_REMOVE(&g_rdma.listen_addrs, listen_addr, link); - free(listen_addr); - } - pthread_mutex_unlock(&g_rdma.lock); -} - static int spdk_nvmf_rdma_session_init(struct spdk_nvmf_session *session, struct spdk_nvmf_conn *conn) { @@ -1128,84 +1038,20 @@ static int spdk_nvmf_rdma_init(uint16_t max_queue_depth, uint32_t max_io_size, uint32_t in_capsule_data_size) { - struct ibv_device **dev_list; - struct ibv_context *ibdev_ctx = NULL; - struct ibv_device_attr ibdev_attr; - int num_of_rdma_devices; - int num_devices_found = 0; - int i, ret; - SPDK_NOTICELOG("*** RDMA Transport Init ***\n"); - dev_list = ibv_get_device_list(&num_of_rdma_devices); - if (!dev_list) { - SPDK_NOTICELOG("No RDMA verbs devices found\n"); - return 0; - } - SPDK_TRACELOG(SPDK_TRACE_RDMA, "%d RDMA verbs device(s) discovered\n", num_of_rdma_devices); - - /* Look through the list of devices for one we support */ - for (i = 0; i < num_of_rdma_devices; i++) { - SPDK_TRACELOG(SPDK_TRACE_RDMA, " RDMA Device %d:\n", i); - SPDK_TRACELOG(SPDK_TRACE_RDMA, " Node type: %d\n", (int)dev_list[i]->node_type); - SPDK_TRACELOG(SPDK_TRACE_RDMA, " Transport type: %d\n", (int)dev_list[i]->transport_type); - SPDK_TRACELOG(SPDK_TRACE_RDMA, " Name: %s\n", dev_list[i]->name); - SPDK_TRACELOG(SPDK_TRACE_RDMA, " Device Name: %s\n", dev_list[i]->dev_name); - - ibdev_ctx = ibv_open_device(dev_list[i]); - if (!ibdev_ctx) { - SPDK_ERRLOG(" No rdma context returned for device %d\n", i); - continue; - } - - ret = ibv_query_device(ibdev_ctx, &ibdev_attr); - if (ret) { - SPDK_ERRLOG(" Failed on query for device %d\n", i); - ibv_close_device(ibdev_ctx); - continue; - } - - /* display device specific attributes */ - SPDK_TRACELOG(SPDK_TRACE_RDMA, " RDMA Device Attributes:\n"); - SPDK_TRACELOG(SPDK_TRACE_RDMA, " Max MR Size: 0x%llx\n", (long long int)ibdev_attr.max_mr_size); - SPDK_TRACELOG(SPDK_TRACE_RDMA, " Page Size Cap: 0x%llx\n", - (long long int)ibdev_attr.page_size_cap); - SPDK_TRACELOG(SPDK_TRACE_RDMA, " Max QPs: 0x%x\n", (int)ibdev_attr.max_qp); - SPDK_TRACELOG(SPDK_TRACE_RDMA, " Max QP WRs: 0x%x\n", (int)ibdev_attr.max_qp_wr); - SPDK_TRACELOG(SPDK_TRACE_RDMA, " Max SGE: 0x%x\n", (int)ibdev_attr.max_sge); - SPDK_TRACELOG(SPDK_TRACE_RDMA, " Max CQs: 0x%x\n", (int)ibdev_attr.max_cq); - SPDK_TRACELOG(SPDK_TRACE_RDMA, " Max CQE per CQ: 0x%x\n", (int)ibdev_attr.max_cqe); - SPDK_TRACELOG(SPDK_TRACE_RDMA, " Max MR: 0x%x\n", (int)ibdev_attr.max_mr); - SPDK_TRACELOG(SPDK_TRACE_RDMA, " Max PD: 0x%x\n", (int)ibdev_attr.max_pd); - SPDK_TRACELOG(SPDK_TRACE_RDMA, " Max QP RD Atom: 0x%x\n", (int)ibdev_attr.max_qp_rd_atom); - SPDK_TRACELOG(SPDK_TRACE_RDMA, " Max QP Init RD Atom: 0x%x\n", - (int)ibdev_attr.max_qp_init_rd_atom); - SPDK_TRACELOG(SPDK_TRACE_RDMA, " Max Res RD Atom: 0x%x\n", (int)ibdev_attr.max_res_rd_atom); - SPDK_TRACELOG(SPDK_TRACE_RDMA, " Max EE: 0x%x\n", (int)ibdev_attr.max_ee); - SPDK_TRACELOG(SPDK_TRACE_RDMA, " Max SRQ: 0x%x\n", (int)ibdev_attr.max_srq); - SPDK_TRACELOG(SPDK_TRACE_RDMA, " Max SRQ WR: 0x%x\n", (int)ibdev_attr.max_srq_wr); - SPDK_TRACELOG(SPDK_TRACE_RDMA, " Max SRQ SGE: 0x%x\n", (int)ibdev_attr.max_srq_sge); - SPDK_TRACELOG(SPDK_TRACE_RDMA, " Max PKeys: 0x%x\n", (int)ibdev_attr.max_pkeys); - SPDK_TRACELOG(SPDK_TRACE_RDMA, " Phys Port Cnt: %d\n", (int)ibdev_attr.phys_port_cnt); - - num_devices_found++; - } - - ibv_free_device_list(dev_list); - SPDK_TRACELOG(SPDK_TRACE_RDMA, " %d Fabric Intf(s) active\n", num_devices_found); - g_rdma.max_queue_depth = max_queue_depth; g_rdma.max_io_size = max_io_size; g_rdma.in_capsule_data_size = in_capsule_data_size; - g_rdma.num_devices_found = num_devices_found; - return num_devices_found; + return 0; } static int spdk_nvmf_rdma_fini(void) { - /* Nothing to do */ + rdma_destroy_event_channel(g_rdma.event_channel); + return 0; } @@ -1424,16 +1270,34 @@ spdk_nvmf_rdma_discover(struct spdk_nvmf_listen_addr *listen_addr, static int spdk_nvmf_rdma_listen(struct spdk_nvmf_listen_addr *listen_addr) { - struct spdk_nvmf_rdma_listen_addr *addr, *tmp; + struct spdk_nvmf_rdma_listen_addr *addr; + struct sockaddr_in saddr; + int rc; pthread_mutex_lock(&g_rdma.lock); - TAILQ_FOREACH_SAFE(addr, &g_rdma.listen_addrs, link, tmp) { + TAILQ_FOREACH(addr, &g_rdma.listen_addrs, link) { if ((!strcasecmp(addr->traddr, listen_addr->traddr)) && (!strcasecmp(addr->trsvcid, listen_addr->trsvcid))) { + /* Already listening at this address */ pthread_mutex_unlock(&g_rdma.lock); return 0; } } + if (g_rdma.event_channel == NULL) { + g_rdma.event_channel = rdma_create_event_channel(); + if (g_rdma.event_channel == NULL) { + SPDK_ERRLOG("rdma_create_event_channel() failed\n"); + pthread_mutex_unlock(&g_rdma.lock); + return -1; + } + + rc = fcntl(g_rdma.event_channel->fd, F_SETFL, O_NONBLOCK); + if (rc < 0) { + SPDK_ERRLOG("fcntl to set fd to non-blocking failed\n"); + pthread_mutex_unlock(&g_rdma.lock); + return -1; + } + } addr = calloc(1, sizeof(*addr)); if (!addr) { @@ -1444,9 +1308,51 @@ spdk_nvmf_rdma_listen(struct spdk_nvmf_listen_addr *listen_addr) addr->traddr = listen_addr->traddr; addr->trsvcid = listen_addr->trsvcid; + rc = rdma_create_id(g_rdma.event_channel, &addr->id, addr, RDMA_PS_TCP); + if (rc < 0) { + SPDK_ERRLOG("rdma_create_id() failed\n"); + free(addr); + pthread_mutex_unlock(&g_rdma.lock); + return -1; + } + + memset(&saddr, 0, sizeof(saddr)); + saddr.sin_family = AF_INET; + saddr.sin_addr.s_addr = inet_addr(addr->traddr); + saddr.sin_port = htons((uint16_t)strtoul(addr->trsvcid, NULL, 10)); + rc = rdma_bind_addr(addr->id, (struct sockaddr *)&saddr); + if (rc < 0) { + SPDK_ERRLOG("rdma_bind_addr() failed\n"); + rdma_destroy_id(addr->id); + free(addr); + pthread_mutex_unlock(&g_rdma.lock); + return -1; + } + + rc = rdma_listen(addr->id, 10); /* 10 = backlog */ + if (rc < 0) { + SPDK_ERRLOG("rdma_listen() failed\n"); + rdma_destroy_id(addr->id); + free(addr); + pthread_mutex_unlock(&g_rdma.lock); + return -1; + } + + rc = ibv_query_device(addr->id->verbs, &addr->attr); + if (rc < 0) { + SPDK_ERRLOG("Failed to query RDMA device attributes.\n"); + rdma_destroy_id(addr->id); + free(addr); + pthread_mutex_unlock(&g_rdma.lock); + return -1; + } + TAILQ_INSERT_TAIL(&g_rdma.listen_addrs, addr, link); pthread_mutex_unlock(&g_rdma.lock); + SPDK_NOTICELOG("*** NVMf Target Listening on %s port %d ***\n", + addr->traddr, ntohs(rdma_get_src_port(addr->id))); + return 0; } @@ -1455,9 +1361,7 @@ const struct spdk_nvmf_transport spdk_nvmf_transport_rdma = { .transport_init = spdk_nvmf_rdma_init, .transport_fini = spdk_nvmf_rdma_fini, - .acceptor_init = spdk_nvmf_rdma_acceptor_init, .acceptor_poll = spdk_nvmf_rdma_acceptor_poll, - .acceptor_fini = spdk_nvmf_rdma_acceptor_fini, .listen_addr_add = spdk_nvmf_rdma_listen, .listen_addr_discover = spdk_nvmf_rdma_discover, diff --git a/lib/nvmf/transport.c b/lib/nvmf/transport.c index e1e88e888..26776587c 100644 --- a/lib/nvmf/transport.c +++ b/lib/nvmf/transport.c @@ -84,20 +84,6 @@ spdk_nvmf_transport_fini(void) return count; } -int -spdk_nvmf_acceptor_init(void) -{ - size_t i; - - for (i = 0; i != NUM_TRANSPORTS; i++) { - if (g_transports[i]->acceptor_init() < 0) { - return -1; - } - } - - return 0; -} - void spdk_nvmf_acceptor_poll(void) { @@ -108,16 +94,6 @@ spdk_nvmf_acceptor_poll(void) } } -void -spdk_nvmf_acceptor_fini(void) -{ - size_t i; - - for (i = 0; i != NUM_TRANSPORTS; i++) { - g_transports[i]->acceptor_fini(); - } -} - const struct spdk_nvmf_transport * spdk_nvmf_transport_get(const char *name) { diff --git a/lib/nvmf/transport.h b/lib/nvmf/transport.h index bb5fb741a..4efbe189e 100644 --- a/lib/nvmf/transport.h +++ b/lib/nvmf/transport.h @@ -60,21 +60,11 @@ struct spdk_nvmf_transport { */ int (*transport_fini)(void); - /** - * Start accepting connections on the transport. - */ - int (*acceptor_init)(void); - /** * Check for new connections on the transport. */ void (*acceptor_poll)(void); - /** - * Stop accepting connections on the transport. - */ - void (*acceptor_fini)(void); - /** * Instruct the acceptor to listen on the address provided. This * may be called multiple times. @@ -126,9 +116,7 @@ int spdk_nvmf_transport_init(void); int spdk_nvmf_transport_fini(void); const struct spdk_nvmf_transport *spdk_nvmf_transport_get(const char *name); -int spdk_nvmf_acceptor_init(void); void spdk_nvmf_acceptor_poll(void); -void spdk_nvmf_acceptor_fini(void); extern const struct spdk_nvmf_transport spdk_nvmf_transport_rdma;