From nobody Mon Feb 9 21:12:00 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=kioxia.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1666395342921194.03550343632912; Fri, 21 Oct 2022 16:35:42 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1om1Ag-0006PW-P1; Fri, 21 Oct 2022 19:11:23 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1om1Af-0006PO-6v for qemu-devel@nongnu.org; Fri, 21 Oct 2022 19:11:21 -0400 Received: from usmailhost21.kioxia.com ([12.0.68.226] helo=SJSMAIL01.us.kioxia.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1om1Ad-0005ry-DX for qemu-devel@nongnu.org; Fri, 21 Oct 2022 19:11:20 -0400 Received: from localhost.localdomain (10.93.83.20) by SJSMAIL01.us.kioxia.com (10.90.133.90) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.32; Fri, 21 Oct 2022 16:10:51 -0700 From: To: CC: Keith Busch , Klaus Jensen , Fam Zheng , =?UTF-8?q?Phlippe=20Mathieu-Daud=C3=A9?= Subject: [PATCH V2 4/4] hw/block/nvme: add zone descriptor changed AEN Date: Fri, 21 Oct 2022 16:10:38 -0700 Message-ID: <20221021231038.1042659-5-clay.mayers@kioxia.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20221021231038.1042659-1-clay.mayers@kioxia.com> References: <20221021231038.1042659-1-clay.mayers@kioxia.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Originating-IP: [10.93.83.20] X-ClientProxiedBy: SJSMAIL01.us.kioxia.com (10.90.133.90) To SJSMAIL01.us.kioxia.com (10.90.133.90) Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=12.0.68.226; envelope-from=Clay.Mayers@kioxia.com; helo=SJSMAIL01.us.kioxia.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Qemu-devel" Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1666395345005100001 Content-Type: text/plain; charset="utf-8" From: Clay Mayers 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 --- hw/nvme/ctrl.c | 63 +++++++++++++++++++++++++++++++++++++++++++- hw/nvme/ns.c | 1 + hw/nvme/nvme.h | 11 ++++++++ include/block/nvme.h | 2 ++ 4 files changed, 76 insertions(+), 1 deletion(-) diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c index 4fb85160cc..be6147363d 100644 --- a/hw/nvme/ctrl.c +++ b/hw/nvme/ctrl.c @@ -1519,6 +1519,52 @@ static void nvme_clear_events(NvmeCtrl *n, uint8_t e= vent_type) } } =20 +static void nvme_zdc_watch(NvmeCtrl *n, NvmeNamespace *ns, NvmeNotifyFnc f= nc) +{ + NvmeZdcNotify *watcher =3D g_malloc0(sizeof(*watcher)); + + watcher->n =3D n; + watcher->notify =3D 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 =3D=3D 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 =3D 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 r= eset) { NvmeZdc *zdc; @@ -1554,6 +1600,7 @@ static void nvme_check_finish(NvmeNamespace *ns, Nvme= ZoneListHead *list) zdc->zone =3D zone; zone->zdc_entry =3D zdc; QTAILQ_INSERT_TAIL(&ns->zdc_list, zdc, entry); + nvme_zdc_notify(ns); } } else if (zone->finish_ms !=3D INT64_MAX) { timer_mod_anticipate(ns->active_timer, zone->finish_ms); @@ -4727,6 +4774,14 @@ static uint16_t nvme_changed_zones(NvmeCtrl *n, uint= 8_t rae, uint32_t buf_len, return NVME_INVALID_NSID | NVME_DNR; } nvme_zdc_list(ns, &zlist, !rae); + if (!rae) { + n->zdc_event_queued =3D 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); + } + } =20 trans_len =3D MIN(sizeof(zlist) - off, buf_len); =20 @@ -5815,6 +5870,7 @@ static uint16_t nvme_ns_attachment(NvmeCtrl *n, NvmeR= equest *req) return NVME_NS_NOT_ATTACHED | NVME_DNR; } =20 + nvme_zdc_unwatch(n, ns); ctrl->namespaces[nsid] =3D NULL; ns->attached--; =20 @@ -7542,7 +7598,7 @@ static void nvme_init_ctrl(NvmeCtrl *n, PCIDevice *pc= i_dev) =20 id->cntlid =3D cpu_to_le16(n->cntlid); =20 - id->oaes =3D cpu_to_le32(NVME_OAES_NS_ATTR); + id->oaes =3D cpu_to_le32(NVME_OAES_NS_ATTR | NVME_OAES_ZDC); id->ctratt |=3D cpu_to_le32(NVME_CTRATT_ELBAS); =20 id->rab =3D 6; @@ -7659,6 +7715,10 @@ void nvme_attach_ns(NvmeCtrl *n, NvmeNamespace *ns) =20 n->dmrsl =3D 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); + } } =20 static void nvme_realize(PCIDevice *pci_dev, Error **errp) @@ -7721,6 +7781,7 @@ static void nvme_exit(PCIDevice *pci_dev) for (i =3D 1; i <=3D NVME_MAX_NAMESPACES; i++) { ns =3D nvme_ns(n, i); if (ns) { + nvme_zdc_unwatch(n, ns); ns->attached--; } } 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); =20 zone =3D ns->zone_array; for (i =3D 0; i < ns->num_zones; i++, zone++) { diff --git a/hw/nvme/nvme.h b/hw/nvme/nvme.h index ae65226150..5499105e7b 100644 --- a/hw/nvme/nvme.h +++ b/hw/nvme/nvme.h @@ -91,6 +91,14 @@ static inline NvmeNamespace *nvme_subsys_ns(NvmeSubsyste= m *subsys, #define NVME_NS(obj) \ OBJECT_CHECK(NvmeNamespace, (obj), TYPE_NVME_NS) =20 +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 { =20 int64_t fto_ms; QEMUTimer *active_timer; + QTAILQ_HEAD(, NvmeZdcNotify) zdc_watchers; QTAILQ_HEAD(, NvmeZdc) zdc_list; =20 NvmeNamespaceParams params; @@ -477,6 +486,8 @@ typedef struct NvmeCtrl { uint64_t dbbuf_eis; bool dbbuf_enabled; =20 + bool zdc_event_queued; + struct { MemoryRegion mem; uint8_t *buf; 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 =3D 1, NVME_AER_INFO_SMART_SPARE_THRESH =3D 2, NVME_AER_INFO_NOTICE_NS_ATTR_CHANGED =3D 0, + NVME_AER_INFO_NOTICE_ZONE_DESC_CHANGED =3D 0xef, }; =20 typedef struct QEMU_PACKED NvmeAerResult { @@ -1133,6 +1134,7 @@ typedef struct NvmeIdCtrlNvm { =20 enum NvmeIdCtrlOaes { NVME_OAES_NS_ATTR =3D 1 << 8, + NVME_OAES_ZDC =3D 1 << 27, }; =20 enum NvmeIdCtrlCtratt { --=20 2.27.0