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:
parent
d34bd0a60b
commit
4a8b3adb44
116
lib/nvmf/ctrlr.c
116
lib/nvmf/ctrlr.c
@ -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 *
|
||||
|
@ -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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user