bdev/nvme: Update ANA log page it self when ANA change event is notified

When ANA change event is notified, increment reference count, read
ANA log page, and parse it to update ANA states of namespaces.

Then remove the spdk_nvme_ns_get_ana_state() call and its stub in
unit tests.

Signed-off-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Change-Id: I254ae6cb993694bf0d7f4fa4b1039b5f9243b5cb
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/8335
Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Community-CI: Mellanox Build Bot
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
Shuhei Matsumoto 2021-07-02 16:03:59 +09:00 committed by Tomasz Zawadzki
parent 7ec6d1d559
commit 072f2d0011
2 changed files with 105 additions and 5 deletions

View File

@ -1282,7 +1282,7 @@ bdev_nvme_dump_info_json(void *ctx, struct spdk_json_write_ctx *w)
if (cdata->cmic.ana_reporting) {
spdk_json_write_named_string(w, "ana_state",
_nvme_ana_state_str(spdk_nvme_ns_get_ana_state(ns)));
_nvme_ana_state_str(nvme_ns->ana_state));
}
spdk_json_write_object_end(w);
@ -1820,6 +1820,85 @@ nvme_ctrlr_depopulate_namespaces(struct nvme_ctrlr *nvme_ctrlr)
}
}
static bool
nvme_ctrlr_acquire(struct nvme_ctrlr *nvme_ctrlr)
{
pthread_mutex_lock(&nvme_ctrlr->mutex);
if (nvme_ctrlr->destruct || nvme_ctrlr->resetting) {
pthread_mutex_unlock(&nvme_ctrlr->mutex);
return false;
}
nvme_ctrlr->ref++;
pthread_mutex_unlock(&nvme_ctrlr->mutex);
return true;
}
static int
nvme_ctrlr_set_ana_states(const struct spdk_nvme_ana_group_descriptor *desc,
void *cb_arg)
{
struct nvme_ctrlr *nvme_ctrlr = cb_arg;
struct nvme_ns *nvme_ns;
uint32_t i, nsid;
for (i = 0; i < desc->num_of_nsid; i++) {
nsid = desc->nsid[i];
if (nsid == 0 || nsid > nvme_ctrlr->num_ns) {
continue;
}
nvme_ns = nvme_ctrlr->namespaces[nsid - 1];
assert(nvme_ns != NULL);
if (!nvme_ns->populated) {
continue;
}
nvme_ns->ana_group_id = desc->ana_group_id;
nvme_ns->ana_state = desc->ana_state;
}
return 0;
}
static void
nvme_ctrlr_read_ana_log_page_done(void *ctx, const struct spdk_nvme_cpl *cpl)
{
struct nvme_ctrlr *nvme_ctrlr = ctx;
if (spdk_nvme_cpl_is_success(cpl)) {
bdev_nvme_parse_ana_log_page(nvme_ctrlr, nvme_ctrlr_set_ana_states,
nvme_ctrlr);
}
nvme_ctrlr_release(nvme_ctrlr);
}
static void
nvme_ctrlr_read_ana_log_page(struct nvme_ctrlr *nvme_ctrlr)
{
int rc;
if (nvme_ctrlr->ana_log_page == NULL) {
return;
}
if (!nvme_ctrlr_acquire(nvme_ctrlr)) {
return;
}
rc = spdk_nvme_ctrlr_cmd_get_log_page(nvme_ctrlr->ctrlr,
SPDK_NVME_LOG_ASYMMETRIC_NAMESPACE_ACCESS,
SPDK_NVME_GLOBAL_NS_TAG,
nvme_ctrlr->ana_log_page,
nvme_ctrlr->ana_log_page_size, 0,
nvme_ctrlr_read_ana_log_page_done,
nvme_ctrlr);
if (rc != 0) {
nvme_ctrlr_release(nvme_ctrlr);
}
}
static void
aer_cb(void *arg, const struct spdk_nvme_cpl *cpl)
{
@ -1839,6 +1918,9 @@ aer_cb(void *arg, const struct spdk_nvme_cpl *cpl)
(event.bits.log_page_identifier == SPDK_OCSSD_LOG_CHUNK_NOTIFICATION) &&
spdk_nvme_ctrlr_is_ocssd_supported(nvme_ctrlr->ctrlr)) {
bdev_ocssd_handle_chunk_notification(nvme_ctrlr);
} else if ((event.bits.async_event_type == SPDK_NVME_ASYNC_EVENT_TYPE_NOTICE) &&
(event.bits.async_event_info == SPDK_NVME_ASYNC_EVENT_ANA_CHANGE)) {
nvme_ctrlr_read_ana_log_page(nvme_ctrlr);
}
}

View File

@ -129,9 +129,6 @@ DEFINE_STUB(spdk_nvme_ns_get_dealloc_logical_block_read_value,
DEFINE_STUB(spdk_nvme_ns_get_optimal_io_boundary, uint32_t, (struct spdk_nvme_ns *ns), 0);
DEFINE_STUB(spdk_nvme_ns_get_ana_state, enum spdk_nvme_ana_state,
(const struct spdk_nvme_ns *ns), 0);
DEFINE_STUB(spdk_nvme_ns_get_csi, enum spdk_nvme_csi,
(const struct spdk_nvme_ns *ns), 0);
@ -1757,7 +1754,7 @@ test_aer_cb(void)
/* Attach a ctrlr, whose max number of namespaces is 4, and 2nd, 3rd, and 4th
* namespaces are populated.
*/
ctrlr = ut_attach_ctrlr(&trid, 4, false);
ctrlr = ut_attach_ctrlr(&trid, 4, true);
SPDK_CU_ASSERT_FATAL(ctrlr != NULL);
ctrlr->ns[0].is_active = false;
@ -1772,6 +1769,9 @@ test_aer_cb(void)
spdk_delay_us(1000);
poll_threads();
spdk_delay_us(10000);
poll_threads();
nvme_ctrlr = nvme_ctrlr_get_by_name("nvme0");
SPDK_CU_ASSERT_FATAL(nvme_ctrlr != NULL);
@ -1804,6 +1804,24 @@ test_aer_cb(void)
CU_ASSERT(nvme_ctrlr->namespaces[3]->populated == true);
CU_ASSERT(bdev->disk.blockcnt == 2048);
/* Change ANA state of active namespaces. */
ctrlr->ns[0].ana_state = SPDK_NVME_ANA_NON_OPTIMIZED_STATE;
ctrlr->ns[1].ana_state = SPDK_NVME_ANA_INACCESSIBLE_STATE;
ctrlr->ns[3].ana_state = SPDK_NVME_ANA_CHANGE_STATE;
event.bits.async_event_type = SPDK_NVME_ASYNC_EVENT_TYPE_NOTICE;
event.bits.async_event_info = SPDK_NVME_ASYNC_EVENT_ANA_CHANGE;
cpl.cdw0 = event.raw;
aer_cb(nvme_ctrlr, &cpl);
spdk_delay_us(10000);
poll_threads();
CU_ASSERT(nvme_ctrlr->namespaces[0]->ana_state == SPDK_NVME_ANA_NON_OPTIMIZED_STATE);
CU_ASSERT(nvme_ctrlr->namespaces[1]->ana_state == SPDK_NVME_ANA_INACCESSIBLE_STATE);
CU_ASSERT(nvme_ctrlr->namespaces[3]->ana_state == SPDK_NVME_ANA_CHANGE_STATE);
rc = bdev_nvme_delete("nvme0", NULL);
CU_ASSERT(rc == 0);