From: Jesper Devantier <jwd@defmacro.it>
To: jwd@defmacro.it, qemu-devel@nongnu.org
Cc: "Philippe Mathieu-Daudé" <philmd@linaro.org>,
"Keith Busch" <kbusch@kernel.org>,
"Klaus Jensen" <its@irrelevant.dk>,
qemu-block@nongnu.org, "Stefan Hajnoczi" <stefanha@redhat.com>,
"Fam Zheng" <fam@euphon.net>, "Hanna Reitz" <hreitz@redhat.com>,
"Kevin Wolf" <kwolf@redhat.com>,
"Klaus Jensen" <k.jensen@samsung.com>
Subject: [PATCH v3 3/5] hw/nvme: add basic endurance group support
Date: Mon, 20 Feb 2023 12:59:24 +0100 [thread overview]
Message-ID: <20230220115926.54623-4-jwd@defmacro.it> (raw)
In-Reply-To: <20230220115926.54623-1-jwd@defmacro.it>
From: Klaus Jensen <k.jensen@samsung.com>
Add the mandatory Endurance Group identify data structures and log
pages.
For now, all namespaces in a subsystem belongs to a single Endurance
Group.
Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
---
hw/nvme/ctrl.c | 48 +++++++++++++++++++++++++++++++++++++++++++-
hw/nvme/ns.c | 3 +++
hw/nvme/nvme.h | 4 ++++
include/block/nvme.h | 42 +++++++++++++++++++++++++++++++-------
4 files changed, 89 insertions(+), 8 deletions(-)
diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
index 99b92ff20b..729ed9adc5 100644
--- a/hw/nvme/ctrl.c
+++ b/hw/nvme/ctrl.c
@@ -4454,6 +4454,44 @@ static uint16_t nvme_smart_info(NvmeCtrl *n, uint8_t rae, uint32_t buf_len,
return nvme_c2h(n, (uint8_t *) &smart + off, trans_len, req);
}
+static uint16_t nvme_endgrp_info(NvmeCtrl *n, uint8_t rae, uint32_t buf_len,
+ uint64_t off, NvmeRequest *req)
+{
+ uint32_t dw11 = le32_to_cpu(req->cmd.cdw11);
+ uint16_t endgrpid = (dw11 >> 16) & 0xffff;
+ struct nvme_stats stats = {};
+ NvmeEndGrpLog info = {};
+ int i;
+
+ if (!n->subsys || endgrpid != 0x1) {
+ return NVME_INVALID_FIELD | NVME_DNR;
+ }
+
+ if (off >= sizeof(info)) {
+ return NVME_INVALID_FIELD | NVME_DNR;
+ }
+
+ for (i = 1; i <= NVME_MAX_NAMESPACES; i++) {
+ NvmeNamespace *ns = nvme_subsys_ns(n->subsys, i);
+ if (!ns) {
+ continue;
+ }
+
+ nvme_set_blk_stats(ns, &stats);
+ }
+
+ info.data_units_read[0] = cpu_to_le64(stats.units_read / 1000000000);
+ info.data_units_written[0] = cpu_to_le64(stats.units_written / 1000000000);
+ info.media_units_written[0] = cpu_to_le64(stats.units_written / 1000000000);
+ info.host_read_commands[0] = cpu_to_le64(stats.read_commands);
+ info.host_write_commands[0] = cpu_to_le64(stats.write_commands);
+
+ buf_len = MIN(sizeof(info) - off, buf_len);
+
+ return nvme_c2h(n, (uint8_t *)&info + off, buf_len, req);
+}
+
+
static uint16_t nvme_fw_log_info(NvmeCtrl *n, uint32_t buf_len, uint64_t off,
NvmeRequest *req)
{
@@ -4626,6 +4664,8 @@ static uint16_t nvme_get_log(NvmeCtrl *n, NvmeRequest *req)
return nvme_changed_nslist(n, rae, len, off, req);
case NVME_LOG_CMD_EFFECTS:
return nvme_cmd_effects(n, csi, len, off, req);
+ case NVME_LOG_ENDGRP:
+ return nvme_endgrp_info(n, rae, len, off, req);
default:
trace_pci_nvme_err_invalid_log_page(nvme_cid(req), lid);
return NVME_INVALID_FIELD | NVME_DNR;
@@ -7382,6 +7422,7 @@ static void nvme_init_ctrl(NvmeCtrl *n, PCIDevice *pci_dev)
uint8_t *pci_conf = pci_dev->config;
uint64_t cap = ldq_le_p(&n->bar.cap);
NvmeSecCtrlEntry *sctrl = nvme_sctrl(n);
+ uint32_t ctratt;
id->vid = cpu_to_le16(pci_get_word(pci_conf + PCI_VENDOR_ID));
id->ssvid = cpu_to_le16(pci_get_word(pci_conf + PCI_SUBSYSTEM_VENDOR_ID));
@@ -7392,7 +7433,7 @@ static void nvme_init_ctrl(NvmeCtrl *n, PCIDevice *pci_dev)
id->cntlid = cpu_to_le16(n->cntlid);
id->oaes = cpu_to_le32(NVME_OAES_NS_ATTR);
- id->ctratt |= cpu_to_le32(NVME_CTRATT_ELBAS);
+ ctratt = NVME_CTRATT_ELBAS;
id->rab = 6;
@@ -7459,8 +7500,13 @@ static void nvme_init_ctrl(NvmeCtrl *n, PCIDevice *pci_dev)
if (n->subsys) {
id->cmic |= NVME_CMIC_MULTI_CTRL;
+ ctratt |= NVME_CTRATT_ENDGRPS;
+
+ id->endgidmax = cpu_to_le16(0x1);
}
+ id->ctratt = cpu_to_le32(ctratt);
+
NVME_CAP_SET_MQES(cap, 0x7ff);
NVME_CAP_SET_CQR(cap, 1);
NVME_CAP_SET_TO(cap, 0xf);
diff --git a/hw/nvme/ns.c b/hw/nvme/ns.c
index 8ebab4fbce..23872a174c 100644
--- a/hw/nvme/ns.c
+++ b/hw/nvme/ns.c
@@ -592,6 +592,8 @@ static void nvme_ns_realize(DeviceState *dev, Error **errp)
if (subsys) {
subsys->namespaces[nsid] = ns;
+ ns->id_ns.endgid = cpu_to_le16(0x1);
+
if (ns->params.detached) {
return;
}
@@ -607,6 +609,7 @@ static void nvme_ns_realize(DeviceState *dev, Error **errp)
return;
}
+
}
nvme_attach_ns(n, ns);
diff --git a/hw/nvme/nvme.h b/hw/nvme/nvme.h
index 5d221073ac..a88e0dea5c 100644
--- a/hw/nvme/nvme.h
+++ b/hw/nvme/nvme.h
@@ -45,6 +45,10 @@ typedef struct NvmeBus {
OBJECT_CHECK(NvmeSubsystem, (obj), TYPE_NVME_SUBSYS)
#define SUBSYS_SLOT_RSVD (void *)0xFFFF
+typedef struct NvmeEnduranceGroup {
+ uint8_t event_conf;
+} NvmeEnduranceGroup;
+
typedef struct NvmeSubsystem {
DeviceState parent_obj;
NvmeBus bus;
diff --git a/include/block/nvme.h b/include/block/nvme.h
index 8027b7126b..4abc1bbfa5 100644
--- a/include/block/nvme.h
+++ b/include/block/nvme.h
@@ -58,6 +58,24 @@ enum NvmeBarRegs {
NVME_REG_PMRMSCU = offsetof(NvmeBar, pmrmscu),
};
+typedef struct QEMU_PACKED NvmeEndGrpLog {
+ uint8_t critical_warning;
+ uint8_t rsvd[2];
+ uint8_t avail_spare;
+ uint8_t avail_spare_thres;
+ uint8_t percet_used;
+ uint8_t rsvd1[26];
+ uint64_t end_estimate[2];
+ uint64_t data_units_read[2];
+ uint64_t data_units_written[2];
+ uint64_t media_units_written[2];
+ uint64_t host_read_commands[2];
+ uint64_t host_write_commands[2];
+ uint64_t media_integrity_errors[2];
+ uint64_t no_err_info_log_entries[2];
+ uint8_t rsvd2[352];
+} NvmeEndGrpLog;
+
enum NvmeCapShift {
CAP_MQES_SHIFT = 0,
CAP_CQR_SHIFT = 16,
@@ -1005,11 +1023,12 @@ enum {
};
enum NvmeLogIdentifier {
- NVME_LOG_ERROR_INFO = 0x01,
- NVME_LOG_SMART_INFO = 0x02,
- NVME_LOG_FW_SLOT_INFO = 0x03,
- NVME_LOG_CHANGED_NSLIST = 0x04,
- NVME_LOG_CMD_EFFECTS = 0x05,
+ NVME_LOG_ERROR_INFO = 0x01,
+ NVME_LOG_SMART_INFO = 0x02,
+ NVME_LOG_FW_SLOT_INFO = 0x03,
+ NVME_LOG_CHANGED_NSLIST = 0x04,
+ NVME_LOG_CMD_EFFECTS = 0x05,
+ NVME_LOG_ENDGRP = 0x09,
};
typedef struct QEMU_PACKED NvmePSD {
@@ -1091,7 +1110,10 @@ typedef struct QEMU_PACKED NvmeIdCtrl {
uint16_t mntmt;
uint16_t mxtmt;
uint32_t sanicap;
- uint8_t rsvd332[180];
+ uint8_t rsvd332[6];
+ uint16_t nsetidmax;
+ uint16_t endgidmax;
+ uint8_t rsvd342[170];
uint8_t sqes;
uint8_t cqes;
uint16_t maxcmd;
@@ -1134,6 +1156,7 @@ enum NvmeIdCtrlOaes {
};
enum NvmeIdCtrlCtratt {
+ NVME_CTRATT_ENDGRPS = 1 << 4,
NVME_CTRATT_ELBAS = 1 << 15,
};
@@ -1227,6 +1250,7 @@ enum NvmeNsAttachmentOperation {
#define NVME_AEC_SMART(aec) (aec & 0xff)
#define NVME_AEC_NS_ATTR(aec) ((aec >> 8) & 0x1)
#define NVME_AEC_FW_ACTIVATION(aec) ((aec >> 9) & 0x1)
+#define NVME_AEC_ENDGRP_NOTICE(aec) ((aec >> 14) & 0x1)
#define NVME_ERR_REC_TLER(err_rec) (err_rec & 0xffff)
#define NVME_ERR_REC_DULBE(err_rec) (err_rec & 0x10000)
@@ -1338,7 +1362,10 @@ typedef struct QEMU_PACKED NvmeIdNs {
uint16_t mssrl;
uint32_t mcl;
uint8_t msrc;
- uint8_t rsvd81[23];
+ uint8_t rsvd81[18];
+ uint8_t nsattr;
+ uint16_t nvmsetid;
+ uint16_t endgid;
uint8_t nguid[16];
uint64_t eui64;
NvmeLBAF lbaf[NVME_MAX_NLBAF];
@@ -1655,5 +1682,6 @@ static inline void _nvme_check_size(void)
QEMU_BUILD_BUG_ON(sizeof(NvmePriCtrlCap) != 4096);
QEMU_BUILD_BUG_ON(sizeof(NvmeSecCtrlEntry) != 32);
QEMU_BUILD_BUG_ON(sizeof(NvmeSecCtrlList) != 4096);
+ QEMU_BUILD_BUG_ON(sizeof(NvmeEndGrpLog) != 512);
}
#endif
--
2.39.2
next prev parent reply other threads:[~2023-02-20 12:00 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-02-20 11:59 [PATCH v3 0/5] Support Flexible Data Placement (FDP) Jesper Devantier
2023-02-20 11:59 ` [PATCH v3 1/5] hw/nvme: move adjustment of data_units{read,written} Jesper Devantier
2023-02-24 8:20 ` Joel Granados
2023-02-24 9:34 ` Klaus Jensen
2023-02-20 11:59 ` [PATCH v3 2/5] hw/nvme: store a pointer to the NvmeSubsystem in the NvmeNamespace Jesper Devantier
2023-02-20 11:59 ` Jesper Devantier [this message]
[not found] ` <CGME20230224085102eucas1p1d57ca7e6909c74db00799be1cff4d9d6@eucas1p1.samsung.com>
2023-02-24 8:51 ` [PATCH v3 3/5] hw/nvme: add basic endurance group support Joel Granados
2023-02-24 9:32 ` Klaus Jensen
2023-02-20 11:59 ` [PATCH v3 4/5] hw/nvme: basic directives support Jesper Devantier
2023-02-20 11:59 ` [PATCH v3 5/5] hw/nvme: flexible data placement emulation Jesper Devantier
2023-03-06 13:32 ` [PATCH v3 0/5] Support Flexible Data Placement (FDP) Klaus Jensen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230220115926.54623-4-jwd@defmacro.it \
--to=jwd@defmacro.it \
--cc=fam@euphon.net \
--cc=hreitz@redhat.com \
--cc=its@irrelevant.dk \
--cc=k.jensen@samsung.com \
--cc=kbusch@kernel.org \
--cc=kwolf@redhat.com \
--cc=philmd@linaro.org \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).