nvmf: Simplify qpair disconnect code path

This path works for disconnect events on qpairs at run time.
Disconnects in response to killing the target have
not been worked out yet.

This path does not currently wait for outstanding I/O to
complete.

Change-Id: I8e476c8444b460c18e51601fb950b9132d12f67d
Signed-off-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-on: https://review.gerrithub.io/412076
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
Ben Walker 2018-05-21 16:39:34 -07:00 committed by Jim Harris
parent d34bd0a60b
commit 4a8b3adb44
2 changed files with 59 additions and 84 deletions

View File

@ -191,14 +191,6 @@ spdk_nvmf_ctrlr_create(struct spdk_nvmf_subsystem *subsystem,
return ctrlr;
}
static void ctrlr_destruct(void *ctx)
{
struct spdk_nvmf_ctrlr *ctrlr = ctx;
spdk_nvmf_subsystem_remove_ctrlr(ctrlr->subsys, ctrlr);
free(ctrlr);
}
void
spdk_nvmf_ctrlr_destruct(struct spdk_nvmf_ctrlr *ctrlr)
{
@ -210,7 +202,9 @@ spdk_nvmf_ctrlr_destruct(struct spdk_nvmf_ctrlr *ctrlr)
spdk_nvmf_transport_qpair_fini(qpair);
}
ctrlr_destruct(ctrlr);
spdk_nvmf_subsystem_remove_ctrlr(ctrlr->subsys, ctrlr);
free(ctrlr);
}
static void
@ -274,50 +268,6 @@ end:
spdk_thread_send_msg(qpair->group->thread, _spdk_nvmf_request_complete, req);
}
static void
_ctrlr_destruct_check(void *ctx)
{
struct spdk_nvmf_ctrlr *ctrlr = ctx;
assert(ctrlr != NULL);
assert(ctrlr->num_qpairs > 0);
ctrlr->num_qpairs--;
if (ctrlr->num_qpairs == 0) {
assert(ctrlr->subsys != NULL);
assert(ctrlr->subsys->thread != NULL);
spdk_thread_send_msg(ctrlr->subsys->thread, ctrlr_destruct, ctrlr);
}
}
static void
nvmf_qpair_fini(void *ctx)
{
struct spdk_nvmf_qpair *qpair = ctx;
struct spdk_nvmf_ctrlr *ctrlr = qpair->ctrlr;
struct spdk_thread *admin_thread = ctrlr->admin_qpair->group->thread;
spdk_nvmf_transport_qpair_fini(qpair);
spdk_thread_send_msg(admin_thread, _ctrlr_destruct_check, ctrlr);
}
static void
ctrlr_delete_qpair(void *ctx)
{
struct spdk_nvmf_qpair *qpair = ctx;
struct spdk_nvmf_ctrlr *ctrlr = qpair->ctrlr;
assert(ctrlr != NULL);
assert(ctrlr->num_qpairs > 0);
/* Defer the admin qpair deletion since there are still io qpairs */
if ((ctrlr->num_qpairs > 1) && (qpair == ctrlr->admin_qpair)) {
spdk_thread_send_msg(qpair->group->thread, ctrlr_delete_qpair, qpair);
return;
}
TAILQ_REMOVE(&ctrlr->qpairs, qpair, link);
spdk_thread_send_msg(qpair->group->thread, nvmf_qpair_fini, qpair);
}
static void
_spdk_nvmf_ctrlr_add_io_qpair(void *ctx)
{
@ -461,16 +411,64 @@ spdk_nvmf_ctrlr_connect(struct spdk_nvmf_request *req)
}
}
static void
_spdk_nvmf_ctrlr_free(void *ctx)
{
struct spdk_nvmf_ctrlr *ctrlr = ctx;
spdk_nvmf_subsystem_remove_ctrlr(ctrlr->subsys, ctrlr);
free(ctrlr);
}
static void
_spdk_nvmf_qpair_destroy(void *ctx)
{
struct spdk_nvmf_qpair *qpair = ctx;
spdk_nvmf_transport_qpair_fini(qpair);
}
static void
_spdk_nvmf_ctrlr_remove_qpair(void *ctx)
{
struct spdk_nvmf_qpair *qpair = ctx;
struct spdk_nvmf_ctrlr *ctrlr = qpair->ctrlr;
assert(ctrlr != NULL);
assert(ctrlr->num_qpairs > 0);
TAILQ_REMOVE(&ctrlr->qpairs, qpair, link);
ctrlr->num_qpairs--;
/* Send a message to the thread that owns the qpair and destroy it. */
qpair->ctrlr = NULL;
spdk_thread_send_msg(qpair->group->thread, _spdk_nvmf_qpair_destroy, qpair);
if (ctrlr->num_qpairs == 0) {
/* If this was the last queue pair on the controller, also send a message
* to the subsystem to remove the controller. */
spdk_thread_send_msg(ctrlr->subsys->thread, _spdk_nvmf_ctrlr_free, ctrlr);
}
}
void
spdk_nvmf_ctrlr_disconnect(struct spdk_nvmf_qpair *qpair)
{
struct spdk_nvmf_ctrlr *ctrlr = qpair->ctrlr;
struct spdk_nvmf_qpair *admin_qpair = ctrlr->admin_qpair;
struct spdk_nvmf_ctrlr *ctrlr;
assert(admin_qpair != NULL);
assert(admin_qpair->group != NULL);
assert(admin_qpair->group->thread != NULL);
spdk_thread_send_msg(admin_qpair->group->thread, ctrlr_delete_qpair, qpair);
ctrlr = qpair->ctrlr;
if (ctrlr == NULL) {
/* This qpair was never added to a controller. Skip a step
* and destroy it immediately. */
spdk_thread_send_msg(qpair->group->thread, _spdk_nvmf_qpair_destroy, qpair);
return;
}
/* Send a message to the controller thread to remove the qpair from its internal
* list. */
spdk_thread_send_msg(ctrlr->admin_qpair->group->thread, _spdk_nvmf_ctrlr_remove_qpair, qpair);
}
struct spdk_nvmf_qpair *

