Commit 072f2d00 authored by Shuhei Matsumoto's avatar Shuhei Matsumoto Committed by Tomasz Zawadzki
Browse files

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: default avatarShuhei 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: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarAleksey Marchuk <alexeymar@mellanox.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
parent 7ec6d1d5
Loading
Loading
Loading
Loading
+83 −1
Original line number Diff line number Diff line
@@ -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);
	}
}

+22 −4
Original line number Diff line number Diff line
@@ -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);