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:
parent
cb8aa8abc5
commit
20839ad6a0
@ -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. */
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user