nvme: Add new detach to a detach context while it is being polled
This update will allow us to use spdk_nvme_detach_async() and spdk_nvme_detach_poll_async() easier to aggregate multiple detachments. Previously, we could do: spdk_nvme_detach_async() spdk_nvme_detach_async() spdk_nvme_detach_async() and then started doing spdk_nvme_detach_poll_async(). Hence aggregating multiple detachments is already supported. After this patch, the following sequence is possible: spdk_nvme_detach_async() = 0 spdk_nvme_detach_async() = 0 spdk_nvme_detach_async() = 0 spdk_nvme_detach_poll_async() = -EAGAIN spdk_nvme_detach_async() = 0 spdk_nvme_detach_async() = 0 spdk_nvme_detach_poll_async() = -EAGAIN spdk_nvme_detach_poll_async() = -EAGAIN spdk_nvme_detach_poll_async() = -EAGAIN spdk_nvme_detach_poll_async() = 0 The actual changes is to remove the variable polling_started from struct spdk_nvme_detach_ctx because it is not necessary anymore. Clarify this change via updating the header file and CHANGELOG. Verify this change by unit test. Signed-off-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Change-Id: Iebdf6c27c5304a2097b7084c315ccc99634ffa1e Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/8468 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Community-CI: Mellanox Build Bot Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com>
This commit is contained in:
parent
4fe4040a14
commit
3959e397d4
@ -63,6 +63,9 @@ the spdk_nvme_ctrlr_opts structure prior to controller attach.
|
|||||||
Add a new function `spdk_nvme_detach_poll` to simplify a common use case to continue
|
Add a new function `spdk_nvme_detach_poll` to simplify a common use case to continue
|
||||||
polling until all detachments complete.
|
polling until all detachments complete.
|
||||||
|
|
||||||
|
An existing function `spdk_nvme_detach_async` was updated to add one or more detachments
|
||||||
|
to an active context while it is being polled.
|
||||||
|
|
||||||
### rpc
|
### rpc
|
||||||
|
|
||||||
New RPC `bdev_rbd_register_cluster` and `bdev_rbd_unregister_cluster` was added, it allows to create
|
New RPC `bdev_rbd_register_cluster` and `bdev_rbd_unregister_cluster` was added, it allows to create
|
||||||
|
@ -180,9 +180,6 @@ spdk_nvme_detach_async(struct spdk_nvme_ctrlr *ctrlr,
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
TAILQ_INIT(&detach_ctx->head);
|
TAILQ_INIT(&detach_ctx->head);
|
||||||
} else if (detach_ctx->polling_started) {
|
|
||||||
SPDK_ERRLOG("Busy at polling detachment now.\n");
|
|
||||||
return -EBUSY;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = nvme_ctrlr_detach_async(ctrlr, &ctx);
|
rc = nvme_ctrlr_detach_async(ctrlr, &ctx);
|
||||||
@ -214,8 +211,6 @@ spdk_nvme_detach_poll_async(struct spdk_nvme_detach_ctx *detach_ctx)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
detach_ctx->polling_started = true;
|
|
||||||
|
|
||||||
TAILQ_FOREACH_SAFE(ctx, &detach_ctx->head, link, tmp_ctx) {
|
TAILQ_FOREACH_SAFE(ctx, &detach_ctx->head, link, tmp_ctx) {
|
||||||
TAILQ_REMOVE(&detach_ctx->head, ctx, link);
|
TAILQ_REMOVE(&detach_ctx->head, ctx, link);
|
||||||
|
|
||||||
|
@ -914,7 +914,6 @@ struct nvme_ctrlr_detach_ctx {
|
|||||||
|
|
||||||
struct spdk_nvme_detach_ctx {
|
struct spdk_nvme_detach_ctx {
|
||||||
TAILQ_HEAD(, nvme_ctrlr_detach_ctx) head;
|
TAILQ_HEAD(, nvme_ctrlr_detach_ctx) head;
|
||||||
bool polling_started;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct nvme_driver {
|
struct nvme_driver {
|
||||||
|
@ -79,12 +79,18 @@ nvme_ctrlr_destruct_async(struct spdk_nvme_ctrlr *ctrlr, struct nvme_ctrlr_detac
|
|||||||
{
|
{
|
||||||
ut_destruct_called = true;
|
ut_destruct_called = true;
|
||||||
ctrlr->is_destructed = true;
|
ctrlr->is_destructed = true;
|
||||||
|
|
||||||
|
ctx->shutdown_complete = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
nvme_ctrlr_destruct_poll_async(struct spdk_nvme_ctrlr *ctrlr,
|
nvme_ctrlr_destruct_poll_async(struct spdk_nvme_ctrlr *ctrlr,
|
||||||
struct nvme_ctrlr_detach_ctx *ctx)
|
struct nvme_ctrlr_detach_ctx *ctx)
|
||||||
{
|
{
|
||||||
|
if (!ctx->shutdown_complete) {
|
||||||
|
return -EAGAIN;
|
||||||
|
}
|
||||||
|
|
||||||
if (ctx->cb_fn) {
|
if (ctx->cb_fn) {
|
||||||
ctx->cb_fn(ctrlr);
|
ctx->cb_fn(ctrlr);
|
||||||
}
|
}
|
||||||
@ -1496,6 +1502,7 @@ test_spdk_nvme_detach_async(void)
|
|||||||
struct spdk_nvme_ctrlr ctrlr1, ctrlr2;
|
struct spdk_nvme_ctrlr ctrlr1, ctrlr2;
|
||||||
struct nvme_driver test_driver;
|
struct nvme_driver test_driver;
|
||||||
struct spdk_nvme_detach_ctx *detach_ctx;
|
struct spdk_nvme_detach_ctx *detach_ctx;
|
||||||
|
struct nvme_ctrlr_detach_ctx *ctx;
|
||||||
|
|
||||||
detach_ctx = NULL;
|
detach_ctx = NULL;
|
||||||
memset(&ctrlr1, 0, sizeof(ctrlr1));
|
memset(&ctrlr1, 0, sizeof(ctrlr1));
|
||||||
@ -1556,6 +1563,49 @@ test_spdk_nvme_detach_async(void)
|
|||||||
CU_ASSERT(TAILQ_EMPTY(&g_nvme_attached_ctrlrs) == true);
|
CU_ASSERT(TAILQ_EMPTY(&g_nvme_attached_ctrlrs) == true);
|
||||||
CU_ASSERT(TAILQ_EMPTY(&test_driver.shared_attached_ctrlrs) == true);
|
CU_ASSERT(TAILQ_EMPTY(&test_driver.shared_attached_ctrlrs) == true);
|
||||||
|
|
||||||
|
/* Test if ctrlr2 can be detached by using the same context that
|
||||||
|
* ctrlr1 uses while ctrlr1 is being detached.
|
||||||
|
*/
|
||||||
|
detach_ctx = NULL;
|
||||||
|
memset(&ctrlr1, 0, sizeof(ctrlr1));
|
||||||
|
ctrlr1.trid.trtype = SPDK_NVME_TRANSPORT_PCIE;
|
||||||
|
memset(&ctrlr2, 0, sizeof(ctrlr2));
|
||||||
|
ctrlr2.trid.trtype = SPDK_NVME_TRANSPORT_PCIE;
|
||||||
|
TAILQ_INSERT_TAIL(&test_driver.shared_attached_ctrlrs, &ctrlr1, tailq);
|
||||||
|
TAILQ_INSERT_TAIL(&test_driver.shared_attached_ctrlrs, &ctrlr2, tailq);
|
||||||
|
|
||||||
|
rc = spdk_nvme_detach_async(&ctrlr1, &detach_ctx);
|
||||||
|
CU_ASSERT(rc == 0);
|
||||||
|
CU_ASSERT(ctrlr1.is_destructed == true);
|
||||||
|
SPDK_CU_ASSERT_FATAL(detach_ctx != NULL);
|
||||||
|
|
||||||
|
ctx = TAILQ_FIRST(&detach_ctx->head);
|
||||||
|
SPDK_CU_ASSERT_FATAL(ctx != NULL);
|
||||||
|
CU_ASSERT(ctx->ctrlr == &ctrlr1);
|
||||||
|
CU_ASSERT(ctx->shutdown_complete == true);
|
||||||
|
|
||||||
|
/* Set ctx->shutdown_complete for ctrlr1 to false to allow ctrlr2 to
|
||||||
|
* add to detach_ctx while spdk_nvme_detach_poll_async() is being
|
||||||
|
* executed.
|
||||||
|
*/
|
||||||
|
ctx->shutdown_complete = false;
|
||||||
|
|
||||||
|
rc = spdk_nvme_detach_poll_async(detach_ctx);
|
||||||
|
CU_ASSERT(rc == -EAGAIN);
|
||||||
|
|
||||||
|
rc = spdk_nvme_detach_async(&ctrlr2, &detach_ctx);
|
||||||
|
CU_ASSERT(rc == 0);
|
||||||
|
CU_ASSERT(ctrlr2.is_destructed == true);
|
||||||
|
|
||||||
|
/* After ctrlr2 is added to detach_ctx, set ctx->shutdown_complete for
|
||||||
|
* ctrlr1 to true to complete spdk_nvme_detach_poll_async().
|
||||||
|
*/
|
||||||
|
ctx->shutdown_complete = true;
|
||||||
|
|
||||||
|
rc = spdk_nvme_detach_poll_async(detach_ctx);
|
||||||
|
CU_ASSERT(rc == 0);
|
||||||
|
CU_ASSERT(TAILQ_EMPTY(&test_driver.shared_attached_ctrlrs) == true);
|
||||||
|
|
||||||
g_spdk_nvme_driver = NULL;
|
g_spdk_nvme_driver = NULL;
|
||||||
pthread_mutex_destroy(&test_driver.lock);
|
pthread_mutex_destroy(&test_driver.lock);
|
||||||
MOCK_CLEAR(nvme_ctrlr_get_ref_count);
|
MOCK_CLEAR(nvme_ctrlr_get_ref_count);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user