From: <clay.mayers@kioxia.com>
To: <qemu-devel@nongnu.org>
Cc: "Keith Busch" <kbusch@kernel.org>,
"Klaus Jensen" <its@irrelevant.dk>, "Fam Zheng" <fam@euphon.net>,
"Phlippe Mathieu-Daudé" <f4bug@amsat.org>
Subject: [PATCH 4/4] hw/block/nvme: add zone descriptor changed AEN
Date: Thu, 20 Oct 2022 17:18:35 -0700 [thread overview]
Message-ID: <20221021001835.942642-5-clay.mayers@kioxia.com> (raw)
In-Reply-To: <20221021001835.942642-1-clay.mayers@kioxia.com>
From: Clay Mayers <clay.mayers@kioxia.com>
If a namespace's param.zoned.finish_time is non-zero,
controllers register with the namespace to be notified
when entries are added to its zone-descriptor-changed
log page. If the zone-descriptor-changed aen is enabled,
this will cause an AEN to be sent from that controller.
Signed-off-by: Clay Mayers <clay.mayers@kioxia.com>
---
hw/nvme/ctrl.c | 62 +++++++++++++++++++++++++++++++++++++++++++-
hw/nvme/ns.c | 1 +
hw/nvme/nvme.h | 9 +++++++
include/block/nvme.h | 2 ++
4 files changed, 73 insertions(+), 1 deletion(-)
diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
index c7ee54ef5e..f1cfa272b4 100644
--- a/hw/nvme/ctrl.c
+++ b/hw/nvme/ctrl.c
@@ -1519,6 +1519,52 @@ static void nvme_clear_events(NvmeCtrl *n, uint8_t event_type)
}
}
+static void nvme_zdc_watch(NvmeCtrl *n, NvmeNamespace *ns, NvmeNotifyFnc fnc)
+{
+ NvmeZdcNotify *watcher = g_malloc0(sizeof(*watcher));
+
+ watcher->n = n;
+ watcher->notify = fnc;
+ QTAILQ_INSERT_TAIL(&ns->zdc_watchers, watcher, entry);
+}
+
+static void nvme_zdc_unwatch(NvmeCtrl *n, NvmeNamespace *ns)
+{
+ NvmeZdcNotify *watcher;
+
+ QTAILQ_FOREACH(watcher, &ns->zdc_watchers, entry) {
+ if (watcher->n == n) {
+ QTAILQ_REMOVE(&ns->zdc_watchers, watcher, entry);
+ break;
+ }
+ }
+}
+
+static void nvme_zdc_notify(NvmeNamespace *ns)
+{
+ NvmeZdcNotify *watcher;
+
+ QTAILQ_FOREACH(watcher, &ns->zdc_watchers, entry) {
+ (*watcher->notify)(watcher->n, ns);
+ }
+}
+
+static void nvme_zdc_aen(NvmeCtrl *n, NvmeNamespace *ns)
+{
+ g_assert(n->id_ctrl.oaes & (1 << 27));
+
+ if (!NVME_AEC_ZONE_CHANGED(n->features.async_config)) {
+ return;
+ }
+
+ if (!n->zdc_event_queued) {
+ n->zdc_event_queued = true;
+ nvme_enqueue_event(n, NVME_AER_TYPE_NOTICE,
+ NVME_AER_INFO_NOTICE_ZONE_DESC_CHANGED,
+ NVME_LOG_CHANGED_ZONE, ns->params.nsid);
+ }
+}
+
static void nvme_zdc_list(NvmeNamespace *ns, NvmeZoneIdList *zlist, bool reset)
{
NvmeZdc *zdc;
@@ -1554,6 +1600,7 @@ static void nvme_check_finish(NvmeNamespace *ns, NvmeZoneListHead *list)
zdc->zone = zone;
zone->zdc_entry = zdc;
QTAILQ_INSERT_TAIL(&ns->zdc_list, zdc, entry);
+ nvme_zdc_notify(ns);
}
} else if (zone->finish_ms != INT64_MAX) {
timer_mod_anticipate(ns->active_timer, zone->finish_ms);
@@ -4722,6 +4769,14 @@ static uint16_t nvme_changed_zones(NvmeCtrl *n, uint8_t rae, uint32_t buf_len,
return NVME_INVALID_NSID | NVME_DNR;
}
nvme_zdc_list(ns, &zlist, !rae);
+ if (!rae) {
+ n->zdc_event_queued = false;
+ nvme_clear_events(n, NVME_AER_TYPE_NOTICE);
+ /* send a new aen if there are still zdc entries */
+ if (!QTAILQ_EMPTY(&ns->zdc_list)) {
+ nvme_zdc_notify(ns);
+ }
+ }
return nvme_c2h(n, ((uint8_t *)&zlist) + off, trans_len, req);
}
@@ -5808,6 +5863,7 @@ static uint16_t nvme_ns_attachment(NvmeCtrl *n, NvmeRequest *req)
return NVME_NS_NOT_ATTACHED | NVME_DNR;
}
+ nvme_zdc_unwatch(n, ns);
ctrl->namespaces[nsid] = NULL;
ns->attached--;
@@ -7535,7 +7591,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->oaes = cpu_to_le32(NVME_OAES_NS_ATTR | NVME_OAES_ZDC);
id->ctratt |= cpu_to_le32(NVME_CTRATT_ELBAS);
id->rab = 6;
@@ -7652,6 +7708,10 @@ void nvme_attach_ns(NvmeCtrl *n, NvmeNamespace *ns)
n->dmrsl = MIN_NON_ZERO(n->dmrsl,
BDRV_REQUEST_MAX_BYTES / nvme_l2b(ns, 1));
+
+ if (ns->params.fto) {
+ nvme_zdc_watch(n, ns, nvme_zdc_aen);
+ }
}
static void nvme_realize(PCIDevice *pci_dev, Error **errp)
diff --git a/hw/nvme/ns.c b/hw/nvme/ns.c
index 25cd490c99..5629b61302 100644
--- a/hw/nvme/ns.c
+++ b/hw/nvme/ns.c
@@ -241,6 +241,7 @@ static void nvme_ns_zoned_init_state(NvmeNamespace *ns)
QTAILQ_INIT(&ns->closed_zones);
QTAILQ_INIT(&ns->full_zones);
QTAILQ_INIT(&ns->zdc_list);
+ QTAILQ_INIT(&ns->zdc_watchers);
zone = ns->zone_array;
for (i = 0; i < ns->num_zones; i++, zone++) {
diff --git a/hw/nvme/nvme.h b/hw/nvme/nvme.h
index 2b7997e4a7..5499105e7b 100644
--- a/hw/nvme/nvme.h
+++ b/hw/nvme/nvme.h
@@ -91,6 +91,14 @@ static inline NvmeNamespace *nvme_subsys_ns(NvmeSubsystem *subsys,
#define NVME_NS(obj) \
OBJECT_CHECK(NvmeNamespace, (obj), TYPE_NVME_NS)
+typedef void (*NvmeNotifyFnc)(NvmeCtrl *n, NvmeNamespace *ns);
+
+typedef struct NvmeZdcNotify {
+ QTAILQ_ENTRY(NvmeZdcNotify) entry;
+ NvmeNotifyFnc notify;
+ NvmeCtrl *n;
+} NvmeZdcNotify;
+
typedef struct NvmeZdc {
QTAILQ_ENTRY(NvmeZdc) entry;
NvmeZone *zone;
@@ -179,6 +187,7 @@ typedef struct NvmeNamespace {
int64_t fto_ms;
QEMUTimer *active_timer;
+ QTAILQ_HEAD(, NvmeZdcNotify) zdc_watchers;
QTAILQ_HEAD(, NvmeZdc) zdc_list;
NvmeNamespaceParams params;
diff --git a/include/block/nvme.h b/include/block/nvme.h
index 9467d4b939..1662046c0d 100644
--- a/include/block/nvme.h
+++ b/include/block/nvme.h
@@ -830,6 +830,7 @@ enum NvmeAsyncEventRequest {
NVME_AER_INFO_SMART_TEMP_THRESH = 1,
NVME_AER_INFO_SMART_SPARE_THRESH = 2,
NVME_AER_INFO_NOTICE_NS_ATTR_CHANGED = 0,
+ NVME_AER_INFO_NOTICE_ZONE_DESC_CHANGED = 0xef,
};
typedef struct QEMU_PACKED NvmeAerResult {
@@ -1133,6 +1134,7 @@ typedef struct NvmeIdCtrlNvm {
enum NvmeIdCtrlOaes {
NVME_OAES_NS_ATTR = 1 << 8,
+ NVME_OAES_ZDC = 1 << 27,
};
enum NvmeIdCtrlCtratt {
--
2.27.0
next prev parent reply other threads:[~2022-10-21 0:38 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-10-21 0:18 [PATCH 0/4] hw/block/nvme: Implement ZNS finish-zone ZDC AEN clay.mayers
2022-10-21 0:18 ` [PATCH 1/4] hw/block/nvme: add ZONE_FINISH_RECOMMENDED functionality clay.mayers
2022-10-21 6:36 ` Klaus Jensen
2022-10-21 0:18 ` [PATCH 2/4] hw/block/nvme: add zone descriptor changed log page clay.mayers
2022-10-21 6:26 ` Klaus Jensen
2022-10-21 15:24 ` Clay Mayers
2022-10-21 0:18 ` [PATCH 3/4] hw/block/nvme: supply dw1 for aen result clay.mayers
2022-10-21 5:59 ` Klaus Jensen
2022-10-21 15:25 ` Clay Mayers
2022-10-21 0:18 ` clay.mayers [this message]
2022-10-21 6:41 ` [PATCH 4/4] hw/block/nvme: add zone descriptor changed AEN Klaus Jensen
2022-10-21 16:39 ` Clay Mayers
2022-10-21 5:57 ` [PATCH 0/4] hw/block/nvme: Implement ZNS finish-zone ZDC AEN 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=20221021001835.942642-5-clay.mayers@kioxia.com \
--to=clay.mayers@kioxia.com \
--cc=f4bug@amsat.org \
--cc=fam@euphon.net \
--cc=its@irrelevant.dk \
--cc=kbusch@kernel.org \
--cc=qemu-devel@nongnu.org \
/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).