nvmf: remove_subsystem now uses qpair_remove asynch api
This is necessary to avoid race conditions when freeing subsystems. Change-Id: I9b4a7d006cc42cd29e13179e940ced0cc580f548 Signed-off-by: Seth Howell <seth.howell@intel.com> Reviewed-on: https://review.gerrithub.io/417351 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Chandler-Test-Pool: SPDK Automated Test System <sys_sgsw@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
This commit is contained in:
parent
1e2c9afa95
commit
d3995f6eca
109
lib/nvmf/nvmf.c
109
lib/nvmf/nvmf.c
@ -56,6 +56,9 @@ SPDK_LOG_REGISTER_COMPONENT("nvmf", SPDK_LOG_NVMF)
|
|||||||
#define SPDK_NVMF_DEFAULT_MAX_SUBSYSTEMS 1024
|
#define SPDK_NVMF_DEFAULT_MAX_SUBSYSTEMS 1024
|
||||||
#define SPDK_NVMF_DEFAULT_IO_UNIT_SIZE 131072
|
#define SPDK_NVMF_DEFAULT_IO_UNIT_SIZE 131072
|
||||||
|
|
||||||
|
typedef void (*nvmf_qpair_disconnect_cpl)(void *ctx, int status);
|
||||||
|
|
||||||
|
/* supplied to a single call to nvmf_qpair_disconnect */
|
||||||
struct nvmf_qpair_disconnect_ctx {
|
struct nvmf_qpair_disconnect_ctx {
|
||||||
struct spdk_nvmf_qpair *qpair;
|
struct spdk_nvmf_qpair *qpair;
|
||||||
struct spdk_nvmf_ctrlr *ctrlr;
|
struct spdk_nvmf_ctrlr *ctrlr;
|
||||||
@ -64,6 +67,17 @@ struct nvmf_qpair_disconnect_ctx {
|
|||||||
void *ctx;
|
void *ctx;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* There are several times when we need to iterate through the list of all qpairs and selectively delete them.
|
||||||
|
* In order to do this sequentially without overlap, we must provide a context to recover the next qpair from
|
||||||
|
* to enable calling nvmf_qpair_disconnect on the next desired qpair.
|
||||||
|
*/
|
||||||
|
struct nvmf_qpair_disconnect_many_ctx {
|
||||||
|
struct spdk_nvmf_subsystem *subsystem;
|
||||||
|
struct spdk_nvmf_poll_group *group;
|
||||||
|
nvmf_qpair_disconnect_cpl cb_fn;
|
||||||
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
spdk_nvmf_tgt_opts_init(struct spdk_nvmf_tgt_opts *opts)
|
spdk_nvmf_tgt_opts_init(struct spdk_nvmf_tgt_opts *opts)
|
||||||
{
|
{
|
||||||
@ -859,27 +873,17 @@ spdk_nvmf_poll_group_add_subsystem(struct spdk_nvmf_poll_group *group,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
static void
|
||||||
spdk_nvmf_poll_group_remove_subsystem(struct spdk_nvmf_poll_group *group,
|
_nvmf_poll_group_remove_subsystem_cb(void *ctx, int status)
|
||||||
struct spdk_nvmf_subsystem *subsystem)
|
|
||||||
{
|
{
|
||||||
struct spdk_nvmf_qpair *qpair, *tmp;
|
|
||||||
struct spdk_nvmf_subsystem_poll_group *sgroup;
|
struct spdk_nvmf_subsystem_poll_group *sgroup;
|
||||||
int rc = 0;
|
|
||||||
uint32_t nsid;
|
uint32_t nsid;
|
||||||
|
|
||||||
TAILQ_FOREACH_SAFE(qpair, &group->qpairs, link, tmp) {
|
if (status) {
|
||||||
if (qpair->ctrlr->subsys == subsystem) {
|
return;
|
||||||
rc += spdk_nvmf_qpair_disconnect(qpair, NULL, NULL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rc != 0) {
|
sgroup = ctx;
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
sgroup = &group->sgroups[subsystem->id];
|
|
||||||
sgroup->state = SPDK_NVMF_SUBSYSTEM_INACTIVE;
|
|
||||||
|
|
||||||
for (nsid = 0; nsid < sgroup->num_channels; nsid++) {
|
for (nsid = 0; nsid < sgroup->num_channels; nsid++) {
|
||||||
if (sgroup->channels[nsid]) {
|
if (sgroup->channels[nsid]) {
|
||||||
@ -891,6 +895,81 @@ spdk_nvmf_poll_group_remove_subsystem(struct spdk_nvmf_poll_group *group,
|
|||||||
sgroup->num_channels = 0;
|
sgroup->num_channels = 0;
|
||||||
free(sgroup->channels);
|
free(sgroup->channels);
|
||||||
sgroup->channels = NULL;
|
sgroup->channels = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_nvmf_subsystem_disconnect_next_qpair(void *ctx)
|
||||||
|
{
|
||||||
|
struct spdk_nvmf_qpair *qpair;
|
||||||
|
struct nvmf_qpair_disconnect_many_ctx *qpair_ctx = ctx;
|
||||||
|
struct spdk_nvmf_subsystem *subsystem;
|
||||||
|
struct spdk_nvmf_poll_group *group;
|
||||||
|
struct spdk_nvmf_subsystem_poll_group *sgroup;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
group = qpair_ctx->group;
|
||||||
|
subsystem = qpair_ctx->subsystem;
|
||||||
|
|
||||||
|
TAILQ_FOREACH(qpair, &group->qpairs, link) {
|
||||||
|
if (qpair->ctrlr->subsys == subsystem) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qpair) {
|
||||||
|
rc = spdk_nvmf_qpair_disconnect(qpair, _nvmf_subsystem_disconnect_next_qpair, qpair_ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!qpair || rc != 0) {
|
||||||
|
if (qpair_ctx->cb_fn) {
|
||||||
|
sgroup = &group->sgroups[subsystem->id];
|
||||||
|
qpair_ctx->cb_fn(sgroup, rc);
|
||||||
|
}
|
||||||
|
free(qpair_ctx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
spdk_nvmf_poll_group_remove_subsystem(struct spdk_nvmf_poll_group *group,
|
||||||
|
struct spdk_nvmf_subsystem *subsystem)
|
||||||
|
{
|
||||||
|
struct spdk_nvmf_qpair *qpair;
|
||||||
|
struct spdk_nvmf_subsystem_poll_group *sgroup;
|
||||||
|
struct nvmf_qpair_disconnect_many_ctx *ctx;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
ctx = calloc(1, sizeof(struct nvmf_qpair_disconnect_many_ctx));
|
||||||
|
|
||||||
|
if (!ctx) {
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->cb_fn = _nvmf_poll_group_remove_subsystem_cb;
|
||||||
|
ctx->group = group;
|
||||||
|
ctx->subsystem = subsystem;
|
||||||
|
|
||||||
|
sgroup = &group->sgroups[subsystem->id];
|
||||||
|
sgroup->state = SPDK_NVMF_SUBSYSTEM_INACTIVE;
|
||||||
|
|
||||||
|
TAILQ_FOREACH(qpair, &group->qpairs, link) {
|
||||||
|
if (qpair->ctrlr->subsys == subsystem) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qpair) {
|
||||||
|
rc = spdk_nvmf_qpair_disconnect(qpair, _nvmf_subsystem_disconnect_next_qpair, ctx);
|
||||||
|
} else {
|
||||||
|
free(ctx);
|
||||||
|
_nvmf_poll_group_remove_subsystem_cb(sgroup, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rc != 0) {
|
||||||
|
free(ctx);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user