qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Sam Li <faithilikerun@gmail.com>
To: qemu-devel@nongnu.org
Cc: qemu-block@nongnu.org, "Kevin Wolf" <kwolf@redhat.com>,
	"Paolo Bonzini" <pbonzini@redhat.com>,
	stefanha@redhat.com, "Peter Xu" <peterx@redhat.com>,
	"David Hildenbrand" <david@redhat.com>,
	dmitry.fomichev@wdc.com, hare@suse.de,
	"Hanna Reitz" <hreitz@redhat.com>,
	"Eric Blake" <eblake@redhat.com>,
	"Markus Armbruster" <armbru@redhat.com>,
	"Philippe Mathieu-Daudé" <philmd@linaro.org>,
	dlemoal@kernel.org, "Keith Busch" <kbusch@kernel.org>,
	"Klaus Jensen" <its@irrelevant.dk>,
	"Sam Li" <faithilikerun@gmail.com>
Subject: [RFC v3 7/7] hw/nvme: make ZDED persistent
Date: Mon, 22 Jan 2024 20:00:13 +0100	[thread overview]
Message-ID: <20240122190013.41302-8-faithilikerun@gmail.com> (raw)
In-Reply-To: <20240122190013.41302-1-faithilikerun@gmail.com>

Zone descriptor extension data (ZDED) is not persistent across QEMU
restarts. The zone descriptor extension valid bit (ZDEV) is part of
zone attributes, which sets to one when the ZDED is associated with
the zone.

With the qcow2 img as the backing file, the NVMe ZNS device stores
the zone attributes at the following eight bit of zone type bit of write
pointers for each zone. The ZDED is stored as part of zoned metadata as
write pointers.

Signed-off-by: Sam Li <faithilikerun@gmail.com>
---
 block/qcow2.c                | 45 ++++++++++++++++++++++++++++++++++++
 hw/nvme/ctrl.c               |  1 +
 include/block/block-common.h |  1 +
 3 files changed, 47 insertions(+)

diff --git a/block/qcow2.c b/block/qcow2.c
index 43ee0f47b9..f2d58d86c4 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -25,6 +25,7 @@
 #include "qemu/osdep.h"
 
 #include "block/qdict.h"
+#include "block/nvme.h"
 #include "sysemu/block-backend.h"
 #include "qemu/main-loop.h"
 #include "qemu/module.h"
@@ -197,6 +198,17 @@ qcow2_extract_crypto_opts(QemuOpts *opts, const char *fmt, Error **errp)
 
 #define QCOW2_ZT_IS_CONV(wp)    (wp & 1ULL << 59)
 
+static inline void qcow2_set_za(uint64_t *wp, uint8_t za)
+{
+    /*
+     * The zone attribute takes up one byte. Store it after the zoned
+     * bit.
+     */
+    uint64_t addr = *wp;
+    addr |= ((uint64_t)za << 51);
+    *wp = addr;
+}
+
 /*
  * To emulate a real zoned device, closed, empty and full states are
  * preserved after a power cycle. The open states are in-memory and will
@@ -5053,6 +5065,36 @@ unlock:
     return ret;
 }
 
+static int coroutine_fn GRAPH_RDLOCK
+qcow2_zns_set_zded(BlockDriverState *bs, uint32_t index)
+{
+    BDRVQcow2State *s = bs->opaque;
+    int ret;
+
+    qemu_co_mutex_lock(&bs->wps->colock);
+    uint64_t *wp = &bs->wps->wp[index];
+    BlockZoneState zs = qcow2_get_zone_state(bs, index);
+    if (zs == BLK_ZS_EMPTY) {
+        if (!qcow2_can_activate_zone(bs)) {
+            goto unlock;
+        }
+
+        qcow2_set_za(wp, NVME_ZA_ZD_EXT_VALID);
+        ret = qcow2_write_wp_at(bs, wp, index);
+        if (ret < 0) {
+            error_report("Failed to set zone extension at 0x%" PRIx64 "", *wp);
+            goto unlock;
+        }
+        s->nr_zones_closed++;
+        qemu_co_mutex_unlock(&bs->wps->colock);
+        return ret;
+    }
+
+unlock:
+    qemu_co_mutex_unlock(&bs->wps->colock);
+    return NVME_ZONE_INVAL_TRANSITION;
+}
+
 static int coroutine_fn GRAPH_RDLOCK
 qcow2_co_zone_mgmt(BlockDriverState *bs, BlockZoneOp op,
                                            int64_t offset, int64_t len)
@@ -5110,6 +5152,9 @@ qcow2_co_zone_mgmt(BlockDriverState *bs, BlockZoneOp op,
     case BLK_ZO_OFFLINE:
         /* There are no transitions from the offline state to any other state */
         break;
+    case BLK_ZO_SET_ZDED:
+        ret = qcow2_zns_set_zded(bs, index);
+        break;
     default:
         error_report("Unsupported zone op: 0x%x", op);
         ret = -ENOTSUP;
diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
index de41d8bac8..2799a3ac31 100644
--- a/hw/nvme/ctrl.c
+++ b/hw/nvme/ctrl.c
@@ -3465,6 +3465,7 @@ static uint16_t nvme_zone_mgmt_send(NvmeCtrl *n, NvmeRequest *req)
         break;
 
     case NVME_ZONE_ACTION_SET_ZD_EXT:
+        op = BLK_ZO_SET_ZDED;
         int zd_ext_size = blk_get_zd_ext_size(blk);
         trace_pci_nvme_set_descriptor_extension(slba, zone_idx);
         if (all || !zd_ext_size) {
diff --git a/include/block/block-common.h b/include/block/block-common.h
index 7690b05149..7c501e053e 100644
--- a/include/block/block-common.h
+++ b/include/block/block-common.h
@@ -88,6 +88,7 @@ typedef enum BlockZoneOp {
     BLK_ZO_FINISH,
     BLK_ZO_RESET,
     BLK_ZO_OFFLINE,
+    BLK_ZO_SET_ZDED,
 } BlockZoneOp;
 
 typedef enum BlockZoneModel {
-- 
2.40.1



      parent reply	other threads:[~2024-01-22 19:02 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-01-22 19:00 [RFC v3 0/7] Add persistence to NVMe ZNS emulation Sam Li
2024-01-22 19:00 ` [RFC v3 1/7] docs/qcow2: add zd_extension_size option to the zoned format feature Sam Li
2024-01-22 19:00 ` [RFC v3 2/7] qcow2: add zd_extension configurations to zoned metadata Sam Li
2024-01-22 19:00 ` [RFC v3 3/7] hw/nvme: use blk_get_*() to access zone info in the block layer Sam Li
2024-01-22 19:00 ` [RFC v3 4/7] hw/nvme: add blk_get_zone_extension to access zd_extensions Sam Li
2024-01-22 19:00 ` [RFC v3 5/7] hw/nvme: make the metadata of ZNS emulation persistent Sam Li
2024-01-22 19:00 ` [RFC v3 6/7] hw/nvme: refactor zone append write using block layer APIs Sam Li
2024-01-22 19:00 ` Sam Li [this message]

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=20240122190013.41302-8-faithilikerun@gmail.com \
    --to=faithilikerun@gmail.com \
    --cc=armbru@redhat.com \
    --cc=david@redhat.com \
    --cc=dlemoal@kernel.org \
    --cc=dmitry.fomichev@wdc.com \
    --cc=eblake@redhat.com \
    --cc=hare@suse.de \
    --cc=hreitz@redhat.com \
    --cc=its@irrelevant.dk \
    --cc=kbusch@kernel.org \
    --cc=kwolf@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=peterx@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).