Commit 02d3d439 authored by Michael Haeuptle's avatar Michael Haeuptle Committed by Tomasz Zawadzki
Browse files

nvme: New function to perform a NVMe subsystem reset



This commit introduces spdk_nvme_ctrlr_subsystem_reset to
perform a NVMe subsystem reset according to the NVMe spec.

Signed-off-by: default avatarMichael Haeuptle <michael.haeuptle@hpe.com>
Change-Id: If4ffae1bd92d4d16a62ec2b6a01f7373223b5705
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/5488


Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarAleksey Marchuk <alexeymar@mellanox.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: default avatarVasuki Manikarnike <vasuki.manikarnike@hpe.com>
Community-CI: Broadcom CI
Community-CI: Mellanox Build Bot
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
parent 64739a7a
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -24,6 +24,10 @@ An `opts_size` element was added in the `spdk_blob_open_opts` structure to solve
ABI compatiblity issue between different SPDK version. And also add `opts_size`
parameter in `spdk_blob_open_opts_init` function.

### nvme

Added a new function `spdk_nvme_ctrlr_reset_subsystem` to perform a NVMe
subsystem reset. Note: The NVMf target does not support the subsystem reset yet.

### event

+19 −0
Original line number Diff line number Diff line
@@ -900,6 +900,25 @@ void spdk_nvme_ctrlr_set_remove_cb(struct spdk_nvme_ctrlr *ctrlr,
 */
int spdk_nvme_ctrlr_reset(struct spdk_nvme_ctrlr *ctrlr);

/**
 * Perform a NVMe subsystem reset.
 *
 * This function should be called from a single thread while no other threads
 * are actively using the NVMe device.
 * A subsystem reset is typically seen by the OS as a hot remove, followed by a
 * hot add event.
 *
 * Any pointers returned from spdk_nvme_ctrlr_get_ns(), spdk_nvme_ns_get_data(),
 * spdk_nvme_zns_ns_get_data(), and spdk_nvme_zns_ctrlr_get_data()
 * may be invalidated by calling this function. The number of namespaces as returned
 * by spdk_nvme_ctrlr_get_num_ns() may also change.
 *
 * \param ctrlr Opaque handle to NVMe controller.
 *
 * \return 0 on success, -1 on failure, -ENOTSUP if subsystem reset is not supported.
 */
int spdk_nvme_ctrlr_reset_subsystem(struct spdk_nvme_ctrlr *ctrlr);

/**
 * Fail the given NVMe controller.
 *
+33 −0
Original line number Diff line number Diff line
@@ -91,6 +91,13 @@ nvme_ctrlr_get_cmbsz(struct spdk_nvme_ctrlr *ctrlr, union spdk_nvme_cmbsz_regist
					      &cmbsz->raw);
}

static int
nvme_ctrlr_set_nssr(struct spdk_nvme_ctrlr *ctrlr, uint32_t nssr_value)
{
	return nvme_transport_ctrlr_set_reg_4(ctrlr, offsetof(struct spdk_nvme_registers, nssr),
					      nssr_value);
}

bool
nvme_ctrlr_multi_iocs_enabled(struct spdk_nvme_ctrlr *ctrlr)
{
@@ -1431,6 +1438,32 @@ out:
	return rc;
}

int
spdk_nvme_ctrlr_reset_subsystem(struct spdk_nvme_ctrlr *ctrlr)
{
	union spdk_nvme_cap_register cap;
	int rc = 0;

	cap = spdk_nvme_ctrlr_get_regs_cap(ctrlr);
	if (cap.bits.nssrs == 0) {
		SPDK_WARNLOG("subsystem reset is not supported\n");
		return -ENOTSUP;
	}

	SPDK_NOTICELOG("resetting subsystem\n");
	nvme_robust_mutex_lock(&ctrlr->ctrlr_lock);
	ctrlr->is_resetting = true;
	rc = nvme_ctrlr_set_nssr(ctrlr, SPDK_NVME_NSSR_VALUE);
	ctrlr->is_resetting = false;

	nvme_robust_mutex_unlock(&ctrlr->ctrlr_lock);
	/*
	 * No more cleanup at this point like in the ctrlr reset. A subsystem reset will cause
	 * a hot remove for PCIe transport. The hot remove handling does all the necessary ctrlr cleanup.
	 */
	return rc;
}

int
spdk_nvme_ctrlr_set_trid(struct spdk_nvme_ctrlr *ctrlr, struct spdk_nvme_transport_id *trid)
{
+1 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@
	spdk_nvme_ctrlr_is_discovery;
	spdk_nvme_ctrlr_get_default_ctrlr_opts;
	spdk_nvme_ctrlr_set_trid;
	spdk_nvme_ctrlr_reset_subsystem;
	spdk_nvme_ctrlr_reset;
	spdk_nvme_ctrlr_fail;
	spdk_nvme_ctrlr_is_failed;