bdev/ocssd: Add ocssd_ns->depopulate_pending to complete pending depopulation

The following patches will remove nvme_ns->ref and use nvme_ns->populated
and nvme_ns->bdev instead because nvms_ns->ref is two at most and
each count of nvme_ns->ref corresponds to nvme_ns->populated or
nvme_ns->bdev.

To do that, we need to ensure nvme_ns->populated is cleared after
spdk_bdev_unregister() is called, otherwise nvme_bdev_ctrlr_destruct()
is called twice.

However OCSSD namespace had used nvme_ns->populated to free resource
after getting log page completes.

To keep such deferral, add the depopulate_pending flag to struct bdev_ocssd_ns
and use it. Then clear nvme_ns->populated in bdev_ocssd_free_namespace()
after spdk_bdev_unregister().

Signed-off-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Change-Id: I93199dbd504145bd1e5ea59f5914422c6c5bc938
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/7102
Community-CI: Broadcom CI
Community-CI: Mellanox Build Bot
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Paul Luse <paul.e.luse@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com>
This commit is contained in:
Shuhei Matsumoto 2021-03-28 10:41:43 +09:00 committed by Jim Harris
parent f26d6c73e1
commit b1d6c2f3cb

View File

@ -88,6 +88,7 @@ struct bdev_ocssd_ns {
struct spdk_ocssd_geometry_data geometry; struct spdk_ocssd_geometry_data geometry;
struct bdev_ocssd_lba_offsets lba_offsets; struct bdev_ocssd_lba_offsets lba_offsets;
bool chunk_notify_pending; bool chunk_notify_pending;
bool depopulate_pending;
uint64_t chunk_notify_count; uint64_t chunk_notify_count;
uint64_t num_outstanding; uint64_t num_outstanding;
#define CHUNK_NOTIFICATION_ENTRY_COUNT 64 #define CHUNK_NOTIFICATION_ENTRY_COUNT 64
@ -905,6 +906,8 @@ bdev_ocssd_free_namespace(struct nvme_bdev_ns *nvme_ns)
free(nvme_ns->type_ctx); free(nvme_ns->type_ctx);
nvme_ns->type_ctx = NULL; nvme_ns->type_ctx = NULL;
nvme_ns->populated = false;
nvme_ctrlr_depopulate_namespace_done(nvme_ns); nvme_ctrlr_depopulate_namespace_done(nvme_ns);
} }
@ -975,9 +978,10 @@ bdev_ocssd_chunk_notification_cb(void *ctx, const struct spdk_nvme_cpl *cpl)
ocssd_ns->num_outstanding--; ocssd_ns->num_outstanding--;
/* The namespace could have been depopulated in the meantime */ /* The namespace was being depopulated in the meantime. */
if (!nvme_ns->populated) { if (ocssd_ns->depopulate_pending) {
if (ocssd_ns->num_outstanding == 0) { if (ocssd_ns->num_outstanding == 0) {
ocssd_ns->depopulate_pending = false;
bdev_ocssd_free_namespace(nvme_ns); bdev_ocssd_free_namespace(nvme_ns);
} }
@ -1485,14 +1489,15 @@ bdev_ocssd_depopulate_namespace(struct nvme_bdev_ns *nvme_ns)
ocssd_ns = bdev_ocssd_get_ns_from_nvme(nvme_ns); ocssd_ns = bdev_ocssd_get_ns_from_nvme(nvme_ns);
/* If there are outstanding admin requests, we cannot free the context /* If there are outstanding admin requests, we cannot free the context
* here, as they'd write over deallocated memory. Clear the populated * here, as they'd write over deallocated memory. Set the populating
* flag, so that the completion callback knows that the namespace is * flag, so that the completion callback knows that the namespace is
* being depopulated and finish its deallocation once all requests are * being depopulated and finish its deallocation once all requests are
* completed. * completed.
*/ */
nvme_ns->populated = false;
if (ocssd_ns->num_outstanding == 0) { if (ocssd_ns->num_outstanding == 0) {
bdev_ocssd_free_namespace(nvme_ns); bdev_ocssd_free_namespace(nvme_ns);
} else {
ocssd_ns->depopulate_pending = true;
} }
} }