View File

@ -705,32 +705,10 @@ nvmf_rdma_connect(struct spdk_nvmf_transport *transport, struct rdma_cm_event *e
return 0;
}
static void
nvmf_rdma_handle_disconnect(void *ctx)
{
struct spdk_nvmf_qpair *qpair = ctx;
struct spdk_nvmf_ctrlr *ctrlr;
struct spdk_nvmf_rdma_qpair *rqpair;
rqpair = SPDK_CONTAINEROF(qpair, struct spdk_nvmf_rdma_qpair, qpair);
ctrlr = qpair->ctrlr;
if (ctrlr == NULL) {
/* No ctrlr has been established yet, so destroy
* the connection.
*/
spdk_nvmf_rdma_qpair_destroy(rqpair);
return;
}
spdk_nvmf_ctrlr_disconnect(qpair);
}
static int
nvmf_rdma_disconnect(struct rdma_cm_event *evt)
{
struct spdk_nvmf_qpair *qpair;
struct spdk_io_channel *ch;
struct spdk_nvmf_qpair *qpair;
if (evt->id == NULL) {
SPDK_ERRLOG("disconnect request: missing cm_id\n");
@ -745,8 +723,7 @@ nvmf_rdma_disconnect(struct rdma_cm_event *evt)
/* ack the disconnect event before rdma_destroy_id */
rdma_ack_cm_event(evt);
ch = spdk_io_channel_from_ctx(qpair->group);
spdk_thread_send_msg(spdk_io_channel_get_thread(ch), nvmf_rdma_handle_disconnect, qpair);
spdk_nvmf_ctrlr_disconnect(qpair);
return 0;
}