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: Michael Haeuptle <michael.haeuptle@hpe.com>
Change-Id: If4ffae1bd92d4d16a62ec2b6a01f7373223b5705
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/5488
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Vasuki Manikarnike <vasuki.manikarnike@hpe.com>
Community-CI: Broadcom CI
Community-CI: Mellanox Build Bot
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
Michael Haeuptle 2020-12-08 16:57:22 +00:00 committed by Tomasz Zawadzki
parent 64739a7a24
commit 02d3d439be
4 changed files with 57 additions and 0 deletions

View File

@ -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

View File

@ -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.
*

View File

@ -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)
{

View File

@ -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;