From nobody Sat Nov 15 02:02:58 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail header.i=@wdc.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=wdc.com ARC-Seal: i=1; a=rsa-sha256; t=1592430601; cv=none; d=zohomail.com; s=zohoarc; b=cGDsRlI0yigzYjvsaEDN3Iw5/3YnZO1JVfSuNupTfoyLLL1RIWgZ+yGt3KmD8eWrWITnbFX5mISIZ1foh2Hc3RX+H3tjaUmKfhXAecdZszV21H2A9+5x23z7DDgoQH9wkii3VJQtuOVrO+kIe8uVW75GmED1LWVcvFkMU392MK4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1592430601; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=ckVU/brvFIOfmBxns7KTNHFgk96gD+EdvChIm2nPZI8=; b=RSlb9g8tFTBwH46aHsDx4GbqHlXJFoXm5EPlyox0DcfTasFuwk20LdEBt56nInvEHWBcDZ3gVzfnZHJBgLg3FaIo3psNc0Bt2h8MsaM0xNQ0SwA2qWUOUhv1x1OHvllDOuAgMoFnUpGpYw7cCTMjvI1ocZq1H3ywaWP+swja2Bc= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail header.i=@wdc.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 header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1592430601238646.4694981565298; Wed, 17 Jun 2020 14:50:01 -0700 (PDT) Received: from localhost ([::1]:37762 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jlfwV-0005LX-QO for importer@patchew.org; Wed, 17 Jun 2020 17:49:59 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:46250) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jlfiJ-0004Y7-AB; Wed, 17 Jun 2020 17:35:19 -0400 Received: from esa1.hgst.iphmx.com ([68.232.141.245]:29866) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jlfiE-0005I4-99; Wed, 17 Jun 2020 17:35:18 -0400 Received: from uls-op-cesaip02.wdc.com (HELO uls-op-cesaep02.wdc.com) ([199.255.45.15]) by ob1.hgst.iphmx.com with ESMTP; 18 Jun 2020 05:34:51 +0800 Received: from uls-op-cesaip02.wdc.com ([10.248.3.37]) by uls-op-cesaep02.wdc.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jun 2020 14:23:32 -0700 Received: from unknown (HELO redsun50.ssa.fujisawa.hgst.com) ([10.149.66.24]) by uls-op-cesaip02.wdc.com with ESMTP; 17 Jun 2020 14:34:50 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1592429714; x=1623965714; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=rmi02F+uclU5nynYawpXrWkddeuvL3BZWHmUPifm9xI=; b=Ghq7WX7YiLGoY0808Qsewfepe6qf5FmZn6KR5Ed1gHOFRxKOdpWui54x 4Uk5KvGowa2Y94jMZjn9uUnyAplcgj8Crld8n/TVsr1meaYNhZhGgg2Vp doqR009TKbElaDdjVmQDcUMpcCaQcv2rN9LxHBeclzlIcb4auE+S9Sc2L oo4wqu9Q3lVjgRg4Mk965e8EuY7ptH+tJ+GN2rhv3cuntrshFNtm5aui6 dpjc1raS7v6VEEFf+7MLSbc6bFatt2rIjiiv4fWpt5T2/b5kW/Gmni2SM xMO3HvNq2SzGZjMt8WOHyERio3o3VOm9JwbRsk4BTKhb1xap/KSZe4i3t A==; IronPort-SDR: urrtczvvNqUSYgGGg4fwZ28pCehImY+DctLDeyuCez8kClc6D4N5lh+tlrhTIzAgtKgeHRmomj JzePp9JtVF3r8bgafjpnSLcvZwgyh9QCLjhwTYt3AqEoZDGuiOHKDoeOOL81AVYm6EAkVT6gTK uEu3mFGGHBlqVEdsW+sDSbvG52t416DjhCApKAZ89p1SyB1hciOQZ2DV/emTYq1pWi27syc2pO M/o64gUThNkIvf9tS4QjJmirn5OXBASsq7swMjaegfNRwFLTv6Dr4UyUqHRLAB1kbVuC65tUnx 6PU= X-IronPort-AV: E=Sophos;i="5.73,523,1583164800"; d="scan'208";a="249439834" IronPort-SDR: sytCPdMjytxDDLnK1dxXyfYwSL661RbpXOPcNyuOy+9z/4MUXwS35Lr6gYrp586kAzYolq7dKl mW7mvwyYlNGvo0z+Fe+leKQlxnd2xbwDo= IronPort-SDR: R97+zqbGmitN2Bn/Kf/fWfZTL/uu8+f/hKUt/cSOjqc6xYmqoGnJLcgjVZ2QJc3M/A7hxK3IxE foVorlpZnZmg== WDCIronportException: Internal From: Dmitry Fomichev To: Kevin Wolf , Keith Busch , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Maxim Levitsky Subject: [PATCH v2 13/18] hw/block/nvme: Set Finish/Reset Zone Recommended attributes Date: Thu, 18 Jun 2020 06:34:10 +0900 Message-Id: <20200617213415.22417-14-dmitry.fomichev@wdc.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20200617213415.22417-1-dmitry.fomichev@wdc.com> References: <20200617213415.22417-1-dmitry.fomichev@wdc.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable 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=68.232.141.245; envelope-from=prvs=430b82a1d=dmitry.fomichev@wdc.com; helo=esa1.hgst.iphmx.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/06/17 17:34:28 X-ACL-Warn: Detected OS = FreeBSD 9.x or newer [fuzzy] X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Niklas Cassel , Damien Le Moal , qemu-block@nongnu.org, Dmitry Fomichev , qemu-devel@nongnu.org, Matias Bjorling Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" Added logic to set and reset FZR and RZR zone attributes. Four new driver properties are added to control the timing of setting and resetting these attributes. FZR/RZR delay lasts from the zone operation and until when the corresponding zone attribute is set. FZR/RZR limits set the time period between setting FZR or RZR attribute and resetting it simulating the internal controller action on that zone. Signed-off-by: Dmitry Fomichev --- hw/block/nvme.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++ hw/block/nvme.h | 13 ++++++- 2 files changed, 111 insertions(+), 1 deletion(-) diff --git a/hw/block/nvme.c b/hw/block/nvme.c index a29cbfcc96..c3898448c7 100644 --- a/hw/block/nvme.c +++ b/hw/block/nvme.c @@ -201,6 +201,84 @@ static inline void nvme_aor_dec_active(NvmeCtrl *n, Nv= meNamespace *ns) assert(ns->nr_active_zones >=3D 0); } =20 +static void nvme_set_rzr(NvmeCtrl *n, NvmeNamespace *ns, NvmeZone *zone) +{ + assert(zone->flags & NVME_ZFLAGS_SET_RZR); + zone->tstamp =3D qemu_clock_get_ns(QEMU_CLOCK_REALTIME); + zone->flags &=3D ~NVME_ZFLAGS_TS_DELAY; + zone->d.za |=3D NVME_ZA_RESET_RECOMMENDED; + zone->flags &=3D ~NVME_ZFLAGS_SET_RZR; + trace_pci_nvme_zone_reset_recommended(zone->d.zslba); +} + +static void nvme_clear_rzr(NvmeCtrl *n, NvmeNamespace *ns, + NvmeZone *zone, bool notify) +{ + if (n->params.rrl_usec) { + zone->flags &=3D ~(NVME_ZFLAGS_SET_RZR | NVME_ZFLAGS_TS_DELAY); + notify =3D notify && (zone->d.za & NVME_ZA_RESET_RECOMMENDED); + zone->d.za &=3D ~NVME_ZA_RESET_RECOMMENDED; + zone->tstamp =3D 0; + } +} + +static void nvme_set_fzr(NvmeCtrl *n, NvmeNamespace *ns, NvmeZone *zone) +{ + assert(zone->flags & NVME_ZFLAGS_SET_FZR); + zone->tstamp =3D qemu_clock_get_ns(QEMU_CLOCK_REALTIME); + zone->flags &=3D ~NVME_ZFLAGS_TS_DELAY; + zone->d.za |=3D NVME_ZA_FINISH_RECOMMENDED; + zone->flags &=3D ~NVME_ZFLAGS_SET_FZR; + trace_pci_nvme_zone_finish_recommended(zone->d.zslba); +} + +static void nvme_clear_fzr(NvmeCtrl *n, NvmeNamespace *ns, + NvmeZone *zone, bool notify) +{ + if (n->params.frl_usec) { + zone->flags &=3D ~(NVME_ZFLAGS_SET_FZR | NVME_ZFLAGS_TS_DELAY); + notify =3D notify && (zone->d.za & NVME_ZA_FINISH_RECOMMENDED); + zone->d.za &=3D ~NVME_ZA_FINISH_RECOMMENDED; + zone->tstamp =3D 0; + } +} + +static void nvme_schedule_rzr(NvmeCtrl *n, NvmeNamespace *ns, NvmeZone *zo= ne) +{ + if (n->params.frl_usec) { + zone->flags &=3D ~(NVME_ZFLAGS_SET_FZR | NVME_ZFLAGS_TS_DELAY); + zone->d.za &=3D ~NVME_ZA_FINISH_RECOMMENDED; + zone->tstamp =3D 0; + } + if (n->params.rrl_usec) { + zone->flags |=3D NVME_ZFLAGS_SET_RZR; + if (n->params.rzr_delay_usec) { + zone->tstamp =3D qemu_clock_get_ns(QEMU_CLOCK_REALTIME); + zone->flags |=3D NVME_ZFLAGS_TS_DELAY; + } else { + nvme_set_rzr(n, ns, zone); + } + } +} + +static void nvme_schedule_fzr(NvmeCtrl *n, NvmeNamespace *ns, NvmeZone *zo= ne) +{ + if (n->params.rrl_usec) { + zone->flags &=3D ~(NVME_ZFLAGS_SET_RZR | NVME_ZFLAGS_TS_DELAY); + zone->d.za &=3D ~NVME_ZA_RESET_RECOMMENDED; + zone->tstamp =3D 0; + } + if (n->params.frl_usec) { + zone->flags |=3D NVME_ZFLAGS_SET_FZR; + if (n->params.fzr_delay_usec) { + zone->tstamp =3D qemu_clock_get_ns(QEMU_CLOCK_REALTIME); + zone->flags |=3D NVME_ZFLAGS_TS_DELAY; + } else { + nvme_set_fzr(n, ns, zone); + } + } +} + static void nvme_assign_zone_state(NvmeCtrl *n, NvmeNamespace *ns, NvmeZone *zone, uint8_t state) { @@ -208,15 +286,19 @@ static void nvme_assign_zone_state(NvmeCtrl *n, NvmeN= amespace *ns, switch (nvme_get_zone_state(zone)) { case NVME_ZONE_STATE_EXPLICITLY_OPEN: nvme_remove_zone(n, ns, ns->exp_open_zones, zone); + nvme_clear_fzr(n, ns, zone, false); break; case NVME_ZONE_STATE_IMPLICITLY_OPEN: nvme_remove_zone(n, ns, ns->imp_open_zones, zone); + nvme_clear_fzr(n, ns, zone, false); break; case NVME_ZONE_STATE_CLOSED: nvme_remove_zone(n, ns, ns->closed_zones, zone); + nvme_clear_fzr(n, ns, zone, false); break; case NVME_ZONE_STATE_FULL: nvme_remove_zone(n, ns, ns->full_zones, zone); + nvme_clear_rzr(n, ns, zone, false); } } =20 @@ -225,15 +307,19 @@ static void nvme_assign_zone_state(NvmeCtrl *n, NvmeN= amespace *ns, switch (state) { case NVME_ZONE_STATE_EXPLICITLY_OPEN: nvme_add_zone_tail(n, ns, ns->exp_open_zones, zone); + nvme_schedule_fzr(n, ns, zone); break; case NVME_ZONE_STATE_IMPLICITLY_OPEN: nvme_add_zone_tail(n, ns, ns->imp_open_zones, zone); + nvme_schedule_fzr(n, ns, zone); break; case NVME_ZONE_STATE_CLOSED: nvme_add_zone_tail(n, ns, ns->closed_zones, zone); + nvme_schedule_fzr(n, ns, zone); break; case NVME_ZONE_STATE_FULL: nvme_add_zone_tail(n, ns, ns->full_zones, zone); + nvme_schedule_rzr(n, ns, zone); break; default: zone->d.za =3D 0; @@ -555,6 +641,7 @@ static void nvme_auto_transition_zone(NvmeCtrl *n, Nvme= Namespace *ns, zone->d.za &=3D ~(NVME_ZA_FINISH_RECOMMENDED | NVME_ZA_RESET_RECOMMENDED); zone->d.za |=3D NVME_ZA_FINISHED_BY_CTLR; + zone->flags =3D 0; zone->tstamp =3D 0; trace_pci_nvme_zone_finished_by_controller(zone->d.zslba); } @@ -2624,6 +2711,11 @@ static void nvme_zoned_init_ctrl(NvmeCtrl *n, Error = **errp) n->num_zones =3D nz; n->zone_array_size =3D sizeof(NvmeZone) * nz; =20 + n->params.rzr_delay_usec *=3D SCALE_MS; + n->params.rrl_usec *=3D SCALE_MS; + n->params.fzr_delay_usec *=3D SCALE_MS; + n->params.frl_usec *=3D SCALE_MS; + /* Make sure that the values of all Zoned Command Set properties are s= ane */ if (n->params.max_open_zones > nz) { n->params.max_open_zones =3D nz; @@ -2651,6 +2743,8 @@ static int nvme_zoned_init_ns(NvmeCtrl *n, NvmeNamesp= ace *ns, int lba_index, /* MAR/MOR are zeroes-based, 0xffffffff means no limit */ ns->id_ns_zoned->mar =3D cpu_to_le32(n->params.max_active_zones - 1); ns->id_ns_zoned->mor =3D cpu_to_le32(n->params.max_open_zones - 1); + ns->id_ns_zoned->rrl =3D cpu_to_le32(n->params.rrl_usec / (1000 * SCAL= E_MS)); + ns->id_ns_zoned->frl =3D cpu_to_le32(n->params.frl_usec / (1000 * SCAL= E_MS)); ns->id_ns_zoned->zoc =3D cpu_to_le16(n->params.active_excursions ? 0x2= : 0); ns->id_ns_zoned->ozcs =3D n->params.cross_zone_read ? 0x01 : 0x00; =20 @@ -3012,6 +3106,11 @@ static Property nvme_props[] =3D { DEFINE_PROP_UINT32("zone_append_max_size", NvmeCtrl, params.zamds_bs, = 0), DEFINE_PROP_INT32("max_active", NvmeCtrl, params.max_active_zones, 0), DEFINE_PROP_INT32("max_open", NvmeCtrl, params.max_open_zones, 0), + DEFINE_PROP_UINT64("reset_rcmnd_delay", NvmeCtrl, params.rzr_delay_use= c, 0), + DEFINE_PROP_UINT64("reset_rcmnd_limit", NvmeCtrl, params.rrl_usec, 0), + DEFINE_PROP_UINT64("finish_rcmnd_delay", NvmeCtrl, + params.fzr_delay_usec, 0), + DEFINE_PROP_UINT64("finish_rcmnd_limit", NvmeCtrl, params.frl_usec, 0), DEFINE_PROP_BOOL("cross_zone_read", NvmeCtrl, params.cross_zone_read, = true), DEFINE_PROP_BOOL("active_excursions", NvmeCtrl, params.active_excursio= ns, false), diff --git a/hw/block/nvme.h b/hw/block/nvme.h index 8a0aaeb09a..be1920f1ef 100644 --- a/hw/block/nvme.h +++ b/hw/block/nvme.h @@ -22,6 +22,10 @@ typedef struct NvmeParams { uint64_t zone_capacity; int32_t max_active_zones; int32_t max_open_zones; + uint64_t rzr_delay_usec; + uint64_t rrl_usec; + uint64_t fzr_delay_usec; + uint64_t frl_usec; } NvmeParams; =20 typedef struct NvmeAsyncEvent { @@ -77,12 +81,19 @@ typedef struct NvmeCQueue { QTAILQ_HEAD(, NvmeRequest) req_list; } NvmeCQueue; =20 +enum NvmeZoneFlags { + NVME_ZFLAGS_TS_DELAY =3D 1 << 0, + NVME_ZFLAGS_SET_RZR =3D 1 << 1, + NVME_ZFLAGS_SET_FZR =3D 1 << 2, +}; + typedef struct NvmeZone { NvmeZoneDescr d; uint64_t tstamp; + uint32_t flags; uint32_t next; uint32_t prev; - uint8_t rsvd80[8]; + uint8_t rsvd84[4]; } NvmeZone; =20 #define NVME_ZONE_LIST_NIL UINT_MAX --=20 2.21.0