nvmf: remove redundant trid obj copy

It is memory optimisation as transport id is 'heavy'. As a side effect
simpler handling of listen and stop_listen on transport specific layer.

Signed-off-by: Jacek Kalwas <jacek.kalwas@intel.com>
Change-Id: I4e9d0e0c5eee2d570ec4ac9079270c32d5afb8db
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/626
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
This commit is contained in:
Jacek Kalwas 2020-02-15 07:19:24 +01:00 committed by Tomasz Zawadzki
parent 6913a864fb
commit 6d8f1fc648
9 changed files with 120 additions and 106 deletions

View File

@ -159,6 +159,13 @@ struct spdk_nvmf_poll_group {
struct spdk_nvmf_poll_group_stat stat; struct spdk_nvmf_poll_group_stat stat;
}; };
struct spdk_nvmf_listener {
struct spdk_nvme_transport_id trid;
uint32_t ref;
TAILQ_ENTRY(spdk_nvmf_listener) link;
};
struct spdk_nvmf_transport { struct spdk_nvmf_transport {
struct spdk_nvmf_tgt *tgt; struct spdk_nvmf_tgt *tgt;
const struct spdk_nvmf_transport_ops *ops; const struct spdk_nvmf_transport_ops *ops;
@ -167,6 +174,7 @@ struct spdk_nvmf_transport {
/* A mempool for transport related data transfers */ /* A mempool for transport related data transfers */
struct spdk_mempool *data_buf_pool; struct spdk_mempool *data_buf_pool;
TAILQ_HEAD(, spdk_nvmf_listener) listeners;
TAILQ_ENTRY(spdk_nvmf_transport) link; TAILQ_ENTRY(spdk_nvmf_transport) link;
}; };
@ -208,8 +216,8 @@ struct spdk_nvmf_transport_ops {
/** /**
* Stop accepting new connections at the given address. * Stop accepting new connections at the given address.
*/ */
int (*stop_listen)(struct spdk_nvmf_transport *transport, void (*stop_listen)(struct spdk_nvmf_transport *transport,
const struct spdk_nvme_transport_id *trid); const struct spdk_nvme_transport_id *trid);
/** /**
* Check for new connections on the transport. * Check for new connections on the transport.

View File

@ -106,7 +106,7 @@ nvmf_generate_discovery_log(struct spdk_nvmf_tgt *tgt, const char *hostnqn, size
entry->subtype = subsystem->subtype; entry->subtype = subsystem->subtype;
snprintf(entry->subnqn, sizeof(entry->subnqn), "%s", subsystem->subnqn); snprintf(entry->subnqn, sizeof(entry->subnqn), "%s", subsystem->subnqn);
spdk_nvmf_transport_listener_discover(listener->transport, &listener->trid, entry); spdk_nvmf_transport_listener_discover(listener->transport, listener->trid, entry);
numrec++; numrec++;
} }

View File

@ -1930,11 +1930,10 @@ nvmf_fc_listen(struct spdk_nvmf_transport *transport,
return 0; return 0;
} }
static int static void
nvmf_fc_stop_listen(struct spdk_nvmf_transport *transport, nvmf_fc_stop_listen(struct spdk_nvmf_transport *transport,
const struct spdk_nvme_transport_id *_trid) const struct spdk_nvme_transport_id *_trid)
{ {
return 0;
} }
static void static void

View File

@ -81,7 +81,7 @@ struct spdk_nvmf_host {
}; };
struct spdk_nvmf_subsystem_listener { struct spdk_nvmf_subsystem_listener {
struct spdk_nvme_transport_id trid; struct spdk_nvme_transport_id *trid;
struct spdk_nvmf_transport *transport; struct spdk_nvmf_transport *transport;
TAILQ_ENTRY(spdk_nvmf_subsystem_listener) link; TAILQ_ENTRY(spdk_nvmf_subsystem_listener) link;
}; };
@ -318,6 +318,9 @@ struct spdk_nvmf_ctrlr *spdk_nvmf_subsystem_get_ctrlr(struct spdk_nvmf_subsystem
struct spdk_nvmf_subsystem_listener *spdk_nvmf_subsystem_find_listener( struct spdk_nvmf_subsystem_listener *spdk_nvmf_subsystem_find_listener(
struct spdk_nvmf_subsystem *subsystem, struct spdk_nvmf_subsystem *subsystem,
const struct spdk_nvme_transport_id *trid); const struct spdk_nvme_transport_id *trid);
struct spdk_nvmf_listener *spdk_nvmf_transport_find_listener(
struct spdk_nvmf_transport *transport,
const struct spdk_nvme_transport_id *trid);
int spdk_nvmf_ctrlr_async_event_ns_notice(struct spdk_nvmf_ctrlr *ctrlr); int spdk_nvmf_ctrlr_async_event_ns_notice(struct spdk_nvmf_ctrlr *ctrlr);
void spdk_nvmf_ctrlr_async_event_reservation_notification(struct spdk_nvmf_ctrlr *ctrlr); void spdk_nvmf_ctrlr_async_event_reservation_notification(struct spdk_nvmf_ctrlr *ctrlr);

View File

@ -489,10 +489,9 @@ struct spdk_nvmf_rdma_device {
}; };
struct spdk_nvmf_rdma_port { struct spdk_nvmf_rdma_port {
struct spdk_nvme_transport_id trid; const struct spdk_nvme_transport_id *trid;
struct rdma_cm_id *id; struct rdma_cm_id *id;
struct spdk_nvmf_rdma_device *device; struct spdk_nvmf_rdma_device *device;
uint32_t ref;
TAILQ_ENTRY(spdk_nvmf_rdma_port) link; TAILQ_ENTRY(spdk_nvmf_rdma_port) link;
}; };
@ -2660,12 +2659,6 @@ spdk_nvmf_rdma_listen(struct spdk_nvmf_transport *transport,
assert(rtransport->event_channel != NULL); assert(rtransport->event_channel != NULL);
pthread_mutex_lock(&rtransport->lock); pthread_mutex_lock(&rtransport->lock);
TAILQ_FOREACH(port, &rtransport->ports, link) {
if (spdk_nvme_transport_id_compare(&port->trid, trid) == 0) {
goto success;
}
}
port = calloc(1, sizeof(*port)); port = calloc(1, sizeof(*port));
if (!port) { if (!port) {
SPDK_ERRLOG("Port allocation failed\n"); SPDK_ERRLOG("Port allocation failed\n");
@ -2673,15 +2666,9 @@ spdk_nvmf_rdma_listen(struct spdk_nvmf_transport *transport,
return -ENOMEM; return -ENOMEM;
} }
/* Selectively copy the trid. Things like NQN don't matter here - that port->trid = trid;
* mapping is enforced elsewhere.
*/
spdk_nvme_trid_populate_transport(&port->trid, SPDK_NVME_TRANSPORT_RDMA);
port->trid.adrfam = trid->adrfam;
snprintf(port->trid.traddr, sizeof(port->trid.traddr), "%s", trid->traddr);
snprintf(port->trid.trsvcid, sizeof(port->trid.trsvcid), "%s", trid->trsvcid);
switch (port->trid.adrfam) { switch (trid->adrfam) {
case SPDK_NVMF_ADRFAM_IPV4: case SPDK_NVMF_ADRFAM_IPV4:
family = AF_INET; family = AF_INET;
break; break;
@ -2689,7 +2676,7 @@ spdk_nvmf_rdma_listen(struct spdk_nvmf_transport *transport,
family = AF_INET6; family = AF_INET6;
break; break;
default: default:
SPDK_ERRLOG("Unhandled ADRFAM %d\n", port->trid.adrfam); SPDK_ERRLOG("Unhandled ADRFAM %d\n", trid->adrfam);
free(port); free(port);
pthread_mutex_unlock(&rtransport->lock); pthread_mutex_unlock(&rtransport->lock);
return -EINVAL; return -EINVAL;
@ -2701,7 +2688,7 @@ spdk_nvmf_rdma_listen(struct spdk_nvmf_transport *transport,
hints.ai_socktype = SOCK_STREAM; hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = 0; hints.ai_protocol = 0;
rc = getaddrinfo(port->trid.traddr, port->trid.trsvcid, &hints, &res); rc = getaddrinfo(trid->traddr, trid->trsvcid, &hints, &res);
if (rc) { if (rc) {
SPDK_ERRLOG("getaddrinfo failed: %s (%d)\n", gai_strerror(rc), rc); SPDK_ERRLOG("getaddrinfo failed: %s (%d)\n", gai_strerror(rc), rc);
free(port); free(port);
@ -2765,50 +2752,35 @@ spdk_nvmf_rdma_listen(struct spdk_nvmf_transport *transport,
trid->traddr, trid->trsvcid); trid->traddr, trid->trsvcid);
TAILQ_INSERT_TAIL(&rtransport->ports, port, link); TAILQ_INSERT_TAIL(&rtransport->ports, port, link);
success:
port->ref++;
pthread_mutex_unlock(&rtransport->lock); pthread_mutex_unlock(&rtransport->lock);
if (cb_fn != NULL) { if (cb_fn != NULL) {
cb_fn(cb_arg, 0); cb_fn(cb_arg, 0);
} }
return 0; return 0;
} }
static int static void
spdk_nvmf_rdma_stop_listen(struct spdk_nvmf_transport *transport, spdk_nvmf_rdma_stop_listen(struct spdk_nvmf_transport *transport,
const struct spdk_nvme_transport_id *_trid) const struct spdk_nvme_transport_id *trid)
{ {
struct spdk_nvmf_rdma_transport *rtransport; struct spdk_nvmf_rdma_transport *rtransport;
struct spdk_nvmf_rdma_port *port, *tmp; struct spdk_nvmf_rdma_port *port, *tmp;
struct spdk_nvme_transport_id trid = {};
rtransport = SPDK_CONTAINEROF(transport, struct spdk_nvmf_rdma_transport, transport); rtransport = SPDK_CONTAINEROF(transport, struct spdk_nvmf_rdma_transport, transport);
/* Selectively copy the trid. Things like NQN don't matter here - that
* mapping is enforced elsewhere.
*/
spdk_nvme_trid_populate_transport(&trid, SPDK_NVME_TRANSPORT_RDMA);
trid.adrfam = _trid->adrfam;
snprintf(trid.traddr, sizeof(port->trid.traddr), "%s", _trid->traddr);
snprintf(trid.trsvcid, sizeof(port->trid.trsvcid), "%s", _trid->trsvcid);
pthread_mutex_lock(&rtransport->lock); pthread_mutex_lock(&rtransport->lock);
TAILQ_FOREACH_SAFE(port, &rtransport->ports, link, tmp) { TAILQ_FOREACH_SAFE(port, &rtransport->ports, link, tmp) {
if (spdk_nvme_transport_id_compare(&port->trid, &trid) == 0) { if (spdk_nvme_transport_id_compare(port->trid, trid) == 0) {
assert(port->ref > 0); TAILQ_REMOVE(&rtransport->ports, port, link);
port->ref--; rdma_destroy_id(port->id);
if (port->ref == 0) { free(port);
TAILQ_REMOVE(&rtransport->ports, port, link);
rdma_destroy_id(port->id);
free(port);
}
break; break;
} }
} }
pthread_mutex_unlock(&rtransport->lock); pthread_mutex_unlock(&rtransport->lock);
return 0;
} }
static void static void
@ -3005,33 +2977,29 @@ static bool
nvmf_rdma_handle_cm_event_addr_change(struct spdk_nvmf_transport *transport, nvmf_rdma_handle_cm_event_addr_change(struct spdk_nvmf_transport *transport,
struct rdma_cm_event *event) struct rdma_cm_event *event)
{ {
struct spdk_nvme_transport_id trid; const struct spdk_nvme_transport_id *trid;
struct spdk_nvmf_rdma_port *port; struct spdk_nvmf_rdma_port *port;
struct spdk_nvmf_rdma_transport *rtransport; struct spdk_nvmf_rdma_transport *rtransport;
uint32_t ref, i;
bool event_acked = false; bool event_acked = false;
rtransport = SPDK_CONTAINEROF(transport, struct spdk_nvmf_rdma_transport, transport); rtransport = SPDK_CONTAINEROF(transport, struct spdk_nvmf_rdma_transport, transport);
TAILQ_FOREACH(port, &rtransport->ports, link) { TAILQ_FOREACH(port, &rtransport->ports, link) {
if (port->id == event->id) { if (port->id == event->id) {
SPDK_ERRLOG("ADDR_CHANGE: IP %s:%s migrated\n", port->trid.traddr, port->trid.trsvcid); SPDK_ERRLOG("ADDR_CHANGE: IP %s:%s migrated\n", port->trid->traddr, port->trid->trsvcid);
rdma_ack_cm_event(event); rdma_ack_cm_event(event);
event_acked = true; event_acked = true;
trid = port->trid; trid = port->trid;
ref = port->ref;
break; break;
} }
} }
if (event_acked) { if (event_acked) {
nvmf_rdma_disconnect_qpairs_on_port(rtransport, port); nvmf_rdma_disconnect_qpairs_on_port(rtransport, port);
for (i = 0; i < ref; i++) { spdk_nvmf_rdma_stop_listen(transport, trid);
spdk_nvmf_rdma_stop_listen(transport, &trid); spdk_nvmf_rdma_listen(transport, trid, NULL, NULL);
}
for (i = 0; i < ref; i++) {
spdk_nvmf_rdma_listen(transport, &trid, NULL, NULL);
}
} }
return event_acked; return event_acked;
} }
@ -3041,20 +3009,18 @@ nvmf_rdma_handle_cm_event_port_removal(struct spdk_nvmf_transport *transport,
{ {
struct spdk_nvmf_rdma_port *port; struct spdk_nvmf_rdma_port *port;
struct spdk_nvmf_rdma_transport *rtransport; struct spdk_nvmf_rdma_transport *rtransport;
uint32_t ref, i;
port = event->id->context; port = event->id->context;
rtransport = SPDK_CONTAINEROF(transport, struct spdk_nvmf_rdma_transport, transport); rtransport = SPDK_CONTAINEROF(transport, struct spdk_nvmf_rdma_transport, transport);
ref = port->ref;
SPDK_NOTICELOG("Port %s:%s is being removed\n", port->trid.traddr, port->trid.trsvcid); SPDK_NOTICELOG("Port %s:%s is being removed\n", port->trid->traddr, port->trid->trsvcid);
nvmf_rdma_disconnect_qpairs_on_port(rtransport, port); nvmf_rdma_disconnect_qpairs_on_port(rtransport, port);
rdma_ack_cm_event(event); rdma_ack_cm_event(event);
for (i = 0; i < ref; i++) { while (spdk_nvmf_transport_stop_listen(transport, port->trid) == 0) {
spdk_nvmf_rdma_stop_listen(transport, &port->trid); ;
} }
} }

View File

@ -320,9 +320,9 @@ _nvmf_subsystem_remove_listener(struct spdk_nvmf_subsystem *subsystem,
struct spdk_nvmf_transport *transport; struct spdk_nvmf_transport *transport;
if (stop) { if (stop) {
transport = spdk_nvmf_tgt_get_transport(subsystem->tgt, listener->trid.trstring); transport = spdk_nvmf_tgt_get_transport(subsystem->tgt, listener->trid->trstring);
if (transport != NULL) { if (transport != NULL) {
spdk_nvmf_transport_stop_listen(transport, &listener->trid); spdk_nvmf_transport_stop_listen(transport, listener->trid);
} }
} }
@ -739,7 +739,7 @@ spdk_nvmf_subsystem_find_listener(struct spdk_nvmf_subsystem *subsystem,
struct spdk_nvmf_subsystem_listener *listener; struct spdk_nvmf_subsystem_listener *listener;
TAILQ_FOREACH(listener, &subsystem->listeners, link) { TAILQ_FOREACH(listener, &subsystem->listeners, link) {
if (spdk_nvme_transport_id_compare(&listener->trid, trid) == 0) { if (spdk_nvme_transport_id_compare(listener->trid, trid) == 0) {
return listener; return listener;
} }
} }
@ -753,6 +753,7 @@ spdk_nvmf_subsystem_add_listener(struct spdk_nvmf_subsystem *subsystem,
{ {
struct spdk_nvmf_transport *transport; struct spdk_nvmf_transport *transport;
struct spdk_nvmf_subsystem_listener *listener; struct spdk_nvmf_subsystem_listener *listener;
struct spdk_nvmf_listener *tr_listener;
if (!(subsystem->state == SPDK_NVMF_SUBSYSTEM_INACTIVE || if (!(subsystem->state == SPDK_NVMF_SUBSYSTEM_INACTIVE ||
subsystem->state == SPDK_NVMF_SUBSYSTEM_PAUSED)) { subsystem->state == SPDK_NVMF_SUBSYSTEM_PAUSED)) {
@ -770,12 +771,18 @@ spdk_nvmf_subsystem_add_listener(struct spdk_nvmf_subsystem *subsystem,
return -EINVAL; return -EINVAL;
} }
tr_listener = spdk_nvmf_transport_find_listener(transport, trid);
if (!tr_listener) {
SPDK_ERRLOG("Cannot find transport listener for %s\n", trid->traddr);
return -EINVAL;
}
listener = calloc(1, sizeof(*listener)); listener = calloc(1, sizeof(*listener));
if (!listener) { if (!listener) {
return -ENOMEM; return -ENOMEM;
} }
listener->trid = *trid; listener->trid = &tr_listener->trid;
listener->transport = transport; listener->transport = transport;
TAILQ_INSERT_HEAD(&subsystem->listeners, listener, link); TAILQ_INSERT_HEAD(&subsystem->listeners, listener, link);
@ -827,7 +834,7 @@ spdk_nvmf_subsystem_listener_allowed(struct spdk_nvmf_subsystem *subsystem,
} }
TAILQ_FOREACH(listener, &subsystem->listeners, link) { TAILQ_FOREACH(listener, &subsystem->listeners, link) {
if (spdk_nvme_transport_id_compare(&listener->trid, trid) == 0) { if (spdk_nvme_transport_id_compare(listener->trid, trid) == 0) {
return true; return true;
} }
} }
@ -851,7 +858,7 @@ spdk_nvmf_subsystem_get_next_listener(struct spdk_nvmf_subsystem *subsystem,
const struct spdk_nvme_transport_id * const struct spdk_nvme_transport_id *
spdk_nvmf_subsystem_listener_get_trid(struct spdk_nvmf_subsystem_listener *listener) spdk_nvmf_subsystem_listener_get_trid(struct spdk_nvmf_subsystem_listener *listener)
{ {
return &listener->trid; return listener->trid;
} }
void void

View File

@ -267,9 +267,8 @@ struct spdk_nvmf_tcp_poll_group {
}; };
struct spdk_nvmf_tcp_port { struct spdk_nvmf_tcp_port {
struct spdk_nvme_transport_id trid; const struct spdk_nvme_transport_id *trid;
struct spdk_sock *listen_sock; struct spdk_sock *listen_sock;
uint32_t ref;
TAILQ_ENTRY(spdk_nvmf_tcp_port) link; TAILQ_ENTRY(spdk_nvmf_tcp_port) link;
}; };
@ -588,7 +587,7 @@ _spdk_nvmf_tcp_find_port(struct spdk_nvmf_tcp_transport *ttransport,
} }
TAILQ_FOREACH(port, &ttransport->ports, link) { TAILQ_FOREACH(port, &ttransport->ports, link) {
if (spdk_nvme_transport_id_compare(&canon_trid, &port->trid) == 0) { if (spdk_nvme_transport_id_compare(&canon_trid, port->trid) == 0) {
return port; return port;
} }
} }
@ -616,11 +615,6 @@ spdk_nvmf_tcp_listen(struct spdk_nvmf_transport *transport,
} }
pthread_mutex_lock(&ttransport->lock); pthread_mutex_lock(&ttransport->lock);
port = _spdk_nvmf_tcp_find_port(ttransport, trid);
if (port) {
goto success;
}
port = calloc(1, sizeof(*port)); port = calloc(1, sizeof(*port));
if (!port) { if (!port) {
SPDK_ERRLOG("Port allocation failed\n"); SPDK_ERRLOG("Port allocation failed\n");
@ -628,14 +622,7 @@ spdk_nvmf_tcp_listen(struct spdk_nvmf_transport *transport,
return -ENOMEM; return -ENOMEM;
} }
if (_spdk_nvmf_tcp_canon_listen_trid(&port->trid, trid) != 0) { port->trid = trid;
SPDK_ERRLOG("Invalid traddr %s / trsvcid %s\n",
trid->traddr, trid->trsvcid);
free(port);
pthread_mutex_unlock(&ttransport->lock);
return -ENOMEM;
}
port->listen_sock = spdk_sock_listen(trid->traddr, trsvcid_int, NULL); port->listen_sock = spdk_sock_listen(trid->traddr, trsvcid_int, NULL);
if (port->listen_sock == NULL) { if (port->listen_sock == NULL) {
SPDK_ERRLOG("spdk_sock_listen(%s, %d) failed: %s (%d)\n", SPDK_ERRLOG("spdk_sock_listen(%s, %d) failed: %s (%d)\n",
@ -667,21 +654,21 @@ spdk_nvmf_tcp_listen(struct spdk_nvmf_transport *transport,
trid->traddr, trid->trsvcid); trid->traddr, trid->trsvcid);
TAILQ_INSERT_TAIL(&ttransport->ports, port, link); TAILQ_INSERT_TAIL(&ttransport->ports, port, link);
success:
port->ref++;
pthread_mutex_unlock(&ttransport->lock); pthread_mutex_unlock(&ttransport->lock);
cb_fn(cb_arg, 0);
if (cb_fn != NULL) {
cb_fn(cb_arg, 0);
}
return 0; return 0;
} }
static int static void
spdk_nvmf_tcp_stop_listen(struct spdk_nvmf_transport *transport, spdk_nvmf_tcp_stop_listen(struct spdk_nvmf_transport *transport,
const struct spdk_nvme_transport_id *trid) const struct spdk_nvme_transport_id *trid)
{ {
struct spdk_nvmf_tcp_transport *ttransport; struct spdk_nvmf_tcp_transport *ttransport;
struct spdk_nvmf_tcp_port *port; struct spdk_nvmf_tcp_port *port;
int rc;
ttransport = SPDK_CONTAINEROF(transport, struct spdk_nvmf_tcp_transport, transport); ttransport = SPDK_CONTAINEROF(transport, struct spdk_nvmf_tcp_transport, transport);
@ -691,21 +678,12 @@ spdk_nvmf_tcp_stop_listen(struct spdk_nvmf_transport *transport,
pthread_mutex_lock(&ttransport->lock); pthread_mutex_lock(&ttransport->lock);
port = _spdk_nvmf_tcp_find_port(ttransport, trid); port = _spdk_nvmf_tcp_find_port(ttransport, trid);
if (port) { if (port) {
assert(port->ref > 0); TAILQ_REMOVE(&ttransport->ports, port, link);
port->ref--; spdk_sock_close(&port->listen_sock);
if (port->ref == 0) { free(port);
TAILQ_REMOVE(&ttransport->ports, port, link);
spdk_sock_close(&port->listen_sock);
free(port);
}
rc = 0;
} else {
SPDK_DEBUGLOG(SPDK_LOG_NVMF_TCP, "Port not found\n");
rc = -ENOENT;
} }
pthread_mutex_unlock(&ttransport->lock);
return rc; pthread_mutex_unlock(&ttransport->lock);
} }
static void spdk_nvmf_tcp_qpair_set_recv_state(struct spdk_nvmf_tcp_qpair *tqpair, static void spdk_nvmf_tcp_qpair_set_recv_state(struct spdk_nvmf_tcp_qpair *tqpair,
@ -919,7 +897,7 @@ _spdk_nvmf_tcp_handle_connect(struct spdk_nvmf_transport *transport,
int rc; int rc;
SPDK_DEBUGLOG(SPDK_LOG_NVMF_TCP, "New connection accepted on %s port %s\n", SPDK_DEBUGLOG(SPDK_LOG_NVMF_TCP, "New connection accepted on %s port %s\n",
port->trid.traddr, port->trid.trsvcid); port->trid->traddr, port->trid->trsvcid);
if (transport->opts.sock_priority) { if (transport->opts.sock_priority) {
rc = spdk_sock_set_priority(sock, transport->opts.sock_priority); rc = spdk_sock_set_priority(sock, transport->opts.sock_priority);

View File

@ -126,6 +126,8 @@ spdk_nvmf_transport_create(const char *transport_name, struct spdk_nvmf_transpor
return NULL; return NULL;
} }
TAILQ_INIT(&transport->listeners);
transport->ops = ops; transport->ops = ops;
transport->opts = *opts; transport->opts = *opts;
chars_written = snprintf(spdk_mempool_name, MAX_MEMPOOL_NAME_LENGTH, "%s_%s_%s", "spdk_nvmf", chars_written = snprintf(spdk_mempool_name, MAX_MEMPOOL_NAME_LENGTH, "%s_%s_%s", "spdk_nvmf",
@ -180,20 +182,62 @@ spdk_nvmf_transport_destroy(struct spdk_nvmf_transport *transport)
return transport->ops->destroy(transport); return transport->ops->destroy(transport);
} }
struct spdk_nvmf_listener *
spdk_nvmf_transport_find_listener(struct spdk_nvmf_transport *transport,
const struct spdk_nvme_transport_id *trid)
{
struct spdk_nvmf_listener *listener;
TAILQ_FOREACH(listener, &transport->listeners, link) {
if (spdk_nvme_transport_id_compare(&listener->trid, trid) == 0) {
return listener;
}
}
return NULL;
}
int int
spdk_nvmf_transport_listen(struct spdk_nvmf_transport *transport, spdk_nvmf_transport_listen(struct spdk_nvmf_transport *transport,
const struct spdk_nvme_transport_id *trid, const struct spdk_nvme_transport_id *trid,
spdk_nvmf_tgt_listen_done_fn cb_fn, spdk_nvmf_tgt_listen_done_fn cb_fn,
void *cb_arg) void *cb_arg)
{ {
return transport->ops->listen(transport, trid, cb_fn, cb_arg); struct spdk_nvmf_listener *listener = spdk_nvmf_transport_find_listener(transport, trid);
if (!listener) {
listener = calloc(1, sizeof(*listener));
if (!listener) {
return -ENOMEM;
}
listener->ref = 1;
listener->trid = *trid;
TAILQ_INSERT_TAIL(&transport->listeners, listener, link);
return transport->ops->listen(transport, &listener->trid, cb_fn, cb_arg);
}
++listener->ref;
cb_fn(cb_arg, 0);
return 0;
} }
int int
spdk_nvmf_transport_stop_listen(struct spdk_nvmf_transport *transport, spdk_nvmf_transport_stop_listen(struct spdk_nvmf_transport *transport,
const struct spdk_nvme_transport_id *trid) const struct spdk_nvme_transport_id *trid)
{ {
return transport->ops->stop_listen(transport, trid); struct spdk_nvmf_listener *listener = spdk_nvmf_transport_find_listener(transport, trid);
if (!listener) {
return -ENOENT;
}
if (--listener->ref == 0) {
TAILQ_REMOVE(&transport->listeners, listener, link);
transport->ops->stop_listen(transport, trid);
free(listener);
}
return 0;
} }
void void

View File

@ -86,6 +86,15 @@ spdk_nvmf_transport_listen(struct spdk_nvmf_transport *transport,
return 0; return 0;
} }
static struct spdk_nvmf_listener g_listener = {};
struct spdk_nvmf_listener *
spdk_nvmf_transport_find_listener(struct spdk_nvmf_transport *transport,
const struct spdk_nvme_transport_id *trid)
{
return &g_listener;
}
void void
spdk_nvmf_transport_listener_discover(struct spdk_nvmf_transport *transport, spdk_nvmf_transport_listener_discover(struct spdk_nvmf_transport *transport,
struct spdk_nvme_transport_id *trid, struct spdk_nvme_transport_id *trid,