bdev/nvme: Hold bdev_io which submits reset into nvme_bdev_ctrlr

Hold the bdev_io which submits the reset request into the nvme_bdev_ctrlr.
as reset_bio. Then differentiate the callback function between
_bdev_nvme_complete_pending_resets() and _bdev_nvme_abort_pending_resets()
to spdk_for_each_channel() in _bdev_nvme_reset_complete().

The next patch will pass nvme_bdev_ctrlr to for_each_channel() instead.

The following patches will register nvme_bdev_subsystem instead of
nvme_bdev_ctrlr as io_device. Hence we need a different way to pass
nvme_bdev_ctrlr to the completion functions of spdk_for_each_channel().

Signed-off-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Change-Id: If7a3386815429e8ed44f4e9e5365a21bd97e7fb6
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/6913
Community-CI: Broadcom CI
Community-CI: Mellanox Build Bot
Reviewed-by: Paul Luse <paul.e.luse@intel.com>
Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
Shuhei Matsumoto 2021-03-19 07:01:01 +09:00 committed by Tomasz Zawadzki
parent cb8aa8abc5
commit 20839ad6a0
2 changed files with 37 additions and 20 deletions

View File

@ -396,23 +396,36 @@ _bdev_nvme_check_pending_destruct(struct spdk_io_channel_iter *i, int status)
} }
static void static void
_bdev_nvme_complete_pending_resets(struct spdk_io_channel_iter *i) _bdev_nvme_complete_pending_resets(struct nvme_io_channel *nvme_ch,
enum spdk_bdev_io_status status)
{ {
struct spdk_io_channel *_ch = spdk_io_channel_iter_get_channel(i);
struct nvme_io_channel *nvme_ch = spdk_io_channel_get_ctx(_ch);
struct spdk_bdev_io *bdev_io; struct spdk_bdev_io *bdev_io;
enum spdk_bdev_io_status status = SPDK_BDEV_IO_STATUS_SUCCESS;
/* A NULL ctx means success. */
if (spdk_io_channel_iter_get_ctx(i) != NULL) {
status = SPDK_BDEV_IO_STATUS_FAILED;
}
while (!TAILQ_EMPTY(&nvme_ch->pending_resets)) { while (!TAILQ_EMPTY(&nvme_ch->pending_resets)) {
bdev_io = TAILQ_FIRST(&nvme_ch->pending_resets); bdev_io = TAILQ_FIRST(&nvme_ch->pending_resets);
TAILQ_REMOVE(&nvme_ch->pending_resets, bdev_io, module_link); TAILQ_REMOVE(&nvme_ch->pending_resets, bdev_io, module_link);
spdk_bdev_io_complete(bdev_io, status); spdk_bdev_io_complete(bdev_io, status);
} }
}
static void
bdev_nvme_complete_pending_resets(struct spdk_io_channel_iter *i)
{
struct spdk_io_channel *_ch = spdk_io_channel_iter_get_channel(i);
struct nvme_io_channel *nvme_ch = spdk_io_channel_get_ctx(_ch);
_bdev_nvme_complete_pending_resets(nvme_ch, SPDK_BDEV_IO_STATUS_SUCCESS);
spdk_for_each_channel_continue(i, 0);
}
static void
bdev_nvme_abort_pending_resets(struct spdk_io_channel_iter *i)
{
struct spdk_io_channel *_ch = spdk_io_channel_iter_get_channel(i);
struct nvme_io_channel *nvme_ch = spdk_io_channel_get_ctx(_ch);
_bdev_nvme_complete_pending_resets(nvme_ch, SPDK_BDEV_IO_STATUS_FAILED);
spdk_for_each_channel_continue(i, 0); spdk_for_each_channel_continue(i, 0);
} }
@ -420,13 +433,9 @@ _bdev_nvme_complete_pending_resets(struct spdk_io_channel_iter *i)
static void static void
_bdev_nvme_reset_complete(struct nvme_bdev_ctrlr *nvme_bdev_ctrlr, int rc) _bdev_nvme_reset_complete(struct nvme_bdev_ctrlr *nvme_bdev_ctrlr, int rc)
{ {
/* we are using the for_each_channel cb_arg like a return code here. */
/* If it's zero, we succeeded, otherwise, the reset failed. */
void *cb_arg = NULL;
struct nvme_bdev_ctrlr_trid *curr_trid; struct nvme_bdev_ctrlr_trid *curr_trid;
if (rc) { if (rc) {
cb_arg = (void *)0x1;
SPDK_ERRLOG("Resetting controller failed.\n"); SPDK_ERRLOG("Resetting controller failed.\n");
} else { } else {
SPDK_NOTICELOG("Resetting controller successful.\n"); SPDK_NOTICELOG("Resetting controller successful.\n");
@ -440,7 +449,7 @@ _bdev_nvme_reset_complete(struct nvme_bdev_ctrlr *nvme_bdev_ctrlr, int rc)
assert(curr_trid != NULL); assert(curr_trid != NULL);
assert(&curr_trid->trid == nvme_bdev_ctrlr->connected_trid); assert(&curr_trid->trid == nvme_bdev_ctrlr->connected_trid);
curr_trid->is_failed = cb_arg != NULL ? true : false; curr_trid->is_failed = rc != 0 ? true : false;
if (nvme_bdev_ctrlr->ref == 0 && nvme_bdev_ctrlr->destruct) { if (nvme_bdev_ctrlr->ref == 0 && nvme_bdev_ctrlr->destruct) {
/* Destruct ctrlr after clearing pending resets. */ /* Destruct ctrlr after clearing pending resets. */
@ -451,8 +460,9 @@ _bdev_nvme_reset_complete(struct nvme_bdev_ctrlr *nvme_bdev_ctrlr, int rc)
/* Make sure we clear any pending resets before returning. */ /* Make sure we clear any pending resets before returning. */
spdk_for_each_channel(nvme_bdev_ctrlr, spdk_for_each_channel(nvme_bdev_ctrlr,
_bdev_nvme_complete_pending_resets, rc == 0 ? bdev_nvme_complete_pending_resets :
cb_arg, bdev_nvme_abort_pending_resets,
NULL,
_bdev_nvme_check_pending_destruct); _bdev_nvme_check_pending_destruct);
} }
@ -460,7 +470,7 @@ static void
_bdev_nvme_reset_create_qpairs_done(struct spdk_io_channel_iter *i, int status) _bdev_nvme_reset_create_qpairs_done(struct spdk_io_channel_iter *i, int status)
{ {
struct nvme_bdev_ctrlr *nvme_bdev_ctrlr = spdk_io_channel_iter_get_io_device(i); struct nvme_bdev_ctrlr *nvme_bdev_ctrlr = spdk_io_channel_iter_get_io_device(i);
struct nvme_bdev_io *bio = spdk_io_channel_iter_get_ctx(i); struct nvme_bdev_io *bio = nvme_bdev_ctrlr->reset_bio;
int rc = SPDK_BDEV_IO_STATUS_SUCCESS; int rc = SPDK_BDEV_IO_STATUS_SUCCESS;
if (status) { if (status) {
@ -468,6 +478,7 @@ _bdev_nvme_reset_create_qpairs_done(struct spdk_io_channel_iter *i, int status)
} }
if (bio) { if (bio) {
spdk_bdev_io_complete(spdk_bdev_io_from_ctx(bio), rc); spdk_bdev_io_complete(spdk_bdev_io_from_ctx(bio), rc);
nvme_bdev_ctrlr->reset_bio = NULL;
} }
_bdev_nvme_reset_complete(nvme_bdev_ctrlr, status); _bdev_nvme_reset_complete(nvme_bdev_ctrlr, status);
} }
@ -488,7 +499,7 @@ static void
_bdev_nvme_reset_ctrlr(struct spdk_io_channel_iter *i, int status) _bdev_nvme_reset_ctrlr(struct spdk_io_channel_iter *i, int status)
{ {
struct nvme_bdev_ctrlr *nvme_bdev_ctrlr = spdk_io_channel_iter_get_io_device(i); struct nvme_bdev_ctrlr *nvme_bdev_ctrlr = spdk_io_channel_iter_get_io_device(i);
struct nvme_bdev_io *bio = spdk_io_channel_iter_get_ctx(i); struct nvme_bdev_io *bio = nvme_bdev_ctrlr->reset_bio;
int rc; int rc;
if (status) { if (status) {
@ -504,13 +515,14 @@ _bdev_nvme_reset_ctrlr(struct spdk_io_channel_iter *i, int status)
/* Recreate all of the I/O queue pairs */ /* Recreate all of the I/O queue pairs */
spdk_for_each_channel(nvme_bdev_ctrlr, spdk_for_each_channel(nvme_bdev_ctrlr,
_bdev_nvme_reset_create_qpair, _bdev_nvme_reset_create_qpair,
bio, NULL,
_bdev_nvme_reset_create_qpairs_done); _bdev_nvme_reset_create_qpairs_done);
return; return;
err: err:
if (bio) { if (bio) {
spdk_bdev_io_complete(spdk_bdev_io_from_ctx(bio), SPDK_BDEV_IO_STATUS_FAILED); spdk_bdev_io_complete(spdk_bdev_io_from_ctx(bio), SPDK_BDEV_IO_STATUS_FAILED);
nvme_bdev_ctrlr->reset_bio = NULL;
} }
_bdev_nvme_reset_complete(nvme_bdev_ctrlr, rc); _bdev_nvme_reset_complete(nvme_bdev_ctrlr, rc);
} }
@ -576,10 +588,13 @@ bdev_nvme_reset(struct nvme_io_channel *nvme_ch, struct nvme_bdev_io *bio)
rc = _bdev_nvme_reset_start(nvme_ch->ctrlr); rc = _bdev_nvme_reset_start(nvme_ch->ctrlr);
if (rc == 0) { if (rc == 0) {
assert(nvme_ch->ctrlr->reset_bio == NULL);
nvme_ch->ctrlr->reset_bio = bio;
/* First, delete all NVMe I/O queue pairs. */ /* First, delete all NVMe I/O queue pairs. */
spdk_for_each_channel(nvme_ch->ctrlr, spdk_for_each_channel(nvme_ch->ctrlr,
_bdev_nvme_reset_destroy_qpair, _bdev_nvme_reset_destroy_qpair,
bio, NULL,
_bdev_nvme_reset_ctrlr); _bdev_nvme_reset_ctrlr);
} else if (rc == -EBUSY) { } else if (rc == -EBUSY) {
/* Don't bother resetting if the controller is in the process of being destructed. */ /* Don't bother resetting if the controller is in the process of being destructed. */

View File

@ -108,6 +108,8 @@ struct nvme_bdev_ctrlr {
struct ocssd_bdev_ctrlr *ocssd_ctrlr; struct ocssd_bdev_ctrlr *ocssd_ctrlr;
struct nvme_bdev_io *reset_bio;
/** linked list pointer for device list */ /** linked list pointer for device list */
TAILQ_ENTRY(nvme_bdev_ctrlr) tailq; TAILQ_ENTRY(nvme_bdev_ctrlr) tailq;