diff --git a/module/bdev/nvme/bdev_nvme.c b/module/bdev/nvme/bdev_nvme.c index 657153019..6740720b6 100644 --- a/module/bdev/nvme/bdev_nvme.c +++ b/module/bdev/nvme/bdev_nvme.c @@ -573,6 +573,30 @@ bdev_nvme_reset_create_qpair(struct spdk_io_channel_iter *i) spdk_for_each_channel_continue(i, rc); } +static int +bdev_nvme_ctrlr_reset_poll(void *arg) +{ + struct nvme_ctrlr *nvme_ctrlr = arg; + int rc; + + rc = spdk_nvme_ctrlr_reset_poll_async(nvme_ctrlr->reset_ctx); + if (rc == -EAGAIN) { + return SPDK_POLLER_BUSY; + } + + spdk_poller_unregister(&nvme_ctrlr->reset_poller); + if (rc == 0) { + /* Recreate all of the I/O queue pairs */ + spdk_for_each_channel(nvme_ctrlr, + bdev_nvme_reset_create_qpair, + NULL, + bdev_nvme_reset_create_qpairs_done); + } else { + bdev_nvme_reset_complete(nvme_ctrlr, rc); + } + return SPDK_POLLER_BUSY; +} + static void bdev_nvme_reset_ctrlr(struct spdk_io_channel_iter *i, int status) { @@ -584,16 +608,15 @@ bdev_nvme_reset_ctrlr(struct spdk_io_channel_iter *i, int status) goto err; } - rc = spdk_nvme_ctrlr_reset(nvme_ctrlr->ctrlr); + rc = spdk_nvme_ctrlr_reset_async(nvme_ctrlr->ctrlr, &nvme_ctrlr->reset_ctx); if (rc != 0) { + SPDK_ERRLOG("Create controller reset context failed\n"); goto err; } + assert(nvme_ctrlr->reset_poller == NULL); + nvme_ctrlr->reset_poller = SPDK_POLLER_REGISTER(bdev_nvme_ctrlr_reset_poll, + nvme_ctrlr, 0); - /* Recreate all of the I/O queue pairs */ - spdk_for_each_channel(nvme_ctrlr, - bdev_nvme_reset_create_qpair, - NULL, - bdev_nvme_reset_create_qpairs_done); return; err: diff --git a/module/bdev/nvme/common.h b/module/bdev/nvme/common.h index 1d7406582..7cd38c539 100644 --- a/module/bdev/nvme/common.h +++ b/module/bdev/nvme/common.h @@ -133,6 +133,8 @@ struct nvme_ctrlr { bdev_nvme_reset_cb reset_cb_fn; void *reset_cb_arg; + struct spdk_nvme_ctrlr_reset_ctx *reset_ctx; + struct spdk_poller *reset_poller; /** linked list pointer for device list */ TAILQ_ENTRY(nvme_ctrlr) tailq; diff --git a/test/unit/lib/bdev/nvme/bdev_nvme.c/bdev_nvme_ut.c b/test/unit/lib/bdev/nvme/bdev_nvme.c/bdev_nvme_ut.c index 3d934e106..0958f0250 100644 --- a/test/unit/lib/bdev/nvme/bdev_nvme.c/bdev_nvme_ut.c +++ b/test/unit/lib/bdev/nvme/bdev_nvme.c/bdev_nvme_ut.c @@ -274,6 +274,10 @@ struct spdk_nvme_probe_ctx { struct spdk_nvme_ctrlr *init_ctrlr; }; +struct spdk_nvme_ctrlr_reset_ctx { + struct spdk_nvme_ctrlr *ctrlr; +}; + static TAILQ_HEAD(, spdk_nvme_ctrlr) g_ut_init_ctrlrs = TAILQ_HEAD_INITIALIZER(g_ut_init_ctrlrs); static TAILQ_HEAD(, spdk_nvme_ctrlr) g_ut_attached_ctrlrs = TAILQ_HEAD_INITIALIZER( g_ut_attached_ctrlrs); @@ -673,6 +677,32 @@ spdk_nvme_ctrlr_reset(struct spdk_nvme_ctrlr *ctrlr) return 0; } +int +spdk_nvme_ctrlr_reset_poll_async(struct spdk_nvme_ctrlr_reset_ctx *ctrlr_reset_ctx) +{ + struct spdk_nvme_ctrlr *ctrlr = ctrlr_reset_ctx->ctrlr; + + free(ctrlr_reset_ctx); + return spdk_nvme_ctrlr_reset(ctrlr); +} + +int +spdk_nvme_ctrlr_reset_async(struct spdk_nvme_ctrlr *ctrlr, + struct spdk_nvme_ctrlr_reset_ctx **reset_ctx) +{ + struct spdk_nvme_ctrlr_reset_ctx *ctrlr_reset_ctx; + + ctrlr_reset_ctx = calloc(1, sizeof(*ctrlr_reset_ctx)); + if (!ctrlr_reset_ctx) { + return -ENOMEM; + } + + ctrlr_reset_ctx->ctrlr = ctrlr; + *reset_ctx = ctrlr_reset_ctx; + + return 0; +} + void spdk_nvme_ctrlr_fail(struct spdk_nvme_ctrlr *ctrlr) {