hw/block/nvme: Process controller reset and shutdown differently

Controller reset ans subsystem shutdown are handled very much the same
in the current code, but some of the steps should be different in these
two cases.

Introduce two new functions, nvme_reset_ctrl() and nvme_shutdown_ctrl(),
to separate some portions of the code from nvme_clear_ctrl(). The steps
that are made different between reset and shutdown are that BAR.CC is not
reset to zero upon the shutdown and namespace data is flushed to
backing storage as a part of shutdown handling, but not upon reset.

Suggested-by: Klaus Jensen <k.jensen@samsung.com>
Signed-off-by: Dmitry Fomichev <dmitry.fomichev@wdc.com>
Reviewed-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
This commit is contained in:
Dmitry Fomichev 2020-12-09 05:03:58 +09:00 committed by Klaus Jensen
parent e1f81c1478
commit ba69f22481
3 changed files with 20 additions and 8 deletions

View File

@ -129,7 +129,7 @@ void nvme_ns_drain(NvmeNamespace *ns)
blk_drain(ns->blkconf.blk);
}
void nvme_ns_flush(NvmeNamespace *ns)
void nvme_ns_shutdown(NvmeNamespace *ns)
{
blk_flush(ns->blkconf.blk);
}

View File

@ -73,6 +73,6 @@ typedef struct NvmeCtrl NvmeCtrl;
int nvme_ns_setup(NvmeCtrl *n, NvmeNamespace *ns, Error **errp);
void nvme_ns_drain(NvmeNamespace *ns);
void nvme_ns_flush(NvmeNamespace *ns);
void nvme_ns_shutdown(NvmeNamespace *ns);
#endif /* NVME_NS_H */

View File

@ -2295,6 +2295,20 @@ static void nvme_clear_ctrl(NvmeCtrl *n)
n->aer_queued = 0;
n->outstanding_aers = 0;
n->qs_created = false;
}
static void nvme_ctrl_reset(NvmeCtrl *n)
{
nvme_clear_ctrl(n);
n->bar.cc = 0;
}
static void nvme_ctrl_shutdown(NvmeCtrl *n)
{
NvmeNamespace *ns;
int i;
nvme_clear_ctrl(n);
for (i = 1; i <= n->num_namespaces; i++) {
ns = nvme_ns(n, i);
@ -2302,10 +2316,8 @@ static void nvme_clear_ctrl(NvmeCtrl *n)
continue;
}
nvme_ns_flush(ns);
nvme_ns_shutdown(ns);
}
n->bar.cc = 0;
}
static int nvme_start_ctrl(NvmeCtrl *n)
@ -2472,12 +2484,12 @@ static void nvme_write_bar(NvmeCtrl *n, hwaddr offset, uint64_t data,
}
} else if (!NVME_CC_EN(data) && NVME_CC_EN(n->bar.cc)) {
trace_pci_nvme_mmio_stopped();
nvme_clear_ctrl(n);
nvme_ctrl_reset(n);
n->bar.csts &= ~NVME_CSTS_READY;
}
if (NVME_CC_SHN(data) && !(NVME_CC_SHN(n->bar.cc))) {
trace_pci_nvme_mmio_shutdown_set();
nvme_clear_ctrl(n);
nvme_ctrl_shutdown(n);
n->bar.cc = data;
n->bar.csts |= NVME_CSTS_SHST_COMPLETE;
} else if (!NVME_CC_SHN(data) && NVME_CC_SHN(n->bar.cc)) {
@ -3088,7 +3100,7 @@ static void nvme_exit(PCIDevice *pci_dev)
{
NvmeCtrl *n = NVME(pci_dev);
nvme_clear_ctrl(n);
nvme_ctrl_shutdown(n);
g_free(n->cq);
g_free(n->sq);
g_free(n->aer_reqs);