Commit 6f226573 authored by Shuhei Matsumoto's avatar Shuhei Matsumoto Committed by Tomasz Zawadzki
Browse files

lib/nvmf: Optionalize ANA reporting feature



After supporting ANA reporting by default, Linux kernel 5.3 reported
error when parsing NVMe ANA log. The newer kernel fixed the issue
but we should optionalize ANA reporting feature to avoid error for
Linux kernel 5.3 or before.

Add a bool variable ana_reporting to struct spdk_nvmf_subsystem
and disable ANA reporting and initialization of related variables
if it is false. We can expose MNAN (Maximum Number of Allowed
Namespaces) even if ANA reporting is disabled. But MNAN is not
required if ANA reporting is disabled. So do not set MNAN if it is
false too.

Add a public API spdk_nvmf_subsystem_set_ana_reporting() to set
ana_reporting by the nvmf_create_subssytem RPC.

The next patch will add ana_reporting to nvmf_create_subsystem RPC.

Signed-off-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Change-Id: Icc77773b4c9513daba2f1a9fdaf951d80574f379
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/3850


Community-CI: Mellanox Build Bot
Community-CI: Broadcom CI
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Reviewed-by: default avatarMonica Kenguva <monica.kenguva@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
parent 4cc04a12
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -654,6 +654,20 @@ void spdk_nvmf_subsystem_allow_any_listener(
bool spdk_nvmf_subsytem_any_listener_allowed(
	struct spdk_nvmf_subsystem *subsystem);

/**
 * Set whether a subsystem supports Asymmetric Namespace Access (ANA)
 * reporting.
 *
 * May only be performed on subsystems in the INACTIVE state.
 *
 * \param subsystem Subsystem to modify.
 * \param ana_reporting true to support or false not to support ANA reporting.
 *
 * \return 0 on success, or negated errno value on failure.
 */
int spdk_nvmf_subsystem_set_ana_reporting(struct spdk_nvmf_subsystem *subsystem,
		bool ana_reporting);

/** NVMe-oF target namespace creation options */
struct spdk_nvmf_ns_opts {
	/**
+24 −12
Original line number Diff line number Diff line
@@ -1903,8 +1903,12 @@ nvmf_ctrlr_get_log_page(struct spdk_nvmf_request *req)
			nvmf_get_firmware_slot_log_page(req->data, offset, len);
			return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE;
		case SPDK_NVME_LOG_ASYMMETRIC_NAMESPACE_ACCESS:
			if (subsystem->ana_reporting) {
				nvmf_get_ana_log_page(ctrlr, req->data, offset, len);
				return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE;
			} else {
				goto invalid_log_page;
			}
		case SPDK_NVME_LOG_COMMAND_EFFECTS_LOG:
			nvmf_get_cmds_and_effects_log_page(req->data, offset, len);
			return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE;
@@ -1965,8 +1969,10 @@ spdk_nvmf_ctrlr_identify_ns(struct spdk_nvmf_ctrlr *ctrlr,
		nsdata->noiob = max_num_blocks;
	}

	if (subsystem->ana_reporting) {
		/* ANA group ID matches NSID. */
		nsdata->anagrpid = ns->nsid;
	}

	return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE;
}
@@ -2017,7 +2023,9 @@ spdk_nvmf_ctrlr_identify_ctrlr(struct spdk_nvmf_ctrlr *ctrlr, struct spdk_nvme_c
	cdata->sgls = ctrlr->cdata.sgls;
	cdata->fuses.compare_and_write = 1;
	cdata->acwu = 1;
	if (subsystem->ana_reporting) {
		cdata->mnan = subsystem->max_nsid;
	}
	spdk_strcpy_pad(cdata->subnqn, subsystem->subnqn, sizeof(cdata->subnqn), '\0');

	SPDK_DEBUGLOG(SPDK_LOG_NVMF, "ctrlr data: maxcmd 0x%x\n", cdata->maxcmd);
@@ -2034,8 +2042,10 @@ spdk_nvmf_ctrlr_identify_ctrlr(struct spdk_nvmf_ctrlr *ctrlr, struct spdk_nvme_c
		cdata->rab = 6;
		cdata->cmic.multi_port = 1;
		cdata->cmic.multi_host = 1;
		if (subsystem->ana_reporting) {
			/* Asymmetric Namespace Access Reporting is supported. */
			cdata->cmic.ana_reporting = 1;
		}
		cdata->oaes.ns_attribute_notices = 1;
		cdata->ctratt.host_id_exhid_supported = 1;
		/* TODO: Concurrent execution of multiple abort commands. */
@@ -2059,11 +2069,13 @@ spdk_nvmf_ctrlr_identify_ctrlr(struct spdk_nvmf_ctrlr *ctrlr, struct spdk_nvme_c
		cdata->oncs.dsm = nvmf_ctrlr_dsm_supported(ctrlr);
		cdata->oncs.write_zeroes = nvmf_ctrlr_write_zeroes_supported(ctrlr);
		cdata->oncs.reservations = 1;
		if (subsystem->ana_reporting) {
			cdata->anacap.ana_optimized_state = 1;
			/* ANAGRPID does not change while namespace is attached to controller */
			cdata->anacap.no_change_anagrpid = 1;
			cdata->anagrpmax = subsystem->max_nsid;
			cdata->nanagrpid = subsystem->max_nsid;
		}

		nvmf_ctrlr_populate_oacs(ctrlr, cdata);

+1 −0
Original line number Diff line number Diff line
@@ -249,6 +249,7 @@ struct spdk_nvmf_subsystem {
	uint16_t next_cntlid;
	bool allow_any_host;
	bool allow_any_listener;
	bool ana_reporting;

	struct spdk_nvmf_tgt			*tgt;

+1 −0
Original line number Diff line number Diff line
@@ -79,6 +79,7 @@
	spdk_nvmf_transport_poll_group_get_stat;
	spdk_nvmf_transport_poll_group_free_stat;
	spdk_nvmf_rdma_init_hooks;
	spdk_nvmf_subsystem_set_ana_reporting;

	# public functions in nvmf_cmd.h
	spdk_nvmf_ctrlr_identify_ctrlr;
+13 −0
Original line number Diff line number Diff line
@@ -2513,3 +2513,16 @@ nvmf_ns_reservation_request(void *ctx)
update_done:
	_nvmf_ns_reservation_update_done(ctrlr->subsys, (void *)req, 0);
}

int
spdk_nvmf_subsystem_set_ana_reporting(struct spdk_nvmf_subsystem *subsystem,
				      bool ana_reporting)
{
	if (subsystem->state != SPDK_NVMF_SUBSYSTEM_INACTIVE) {
		return -EAGAIN;
	}

	subsystem->ana_reporting = ana_reporting;

	return 0;
}