From patchwork Mon May 8 05:19:13 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Li X-Patchwork-Id: 13234051 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 7F72EC77B7F for ; Mon, 8 May 2023 05:20:09 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pvtHb-0005co-Fw; Mon, 08 May 2023 01:19:35 -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 1pvtHZ-0005Zo-K3; Mon, 08 May 2023 01:19:33 -0400 Received: from mail-pf1-x42a.google.com ([2607:f8b0:4864:20::42a]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1pvtHX-0002tI-2t; Mon, 08 May 2023 01:19:33 -0400 Received: by mail-pf1-x42a.google.com with SMTP id d2e1a72fcca58-643912bca6fso3168216b3a.0; Sun, 07 May 2023 22:19:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1683523169; x=1686115169; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=aNSd36k584tC1hjIMdhXes+3tTk07CmrixpR6JJVoC4=; b=jRG54EilRQMsxjbMECdGPcUPqlAYbjgYWrU+i77asFjO+B7AtHUeKe/a9OQnKP56uz tO0Qqob3KJ3X2JpytHxW8MKaE2TD713YCqwouDAKxJ0Dgjhc0VLZ3Y8t1nhStTphN4Tf G0170kopVdTSb91g5ubsVnumuDy9iKIyJJ2zW1eq17oLe+SAADW62HAAW59rah4kjKWm AjnsFAojoE/IsqRPEgbqvGuOiQz9T4aTlrA/FlyWEV6R5krzhdPGIbT2H42r4StwEJX0 XJBGlvHz4nlLdQQf+aMGQPYAxIV43BPPrWPi9Gs9FBqjqBqJhjrRh0PaYWxwgE7rF/mL gvAA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1683523169; x=1686115169; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=aNSd36k584tC1hjIMdhXes+3tTk07CmrixpR6JJVoC4=; b=l97ItQtoAfvwOuFvZyf0QlROt7nszEEz70Kc15ppfsmVcnxGmXt6nYFLmQkeAlgJHy nsgs1aXgBETnUCF2wilM1uHyzqngg7rbo8oyLqyKyotK476TXzIcPaaE3C71jg92/2AU 8Ry+BZfMozWixRdXlShuhjZE2zASqvc7/2BbVYVYAxOerKWMU3flrI0be56mggO4Tlz6 tLkr4zlpZhj9dMni7ifHko3gdQ8sFKY8XI6TL52TM7ENC2t9gCuKMX3+53kE0xVKUpNY Q2zx4muFFR+DkOGMq9QBy95Awk/CkpcDJf+DWKkk9NMsmsCpcVZDiKjnrkCd3mmqpTCN YH6Q== X-Gm-Message-State: AC+VfDzZOTDqXPst4II+p8grGrKOD3ToLEnHlExx5EO4JxqESc6J7d9o dwRgovsor0V2a4GcRmmJ4/ekwwWaA9oGbn6E X-Google-Smtp-Source: ACHHUZ79HAyblQjACzDz9macBosVCsywSOhF16anW2P1Cy4DxZoCKwCGmG6Wd7Qc4bo0uvqEIS8hWw== X-Received: by 2002:a05:6a00:1881:b0:643:b489:246d with SMTP id x1-20020a056a00188100b00643b489246dmr8434723pfh.3.1683523168241; Sun, 07 May 2023 22:19:28 -0700 (PDT) Received: from fedlinux.. ([106.84.128.239]) by smtp.gmail.com with ESMTPSA id j1-20020aa783c1000000b0063a1e7d7439sm5247997pfn.69.2023.05.07.22.19.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 07 May 2023 22:19:27 -0700 (PDT) From: Sam Li To: qemu-devel@nongnu.org Cc: Raphael Norwitz , Hanna Reitz , Eric Blake , Stefan Hajnoczi , Kevin Wolf , Markus Armbruster , "Michael S. Tsirkin" , hare@suse.de, qemu-block@nongnu.org, dlemoal@kernel.org, dmitry.fomichev@wdc.com, Sam Li Subject: [PATCH v11 1/4] virtio-blk: add zoned storage emulation for zoned devices Date: Mon, 8 May 2023 13:19:13 +0800 Message-Id: <20230508051916.178322-2-faithilikerun@gmail.com> X-Mailer: git-send-email 2.40.0 In-Reply-To: <20230508051916.178322-1-faithilikerun@gmail.com> References: <20230508051916.178322-1-faithilikerun@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::42a; envelope-from=faithilikerun@gmail.com; helo=mail-pf1-x42a.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 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, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 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: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org This patch extends virtio-blk emulation to handle zoned device commands by calling the new block layer APIs to perform zoned device I/O on behalf of the guest. It supports Report Zone, four zone oparations (open, close, finish, reset), and Append Zone. The VIRTIO_BLK_F_ZONED feature bit will only be set if the host does support zoned block devices. Regular block devices(conventional zones) will not be set. The guest os can use blktests, fio to test those commands on zoned devices. Furthermore, using zonefs to test zone append write is also supported. Signed-off-by: Sam Li --- hw/block/virtio-blk-common.c | 2 + hw/block/virtio-blk.c | 389 +++++++++++++++++++++++++++++++++++ hw/virtio/virtio-qmp.c | 2 + 3 files changed, 393 insertions(+) diff --git a/hw/block/virtio-blk-common.c b/hw/block/virtio-blk-common.c index ac52d7c176..e2f8e2f6da 100644 --- a/hw/block/virtio-blk-common.c +++ b/hw/block/virtio-blk-common.c @@ -29,6 +29,8 @@ static const VirtIOFeature feature_sizes[] = { .end = endof(struct virtio_blk_config, discard_sector_alignment)}, {.flags = 1ULL << VIRTIO_BLK_F_WRITE_ZEROES, .end = endof(struct virtio_blk_config, write_zeroes_may_unmap)}, + {.flags = 1ULL << VIRTIO_BLK_F_ZONED, + .end = endof(struct virtio_blk_config, zoned)}, {} }; diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c index cefca93b31..cb741dec39 100644 --- a/hw/block/virtio-blk.c +++ b/hw/block/virtio-blk.c @@ -17,6 +17,7 @@ #include "qemu/module.h" #include "qemu/error-report.h" #include "qemu/main-loop.h" +#include "block/block_int.h" #include "trace.h" #include "hw/block/block.h" #include "hw/qdev-properties.h" @@ -601,6 +602,335 @@ err: return err_status; } +typedef struct ZoneCmdData { + VirtIOBlockReq *req; + struct iovec *in_iov; + unsigned in_num; + union { + struct { + unsigned int nr_zones; + BlockZoneDescriptor *zones; + } zone_report_data; + struct { + int64_t offset; + } zone_append_data; + }; +} ZoneCmdData; + +/* + * check zoned_request: error checking before issuing requests. If all checks + * passed, return true. + * append: true if only zone append requests issued. + */ +static bool check_zoned_request(VirtIOBlock *s, int64_t offset, int64_t len, + bool append, uint8_t *status) { + BlockDriverState *bs = blk_bs(s->blk); + int index; + + if (!virtio_has_feature(s->host_features, VIRTIO_BLK_F_ZONED)) { + *status = VIRTIO_BLK_S_UNSUPP; + return false; + } + + if (offset < 0 || len < 0 || len > (bs->total_sectors << BDRV_SECTOR_BITS) + || offset > (bs->total_sectors << BDRV_SECTOR_BITS) - len) { + *status = VIRTIO_BLK_S_ZONE_INVALID_CMD; + return false; + } + + if (append) { + if (bs->bl.write_granularity) { + if ((offset % bs->bl.write_granularity) != 0) { + *status = VIRTIO_BLK_S_ZONE_UNALIGNED_WP; + return false; + } + } + + index = offset / bs->bl.zone_size; + if (BDRV_ZT_IS_CONV(bs->wps->wp[index])) { + *status = VIRTIO_BLK_S_ZONE_INVALID_CMD; + return false; + } + + if (len / 512 > bs->bl.max_append_sectors) { + if (bs->bl.max_append_sectors == 0) { + *status = VIRTIO_BLK_S_UNSUPP; + } else { + *status = VIRTIO_BLK_S_ZONE_INVALID_CMD; + } + return false; + } + } + return true; +} + +static void virtio_blk_zone_report_complete(void *opaque, int ret) +{ + ZoneCmdData *data = opaque; + VirtIOBlockReq *req = data->req; + VirtIOBlock *s = req->dev; + VirtIODevice *vdev = VIRTIO_DEVICE(req->dev); + struct iovec *in_iov = data->in_iov; + unsigned in_num = data->in_num; + int64_t zrp_size, n, j = 0; + int64_t nz = data->zone_report_data.nr_zones; + int8_t err_status = VIRTIO_BLK_S_OK; + + if (ret) { + err_status = VIRTIO_BLK_S_ZONE_INVALID_CMD; + goto out; + } + + struct virtio_blk_zone_report zrp_hdr = (struct virtio_blk_zone_report) { + .nr_zones = cpu_to_le64(nz), + }; + zrp_size = sizeof(struct virtio_blk_zone_report) + + sizeof(struct virtio_blk_zone_descriptor) * nz; + n = iov_from_buf(in_iov, in_num, 0, &zrp_hdr, sizeof(zrp_hdr)); + if (n != sizeof(zrp_hdr)) { + virtio_error(vdev, "Driver provided input buffer that is too small!"); + err_status = VIRTIO_BLK_S_ZONE_INVALID_CMD; + goto out; + } + + for (size_t i = sizeof(zrp_hdr); i < zrp_size; + i += sizeof(struct virtio_blk_zone_descriptor), ++j) { + struct virtio_blk_zone_descriptor desc = + (struct virtio_blk_zone_descriptor) { + .z_start = cpu_to_le64(data->zone_report_data.zones[j].start + >> BDRV_SECTOR_BITS), + .z_cap = cpu_to_le64(data->zone_report_data.zones[j].cap + >> BDRV_SECTOR_BITS), + .z_wp = cpu_to_le64(data->zone_report_data.zones[j].wp + >> BDRV_SECTOR_BITS), + }; + + switch (data->zone_report_data.zones[j].type) { + case BLK_ZT_CONV: + desc.z_type = VIRTIO_BLK_ZT_CONV; + break; + case BLK_ZT_SWR: + desc.z_type = VIRTIO_BLK_ZT_SWR; + break; + case BLK_ZT_SWP: + desc.z_type = VIRTIO_BLK_ZT_SWP; + break; + default: + g_assert_not_reached(); + } + + switch (data->zone_report_data.zones[j].state) { + case BLK_ZS_RDONLY: + desc.z_state = VIRTIO_BLK_ZS_RDONLY; + break; + case BLK_ZS_OFFLINE: + desc.z_state = VIRTIO_BLK_ZS_OFFLINE; + break; + case BLK_ZS_EMPTY: + desc.z_state = VIRTIO_BLK_ZS_EMPTY; + break; + case BLK_ZS_CLOSED: + desc.z_state = VIRTIO_BLK_ZS_CLOSED; + break; + case BLK_ZS_FULL: + desc.z_state = VIRTIO_BLK_ZS_FULL; + break; + case BLK_ZS_EOPEN: + desc.z_state = VIRTIO_BLK_ZS_EOPEN; + break; + case BLK_ZS_IOPEN: + desc.z_state = VIRTIO_BLK_ZS_IOPEN; + break; + case BLK_ZS_NOT_WP: + desc.z_state = VIRTIO_BLK_ZS_NOT_WP; + break; + default: + g_assert_not_reached(); + } + + /* TODO: it takes O(n^2) time complexity. Optimizations required. */ + n = iov_from_buf(in_iov, in_num, i, &desc, sizeof(desc)); + if (n != sizeof(desc)) { + virtio_error(vdev, "Driver provided input buffer " + "for descriptors that is too small!"); + err_status = VIRTIO_BLK_S_ZONE_INVALID_CMD; + } + } + +out: + aio_context_acquire(blk_get_aio_context(s->conf.conf.blk)); + virtio_blk_req_complete(req, err_status); + virtio_blk_free_request(req); + aio_context_release(blk_get_aio_context(s->conf.conf.blk)); + g_free(data->zone_report_data.zones); + g_free(data); +} + +static void virtio_blk_handle_zone_report(VirtIOBlockReq *req, + struct iovec *in_iov, + unsigned in_num) +{ + VirtIOBlock *s = req->dev; + VirtIODevice *vdev = VIRTIO_DEVICE(s); + unsigned int nr_zones; + ZoneCmdData *data; + int64_t zone_size, offset; + uint8_t err_status; + + if (req->in_len < sizeof(struct virtio_blk_inhdr) + + sizeof(struct virtio_blk_zone_report) + + sizeof(struct virtio_blk_zone_descriptor)) { + virtio_error(vdev, "in buffer too small for zone report"); + return; + } + + /* start byte offset of the zone report */ + offset = virtio_ldq_p(vdev, &req->out.sector) << BDRV_SECTOR_BITS; + if (!check_zoned_request(s, offset, 0, false, &err_status)) { + goto out; + } + nr_zones = (req->in_len - sizeof(struct virtio_blk_inhdr) - + sizeof(struct virtio_blk_zone_report)) / + sizeof(struct virtio_blk_zone_descriptor); + + zone_size = sizeof(BlockZoneDescriptor) * nr_zones; + data = g_malloc(sizeof(ZoneCmdData)); + data->req = req; + data->in_iov = in_iov; + data->in_num = in_num; + data->zone_report_data.nr_zones = nr_zones; + data->zone_report_data.zones = g_malloc(zone_size), + + blk_aio_zone_report(s->blk, offset, &data->zone_report_data.nr_zones, + data->zone_report_data.zones, + virtio_blk_zone_report_complete, data); + return; +out: + virtio_blk_req_complete(req, err_status); + virtio_blk_free_request(req); +} + +static void virtio_blk_zone_mgmt_complete(void *opaque, int ret) +{ + VirtIOBlockReq *req = opaque; + VirtIOBlock *s = req->dev; + int8_t err_status = VIRTIO_BLK_S_OK; + + if (ret) { + err_status = VIRTIO_BLK_S_ZONE_INVALID_CMD; + } + + aio_context_acquire(blk_get_aio_context(s->conf.conf.blk)); + virtio_blk_req_complete(req, err_status); + virtio_blk_free_request(req); + aio_context_release(blk_get_aio_context(s->conf.conf.blk)); +} + +static int virtio_blk_handle_zone_mgmt(VirtIOBlockReq *req, BlockZoneOp op) +{ + VirtIOBlock *s = req->dev; + VirtIODevice *vdev = VIRTIO_DEVICE(s); + BlockDriverState *bs = blk_bs(s->blk); + int64_t offset = virtio_ldq_p(vdev, &req->out.sector) << BDRV_SECTOR_BITS; + uint64_t len; + uint64_t capacity = bs->total_sectors << BDRV_SECTOR_BITS; + uint8_t err_status = VIRTIO_BLK_S_OK; + + uint32_t type = virtio_ldl_p(vdev, &req->out.type); + if (type == VIRTIO_BLK_T_ZONE_RESET_ALL) { + /* Entire drive capacity */ + offset = 0; + len = capacity; + } else { + if (bs->bl.zone_size > capacity - offset) { + /* The zoned device allows the last smaller zone. */ + len = capacity - bs->bl.zone_size * (bs->bl.nr_zones - 1); + } else { + len = bs->bl.zone_size; + } + } + + if (!check_zoned_request(s, offset, len, false, &err_status)) { + goto out; + } + + blk_aio_zone_mgmt(s->blk, op, offset, len, + virtio_blk_zone_mgmt_complete, req); + + return 0; +out: + virtio_blk_req_complete(req, err_status); + virtio_blk_free_request(req); + return err_status; +} + +static void virtio_blk_zone_append_complete(void *opaque, int ret) +{ + ZoneCmdData *data = opaque; + VirtIOBlockReq *req = data->req; + VirtIOBlock *s = req->dev; + VirtIODevice *vdev = VIRTIO_DEVICE(req->dev); + int64_t append_sector, n; + uint8_t err_status = VIRTIO_BLK_S_OK; + + if (ret) { + err_status = VIRTIO_BLK_S_ZONE_INVALID_CMD; + goto out; + } + + virtio_stq_p(vdev, &append_sector, + data->zone_append_data.offset >> BDRV_SECTOR_BITS); + n = iov_from_buf(data->in_iov, data->in_num, 0, &append_sector, + sizeof(append_sector)); + if (n != sizeof(append_sector)) { + virtio_error(vdev, "Driver provided input buffer less than size of " + "append_sector"); + err_status = VIRTIO_BLK_S_ZONE_INVALID_CMD; + goto out; + } + +out: + aio_context_acquire(blk_get_aio_context(s->conf.conf.blk)); + virtio_blk_req_complete(req, err_status); + virtio_blk_free_request(req); + aio_context_release(blk_get_aio_context(s->conf.conf.blk)); + g_free(data); +} + +static int virtio_blk_handle_zone_append(VirtIOBlockReq *req, + struct iovec *out_iov, + struct iovec *in_iov, + uint64_t out_num, + unsigned in_num) { + VirtIOBlock *s = req->dev; + VirtIODevice *vdev = VIRTIO_DEVICE(s); + uint8_t err_status = VIRTIO_BLK_S_OK; + + int64_t offset = virtio_ldq_p(vdev, &req->out.sector) << BDRV_SECTOR_BITS; + int64_t len = iov_size(out_iov, out_num); + + if (!check_zoned_request(s, offset, len, true, &err_status)) { + goto out; + } + + ZoneCmdData *data = g_malloc(sizeof(ZoneCmdData)); + data->req = req; + data->in_iov = in_iov; + data->in_num = in_num; + data->zone_append_data.offset = offset; + qemu_iovec_init_external(&req->qiov, out_iov, out_num); + blk_aio_zone_append(s->blk, &data->zone_append_data.offset, &req->qiov, 0, + virtio_blk_zone_append_complete, data); + return 0; + +out: + aio_context_acquire(blk_get_aio_context(s->conf.conf.blk)); + virtio_blk_req_complete(req, err_status); + virtio_blk_free_request(req); + aio_context_release(blk_get_aio_context(s->conf.conf.blk)); + return err_status; +} + static int virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb) { uint32_t type; @@ -687,6 +1017,24 @@ static int virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb) case VIRTIO_BLK_T_FLUSH: virtio_blk_handle_flush(req, mrb); break; + case VIRTIO_BLK_T_ZONE_REPORT: + virtio_blk_handle_zone_report(req, in_iov, in_num); + break; + case VIRTIO_BLK_T_ZONE_OPEN: + virtio_blk_handle_zone_mgmt(req, BLK_ZO_OPEN); + break; + case VIRTIO_BLK_T_ZONE_CLOSE: + virtio_blk_handle_zone_mgmt(req, BLK_ZO_CLOSE); + break; + case VIRTIO_BLK_T_ZONE_FINISH: + virtio_blk_handle_zone_mgmt(req, BLK_ZO_FINISH); + break; + case VIRTIO_BLK_T_ZONE_RESET: + virtio_blk_handle_zone_mgmt(req, BLK_ZO_RESET); + break; + case VIRTIO_BLK_T_ZONE_RESET_ALL: + virtio_blk_handle_zone_mgmt(req, BLK_ZO_RESET); + break; case VIRTIO_BLK_T_SCSI_CMD: virtio_blk_handle_scsi(req); break; @@ -705,6 +1053,14 @@ static int virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb) virtio_blk_free_request(req); break; } + case VIRTIO_BLK_T_ZONE_APPEND & ~VIRTIO_BLK_T_OUT: + /* + * Passing out_iov/out_num and in_iov/in_num is not safe + * to access req->elem.out_sg directly because it may be + * modified by virtio_blk_handle_request(). + */ + virtio_blk_handle_zone_append(req, out_iov, in_iov, out_num, in_num); + break; /* * VIRTIO_BLK_T_DISCARD and VIRTIO_BLK_T_WRITE_ZEROES are defined with * VIRTIO_BLK_T_OUT flag set. We masked this flag in the switch statement, @@ -890,6 +1246,7 @@ static void virtio_blk_update_config(VirtIODevice *vdev, uint8_t *config) { VirtIOBlock *s = VIRTIO_BLK(vdev); BlockConf *conf = &s->conf.conf; + BlockDriverState *bs = blk_bs(s->blk); struct virtio_blk_config blkcfg; uint64_t capacity; int64_t length; @@ -954,6 +1311,30 @@ static void virtio_blk_update_config(VirtIODevice *vdev, uint8_t *config) blkcfg.write_zeroes_may_unmap = 1; virtio_stl_p(vdev, &blkcfg.max_write_zeroes_seg, 1); } + if (bs->bl.zoned != BLK_Z_NONE) { + switch (bs->bl.zoned) { + case BLK_Z_HM: + blkcfg.zoned.model = VIRTIO_BLK_Z_HM; + break; + case BLK_Z_HA: + blkcfg.zoned.model = VIRTIO_BLK_Z_HA; + break; + default: + g_assert_not_reached(); + } + + virtio_stl_p(vdev, &blkcfg.zoned.zone_sectors, + bs->bl.zone_size / 512); + virtio_stl_p(vdev, &blkcfg.zoned.max_active_zones, + bs->bl.max_active_zones); + virtio_stl_p(vdev, &blkcfg.zoned.max_open_zones, + bs->bl.max_open_zones); + virtio_stl_p(vdev, &blkcfg.zoned.write_granularity, blk_size); + virtio_stl_p(vdev, &blkcfg.zoned.max_append_sectors, + bs->bl.max_append_sectors); + } else { + blkcfg.zoned.model = VIRTIO_BLK_Z_NONE; + } memcpy(config, &blkcfg, s->config_size); } @@ -1163,6 +1544,14 @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp) return; } + BlockDriverState *bs = blk_bs(conf->conf.blk); + if (bs->bl.zoned != BLK_Z_NONE) { + virtio_add_feature(&s->host_features, VIRTIO_BLK_F_ZONED); + if (bs->bl.zoned == BLK_Z_HM) { + virtio_clear_feature(&s->host_features, VIRTIO_BLK_F_DISCARD); + } + } + if (virtio_has_feature(s->host_features, VIRTIO_BLK_F_DISCARD) && (!conf->max_discard_sectors || conf->max_discard_sectors > BDRV_REQUEST_MAX_SECTORS)) { diff --git a/hw/virtio/virtio-qmp.c b/hw/virtio/virtio-qmp.c index b70148aba9..e84316dcfd 100644 --- a/hw/virtio/virtio-qmp.c +++ b/hw/virtio/virtio-qmp.c @@ -176,6 +176,8 @@ static const qmp_virtio_feature_map_t virtio_blk_feature_map[] = { "VIRTIO_BLK_F_DISCARD: Discard command supported"), FEATURE_ENTRY(VIRTIO_BLK_F_WRITE_ZEROES, \ "VIRTIO_BLK_F_WRITE_ZEROES: Write zeroes command supported"), + FEATURE_ENTRY(VIRTIO_BLK_F_ZONED, \ + "VIRTIO_BLK_F_ZONED: Zoned block devices"), #ifndef VIRTIO_BLK_NO_LEGACY FEATURE_ENTRY(VIRTIO_BLK_F_BARRIER, \ "VIRTIO_BLK_F_BARRIER: Request barriers supported"), From patchwork Mon May 8 05:19:14 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Li X-Patchwork-Id: 13234052 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id D3A2EC77B75 for ; Mon, 8 May 2023 05:20:21 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pvtHi-0005jX-PA; Mon, 08 May 2023 01:19:42 -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 1pvtHg-0005eY-Qc; Mon, 08 May 2023 01:19:40 -0400 Received: from mail-pf1-x42b.google.com ([2607:f8b0:4864:20::42b]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1pvtHc-0002v4-Mv; Mon, 08 May 2023 01:19:40 -0400 Received: by mail-pf1-x42b.google.com with SMTP id d2e1a72fcca58-64384274895so2832825b3a.2; Sun, 07 May 2023 22:19:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1683523173; x=1686115173; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=4nacodspM4Daa3g6DCKVoWnX9dAkF7WX9ek4ckpdn1E=; b=V6tYDOCoujFkBCuLEG9qglGdFsxcjnP/2apWEeB1na/xIeQ9THiW3zRBoQlTIGLoBf Cuuh2yU6lqEsBs6b0Lb2tShYrT3PC53Op9mgJmbpUHpgoXraKp8QTRAa828MOT+37a+5 qup+13rW6VrPULSFG3ZJJrKH2P8PML1mNX/LRha4ZT/skyN5HKw7TM9wK70tw44G5KPs MtYgvjPCpmYULgPUq2JliOhTarvFmTHraNAKFCB5HNq38ADV7faKdleNgAapwL37bipe o41hUNuA1PkZ2onqOxqFCX4BoFwN2vBdkTeZqXs1TmCuCtodzwiFSjFweBJuvKsfDy6E 4KwQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1683523173; x=1686115173; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=4nacodspM4Daa3g6DCKVoWnX9dAkF7WX9ek4ckpdn1E=; b=NkbldqDf06+q2/6U7BBwL7poFczPWtnPl09SR/xA6XoPWbJnpoba55hUPS06psUzyM 6OjcORcRBmMtfB0DEQfejPKFLak/VTqsq6ZxSclVfIKSG4e2moiApoevwxYEowwHSNp4 FB/RpnRhvYY3X6bQGonLT4dLUt8L3c0VZLwIOK2MBxB8RJJB7aFzMzVK2ypq5XUXn9py OG5UehRvRhlDReIyaTw6oB6AdIhe+IUfZV/CX8OPon+7fpV6Q3eudCZBvvfD5mV7pglN EWxQXA5QKfsnOPq3QX4Q5JflbxJ0iX8AaCtR0Elzun8IgEEhoxc09/MgoReprLAHCU5B iDdg== X-Gm-Message-State: AC+VfDy05xiXp2y3IRJ1KdBVzJuHU02O57sKzyFEdwJyQbRg8n7v3Tpj b5v1yjjhXi79RqcWww6lUZd5KkKCfRWQL8Mh X-Google-Smtp-Source: ACHHUZ4Dz+3XoOH/1T5+reaMKot4WXlQq+XmSpl5BX6UasOPhYJmX7XAVOxo2nyQKa/ZjLUbXxLreA== X-Received: by 2002:a05:6a20:9144:b0:100:3edd:6110 with SMTP id x4-20020a056a20914400b001003edd6110mr4022803pzc.34.1683523173100; Sun, 07 May 2023 22:19:33 -0700 (PDT) Received: from fedlinux.. ([106.84.128.239]) by smtp.gmail.com with ESMTPSA id j1-20020aa783c1000000b0063a1e7d7439sm5247997pfn.69.2023.05.07.22.19.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 07 May 2023 22:19:32 -0700 (PDT) From: Sam Li To: qemu-devel@nongnu.org Cc: Raphael Norwitz , Hanna Reitz , Eric Blake , Stefan Hajnoczi , Kevin Wolf , Markus Armbruster , "Michael S. Tsirkin" , hare@suse.de, qemu-block@nongnu.org, dlemoal@kernel.org, dmitry.fomichev@wdc.com, Sam Li Subject: [PATCH v11 2/4] block: add accounting for zone append operation Date: Mon, 8 May 2023 13:19:14 +0800 Message-Id: <20230508051916.178322-3-faithilikerun@gmail.com> X-Mailer: git-send-email 2.40.0 In-Reply-To: <20230508051916.178322-1-faithilikerun@gmail.com> References: <20230508051916.178322-1-faithilikerun@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::42b; envelope-from=faithilikerun@gmail.com; helo=mail-pf1-x42b.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 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, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 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: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Taking account of the new zone append write operation for zoned devices, BLOCK_ACCT_ZONE_APPEND enum is introduced as other I/O request type (read, write, flush). Signed-off-by: Sam Li --- block/qapi-sysemu.c | 11 ++++++ block/qapi.c | 18 ++++++++++ hw/block/virtio-blk.c | 4 +++ include/block/accounting.h | 1 + qapi/block-core.json | 68 ++++++++++++++++++++++++++++++++------ qapi/block.json | 4 +++ tests/qemu-iotests/227.out | 18 ++++++++++ 7 files changed, 113 insertions(+), 11 deletions(-) diff --git a/block/qapi-sysemu.c b/block/qapi-sysemu.c index 7bd7554150..cec3c1afb4 100644 --- a/block/qapi-sysemu.c +++ b/block/qapi-sysemu.c @@ -517,6 +517,7 @@ void qmp_block_latency_histogram_set( bool has_boundaries, uint64List *boundaries, bool has_boundaries_read, uint64List *boundaries_read, bool has_boundaries_write, uint64List *boundaries_write, + bool has_boundaries_append, uint64List *boundaries_append, bool has_boundaries_flush, uint64List *boundaries_flush, Error **errp) { @@ -557,6 +558,16 @@ void qmp_block_latency_histogram_set( } } + if (has_boundaries || has_boundaries_append) { + ret = block_latency_histogram_set( + stats, BLOCK_ACCT_ZONE_APPEND, + has_boundaries_append ? boundaries_append : boundaries); + if (ret) { + error_setg(errp, "Device '%s' set append write boundaries fail", id); + return; + } + } + if (has_boundaries || has_boundaries_flush) { ret = block_latency_histogram_set( stats, BLOCK_ACCT_FLUSH, diff --git a/block/qapi.c b/block/qapi.c index c84147849d..2684484e9d 100644 --- a/block/qapi.c +++ b/block/qapi.c @@ -533,27 +533,36 @@ static void bdrv_query_blk_stats(BlockDeviceStats *ds, BlockBackend *blk) ds->rd_bytes = stats->nr_bytes[BLOCK_ACCT_READ]; ds->wr_bytes = stats->nr_bytes[BLOCK_ACCT_WRITE]; + ds->zone_append_bytes = stats->nr_bytes[BLOCK_ACCT_ZONE_APPEND]; ds->unmap_bytes = stats->nr_bytes[BLOCK_ACCT_UNMAP]; ds->rd_operations = stats->nr_ops[BLOCK_ACCT_READ]; ds->wr_operations = stats->nr_ops[BLOCK_ACCT_WRITE]; + ds->zone_append_operations = stats->nr_ops[BLOCK_ACCT_ZONE_APPEND]; ds->unmap_operations = stats->nr_ops[BLOCK_ACCT_UNMAP]; ds->failed_rd_operations = stats->failed_ops[BLOCK_ACCT_READ]; ds->failed_wr_operations = stats->failed_ops[BLOCK_ACCT_WRITE]; + ds->failed_zone_append_operations = + stats->failed_ops[BLOCK_ACCT_ZONE_APPEND]; ds->failed_flush_operations = stats->failed_ops[BLOCK_ACCT_FLUSH]; ds->failed_unmap_operations = stats->failed_ops[BLOCK_ACCT_UNMAP]; ds->invalid_rd_operations = stats->invalid_ops[BLOCK_ACCT_READ]; ds->invalid_wr_operations = stats->invalid_ops[BLOCK_ACCT_WRITE]; + ds->invalid_zone_append_operations = + stats->invalid_ops[BLOCK_ACCT_ZONE_APPEND]; ds->invalid_flush_operations = stats->invalid_ops[BLOCK_ACCT_FLUSH]; ds->invalid_unmap_operations = stats->invalid_ops[BLOCK_ACCT_UNMAP]; ds->rd_merged = stats->merged[BLOCK_ACCT_READ]; ds->wr_merged = stats->merged[BLOCK_ACCT_WRITE]; + ds->zone_append_merged = stats->merged[BLOCK_ACCT_ZONE_APPEND]; ds->unmap_merged = stats->merged[BLOCK_ACCT_UNMAP]; ds->flush_operations = stats->nr_ops[BLOCK_ACCT_FLUSH]; ds->wr_total_time_ns = stats->total_time_ns[BLOCK_ACCT_WRITE]; + ds->zone_append_total_time_ns = + stats->total_time_ns[BLOCK_ACCT_ZONE_APPEND]; ds->rd_total_time_ns = stats->total_time_ns[BLOCK_ACCT_READ]; ds->flush_total_time_ns = stats->total_time_ns[BLOCK_ACCT_FLUSH]; ds->unmap_total_time_ns = stats->total_time_ns[BLOCK_ACCT_UNMAP]; @@ -571,6 +580,7 @@ static void bdrv_query_blk_stats(BlockDeviceStats *ds, BlockBackend *blk) TimedAverage *rd = &ts->latency[BLOCK_ACCT_READ]; TimedAverage *wr = &ts->latency[BLOCK_ACCT_WRITE]; + TimedAverage *zap = &ts->latency[BLOCK_ACCT_ZONE_APPEND]; TimedAverage *fl = &ts->latency[BLOCK_ACCT_FLUSH]; dev_stats->interval_length = ts->interval_length; @@ -583,6 +593,10 @@ static void bdrv_query_blk_stats(BlockDeviceStats *ds, BlockBackend *blk) dev_stats->max_wr_latency_ns = timed_average_max(wr); dev_stats->avg_wr_latency_ns = timed_average_avg(wr); + dev_stats->min_zone_append_latency_ns = timed_average_min(zap); + dev_stats->max_zone_append_latency_ns = timed_average_max(zap); + dev_stats->avg_zone_append_latency_ns = timed_average_avg(zap); + dev_stats->min_flush_latency_ns = timed_average_min(fl); dev_stats->max_flush_latency_ns = timed_average_max(fl); dev_stats->avg_flush_latency_ns = timed_average_avg(fl); @@ -591,6 +605,8 @@ static void bdrv_query_blk_stats(BlockDeviceStats *ds, BlockBackend *blk) block_acct_queue_depth(ts, BLOCK_ACCT_READ); dev_stats->avg_wr_queue_depth = block_acct_queue_depth(ts, BLOCK_ACCT_WRITE); + dev_stats->avg_zone_append_queue_depth = + block_acct_queue_depth(ts, BLOCK_ACCT_ZONE_APPEND); QAPI_LIST_PREPEND(ds->timed_stats, dev_stats); } @@ -600,6 +616,8 @@ static void bdrv_query_blk_stats(BlockDeviceStats *ds, BlockBackend *blk) = bdrv_latency_histogram_stats(&hgram[BLOCK_ACCT_READ]); ds->wr_latency_histogram = bdrv_latency_histogram_stats(&hgram[BLOCK_ACCT_WRITE]); + ds->zone_append_latency_histogram + = bdrv_latency_histogram_stats(&hgram[BLOCK_ACCT_ZONE_APPEND]); ds->flush_latency_histogram = bdrv_latency_histogram_stats(&hgram[BLOCK_ACCT_FLUSH]); } diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c index cb741dec39..bf05251a75 100644 --- a/hw/block/virtio-blk.c +++ b/hw/block/virtio-blk.c @@ -919,6 +919,10 @@ static int virtio_blk_handle_zone_append(VirtIOBlockReq *req, data->in_num = in_num; data->zone_append_data.offset = offset; qemu_iovec_init_external(&req->qiov, out_iov, out_num); + + block_acct_start(blk_get_stats(s->blk), &req->acct, len, + BLOCK_ACCT_ZONE_APPEND); + blk_aio_zone_append(s->blk, &data->zone_append_data.offset, &req->qiov, 0, virtio_blk_zone_append_complete, data); return 0; diff --git a/include/block/accounting.h b/include/block/accounting.h index b9caad60d5..a59e39f49d 100644 --- a/include/block/accounting.h +++ b/include/block/accounting.h @@ -37,6 +37,7 @@ enum BlockAcctType { BLOCK_ACCT_READ, BLOCK_ACCT_WRITE, BLOCK_ACCT_FLUSH, + BLOCK_ACCT_ZONE_APPEND, BLOCK_ACCT_UNMAP, BLOCK_MAX_IOTYPE, }; diff --git a/qapi/block-core.json b/qapi/block-core.json index b57978957f..c10b9ebd05 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -849,6 +849,10 @@ # @min_wr_latency_ns: Minimum latency of write operations in the # defined interval, in nanoseconds. # +# @min_zone_append_latency_ns: Minimum latency of zone append operations +# in the defined interval, in nanoseconds +# (since 8.1) +# # @min_flush_latency_ns: Minimum latency of flush operations in the # defined interval, in nanoseconds. # @@ -858,6 +862,10 @@ # @max_wr_latency_ns: Maximum latency of write operations in the # defined interval, in nanoseconds. # +# @max_zone_append_latency_ns: Maximum latency of zone append operations +# in the defined interval, in nanoseconds +# (since 8.1) +# # @max_flush_latency_ns: Maximum latency of flush operations in the # defined interval, in nanoseconds. # @@ -867,6 +875,10 @@ # @avg_wr_latency_ns: Average latency of write operations in the # defined interval, in nanoseconds. # +# @avg_zone_append_latency_ns: Average latency of zone append operations +# in the defined interval, in nanoseconds +# (since 8.1) +# # @avg_flush_latency_ns: Average latency of flush operations in the # defined interval, in nanoseconds. # @@ -876,15 +888,23 @@ # @avg_wr_queue_depth: Average number of pending write operations # in the defined interval. # +# @avg_zone_append_queue_depth: Average number of pending zone append +# operations in the defined interval +# (since 8.1). +# # Since: 2.5 ## { 'struct': 'BlockDeviceTimedStats', 'data': { 'interval_length': 'int', 'min_rd_latency_ns': 'int', 'max_rd_latency_ns': 'int', 'avg_rd_latency_ns': 'int', 'min_wr_latency_ns': 'int', 'max_wr_latency_ns': 'int', - 'avg_wr_latency_ns': 'int', 'min_flush_latency_ns': 'int', - 'max_flush_latency_ns': 'int', 'avg_flush_latency_ns': 'int', - 'avg_rd_queue_depth': 'number', 'avg_wr_queue_depth': 'number' } } + 'avg_wr_latency_ns': 'int', 'min_zone_append_latency_ns': 'int', + 'max_zone_append_latency_ns': 'int', + 'avg_zone_append_latency_ns': 'int', + 'min_flush_latency_ns': 'int', 'max_flush_latency_ns': 'int', + 'avg_flush_latency_ns': 'int', 'avg_rd_queue_depth': 'number', + 'avg_wr_queue_depth': 'number', + 'avg_zone_append_queue_depth': 'number' } } ## # @BlockDeviceStats: @@ -895,12 +915,18 @@ # # @wr_bytes: The number of bytes written by the device. # +# @zone_append_bytes: The number of bytes appended by the zoned devices +# (since 8.1) +# # @unmap_bytes: The number of bytes unmapped by the device (Since 4.2) # # @rd_operations: The number of read operations performed by the device. # # @wr_operations: The number of write operations performed by the device. # +# @zone_append_operations: The number of zone append operations performed +# by the zoned devices (since 8.1) +# # @flush_operations: The number of cache flush operations performed by the # device (since 0.15) # @@ -911,6 +937,9 @@ # # @wr_total_time_ns: Total time spent on writes in nanoseconds (since 0.15). # +# @zone_append_total_time_ns: Total time spent on zone append writes +# in nanoseconds (since 8.1) +# # @flush_total_time_ns: Total time spent on cache flushes in nanoseconds # (since 0.15). # @@ -928,6 +957,9 @@ # @wr_merged: Number of write requests that have been merged into another # request (Since 2.3). # +# @zone_append_merged: Number of zone append requests that have been merged +# into another request (since 8.1) +# # @unmap_merged: Number of unmap requests that have been merged into another # request (Since 4.2) # @@ -941,6 +973,10 @@ # @failed_wr_operations: The number of failed write operations # performed by the device (Since 2.5) # +# @failed_zone_append_operations: The number of failed zone append write +# operations performed by the zoned devices +# (since 8.1) +# # @failed_flush_operations: The number of failed flush operations # performed by the device (Since 2.5) # @@ -953,6 +989,9 @@ # @invalid_wr_operations: The number of invalid write operations # performed by the device (Since 2.5) # +# @invalid_zone_append_operations: The number of invalid zone append operations +# performed by the zoned device (since 8.1) +# # @invalid_flush_operations: The number of invalid flush operations # performed by the device (Since 2.5) # @@ -972,27 +1011,34 @@ # # @wr_latency_histogram: @BlockLatencyHistogramInfo. (Since 4.0) # +# @zone_append_latency_histogram: @BlockLatencyHistogramInfo. (since 8.1) +# # @flush_latency_histogram: @BlockLatencyHistogramInfo. (Since 4.0) # # Since: 0.14 ## { 'struct': 'BlockDeviceStats', - 'data': {'rd_bytes': 'int', 'wr_bytes': 'int', 'unmap_bytes' : 'int', - 'rd_operations': 'int', 'wr_operations': 'int', + 'data': {'rd_bytes': 'int', 'wr_bytes': 'int', 'zone_append_bytes': 'int', + 'unmap_bytes' : 'int', 'rd_operations': 'int', + 'wr_operations': 'int', 'zone_append_operations': 'int', 'flush_operations': 'int', 'unmap_operations': 'int', 'rd_total_time_ns': 'int', 'wr_total_time_ns': 'int', - 'flush_total_time_ns': 'int', 'unmap_total_time_ns': 'int', - 'wr_highest_offset': 'int', - 'rd_merged': 'int', 'wr_merged': 'int', 'unmap_merged': 'int', - '*idle_time_ns': 'int', + 'zone_append_total_time_ns': 'int', 'flush_total_time_ns': 'int', + 'unmap_total_time_ns': 'int', 'wr_highest_offset': 'int', + 'rd_merged': 'int', 'wr_merged': 'int', 'zone_append_merged': 'int', + 'unmap_merged': 'int', '*idle_time_ns': 'int', 'failed_rd_operations': 'int', 'failed_wr_operations': 'int', - 'failed_flush_operations': 'int', 'failed_unmap_operations': 'int', - 'invalid_rd_operations': 'int', 'invalid_wr_operations': 'int', + 'failed_zone_append_operations': 'int', + 'failed_flush_operations': 'int', + 'failed_unmap_operations': 'int', 'invalid_rd_operations': 'int', + 'invalid_wr_operations': 'int', + 'invalid_zone_append_operations': 'int', 'invalid_flush_operations': 'int', 'invalid_unmap_operations': 'int', 'account_invalid': 'bool', 'account_failed': 'bool', 'timed_stats': ['BlockDeviceTimedStats'], '*rd_latency_histogram': 'BlockLatencyHistogramInfo', '*wr_latency_histogram': 'BlockLatencyHistogramInfo', + '*zone_append_latency_histogram': 'BlockLatencyHistogramInfo', '*flush_latency_histogram': 'BlockLatencyHistogramInfo' } } ## diff --git a/qapi/block.json b/qapi/block.json index 94339a1761..83ebad9568 100644 --- a/qapi/block.json +++ b/qapi/block.json @@ -525,6 +525,9 @@ # @boundaries-write: list of interval boundary values for write latency # histogram. # +# @boundaries-zap: list of interval boundary values for zone append write +# latency histogram. +# # @boundaries-flush: list of interval boundary values for flush latency # histogram. # @@ -573,5 +576,6 @@ '*boundaries': ['uint64'], '*boundaries-read': ['uint64'], '*boundaries-write': ['uint64'], + '*boundaries-zap': ['uint64'], '*boundaries-flush': ['uint64'] }, 'allow-preconfig': true } diff --git a/tests/qemu-iotests/227.out b/tests/qemu-iotests/227.out index 378c1b8fb1..a947b1a87d 100644 --- a/tests/qemu-iotests/227.out +++ b/tests/qemu-iotests/227.out @@ -17,6 +17,7 @@ Testing: -drive driver=null-co,read-zeroes=on,if=virtio "stats": { "unmap_operations": 0, "unmap_merged": 0, + "failed_zone_append_operations": 0, "flush_total_time_ns": 0, "wr_highest_offset": 0, "wr_total_time_ns": 0, @@ -27,6 +28,7 @@ Testing: -drive driver=null-co,read-zeroes=on,if=virtio "timed_stats": [ ], "failed_unmap_operations": 0, + "zone_append_merged": 0, "failed_flush_operations": 0, "account_invalid": true, "rd_total_time_ns": 0, @@ -39,7 +41,11 @@ Testing: -drive driver=null-co,read-zeroes=on,if=virtio "unmap_total_time_ns": 0, "invalid_flush_operations": 0, "account_failed": true, + "zone_append_total_time_ns": 0, + "zone_append_operations": 0, "rd_operations": 0, + "zone_append_bytes": 0, + "invalid_zone_append_operations": 0, "invalid_wr_operations": 0, "invalid_rd_operations": 0 }, @@ -82,6 +88,7 @@ Testing: -drive driver=null-co,if=none "stats": { "unmap_operations": 0, "unmap_merged": 0, + "failed_zone_append_operations": 0, "flush_total_time_ns": 0, "wr_highest_offset": 0, "wr_total_time_ns": 0, @@ -92,6 +99,7 @@ Testing: -drive driver=null-co,if=none "timed_stats": [ ], "failed_unmap_operations": 0, + "zone_append_merged": 0, "failed_flush_operations": 0, "account_invalid": true, "rd_total_time_ns": 0, @@ -104,7 +112,11 @@ Testing: -drive driver=null-co,if=none "unmap_total_time_ns": 0, "invalid_flush_operations": 0, "account_failed": true, + "zone_append_total_time_ns": 0, + "zone_append_operations": 0, "rd_operations": 0, + "zone_append_bytes": 0, + "invalid_zone_append_operations": 0, "invalid_wr_operations": 0, "invalid_rd_operations": 0 }, @@ -177,6 +189,7 @@ Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device virtio-b "stats": { "unmap_operations": 0, "unmap_merged": 0, + "failed_zone_append_operations": 0, "flush_total_time_ns": 0, "wr_highest_offset": 0, "wr_total_time_ns": 0, @@ -187,6 +200,7 @@ Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device virtio-b "timed_stats": [ ], "failed_unmap_operations": 0, + "zone_append_merged": 0, "failed_flush_operations": 0, "account_invalid": true, "rd_total_time_ns": 0, @@ -199,7 +213,11 @@ Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device virtio-b "unmap_total_time_ns": 0, "invalid_flush_operations": 0, "account_failed": true, + "zone_append_total_time_ns": 0, + "zone_append_operations": 0, "rd_operations": 0, + "zone_append_bytes": 0, + "invalid_zone_append_operations": 0, "invalid_wr_operations": 0, "invalid_rd_operations": 0 }, From patchwork Mon May 8 05:19:15 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Li X-Patchwork-Id: 13234053 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 6CEFCC77B75 for ; Mon, 8 May 2023 05:20:40 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pvtHk-0005qU-8t; Mon, 08 May 2023 01:19:44 -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 1pvtHi-0005jF-Hz; Mon, 08 May 2023 01:19:42 -0400 Received: from mail-pf1-x429.google.com ([2607:f8b0:4864:20::429]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1pvtHg-0002w5-Kg; Mon, 08 May 2023 01:19:42 -0400 Received: by mail-pf1-x429.google.com with SMTP id d2e1a72fcca58-643a6f993a7so1820293b3a.1; Sun, 07 May 2023 22:19:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1683523178; x=1686115178; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=PpvdI3M1HOtzilCHTXh4ZWumGK5yb3Wc1e0ALqP7+po=; b=pERCTeX/5y3qOBrKFP7Rb0zadWi/fHf15AEe/a+0IqSpaMWkOYX1WQNEUFSEdNpE1D kglNkDwr0z2bJyvBwkdfx1d2n16hanu+a9+yEJBS3xbgzASbr1aoYMHAt3iQNheUGZfZ qfCsZ6mZ9jEbDvXR0RjXE8GvkVPP2B9FBsfVfX1yhG08mwRZd0BtApZ+6fpJQ5R5ZUAo 8OHykViIjnMCBmrsoW9i7iEDBm0PzCCQGs++MheJua3I4bpPyzg4fK8GmXLx7Bj6RkM0 +RyWsWT5hKDtFrCHykwfMXG26xxnAa3C56UIje9pn9pa2BLenxbpotLBQWlT2ntseAob JeOA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1683523178; x=1686115178; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=PpvdI3M1HOtzilCHTXh4ZWumGK5yb3Wc1e0ALqP7+po=; b=OiBApOGRMlMw1MUVCvdlzcnTMo4JSugQ4iooqD4IzAaVCFC8RHR2R82sr0Jvls1JK3 UVKgC7WBKkDK1j2oJ3NBnfd6DUGmBDR6wz2fRYs484V8HwvxVIZW4wkkkVZipOd40YXy s7HBsR3KLDFsuF7Eaq13GRHt4hmz1fCrT7B+OYdpXRusv0ceeECRe2mBQ7dMe71xwsad 5oARySr3OslnWzmEMb5RNYpjbqnEaiP0x/cGBPldvfbciSfgeYjWihdEEY24dF6OJ++V TROd87qM0z1ipXnAGJXdlZk0DBlUlkIaotz1cADLKBbqo/tlEZ4sY+VacOn4jt0gvK3Z /pig== X-Gm-Message-State: AC+VfDxoIfkt5Sau7Vet0wLO0WgC2e7VdlWPe9N7ZadtuMIAzf53+NVb XRSc4iohpBXUZRLXWMhCKR2CctcBBYp9PhFK X-Google-Smtp-Source: ACHHUZ40k1rueDf6xieq/ISn4hRxCgb0GS6ZaMe2Op4QIE2LMLWatulAlgFea8AoJs26WGFCGQEEdA== X-Received: by 2002:a05:6a00:a8d:b0:63a:ece0:48d0 with SMTP id b13-20020a056a000a8d00b0063aece048d0mr13483563pfl.28.1683523177753; Sun, 07 May 2023 22:19:37 -0700 (PDT) Received: from fedlinux.. ([106.84.128.239]) by smtp.gmail.com with ESMTPSA id j1-20020aa783c1000000b0063a1e7d7439sm5247997pfn.69.2023.05.07.22.19.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 07 May 2023 22:19:37 -0700 (PDT) From: Sam Li To: qemu-devel@nongnu.org Cc: Raphael Norwitz , Hanna Reitz , Eric Blake , Stefan Hajnoczi , Kevin Wolf , Markus Armbruster , "Michael S. Tsirkin" , hare@suse.de, qemu-block@nongnu.org, dlemoal@kernel.org, dmitry.fomichev@wdc.com, Sam Li Subject: [PATCH v11 3/4] virtio-blk: add some trace events for zoned emulation Date: Mon, 8 May 2023 13:19:15 +0800 Message-Id: <20230508051916.178322-4-faithilikerun@gmail.com> X-Mailer: git-send-email 2.40.0 In-Reply-To: <20230508051916.178322-1-faithilikerun@gmail.com> References: <20230508051916.178322-1-faithilikerun@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::429; envelope-from=faithilikerun@gmail.com; helo=mail-pf1-x429.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 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, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 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: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Signed-off-by: Sam Li Reviewed-by: Stefan Hajnoczi --- hw/block/trace-events | 7 +++++++ hw/block/virtio-blk.c | 12 ++++++++++++ 2 files changed, 19 insertions(+) diff --git a/hw/block/trace-events b/hw/block/trace-events index 2c45a62bd5..34be8b9135 100644 --- a/hw/block/trace-events +++ b/hw/block/trace-events @@ -44,9 +44,16 @@ pflash_write_unknown(const char *name, uint8_t cmd) "%s: unknown command 0x%02x" # virtio-blk.c virtio_blk_req_complete(void *vdev, void *req, int status) "vdev %p req %p status %d" virtio_blk_rw_complete(void *vdev, void *req, int ret) "vdev %p req %p ret %d" +virtio_blk_zone_report_complete(void *vdev, void *req, unsigned int nr_zones, int ret) "vdev %p req %p nr_zones %u ret %d" +virtio_blk_zone_mgmt_complete(void *vdev, void *req, int ret) "vdev %p req %p ret %d" +virtio_blk_zone_append_complete(void *vdev, void *req, int64_t sector, int ret) "vdev %p req %p, append sector 0x%" PRIx64 " ret %d" virtio_blk_handle_write(void *vdev, void *req, uint64_t sector, size_t nsectors) "vdev %p req %p sector %"PRIu64" nsectors %zu" virtio_blk_handle_read(void *vdev, void *req, uint64_t sector, size_t nsectors) "vdev %p req %p sector %"PRIu64" nsectors %zu" virtio_blk_submit_multireq(void *vdev, void *mrb, int start, int num_reqs, uint64_t offset, size_t size, bool is_write) "vdev %p mrb %p start %d num_reqs %d offset %"PRIu64" size %zu is_write %d" +virtio_blk_handle_zone_report(void *vdev, void *req, int64_t sector, unsigned int nr_zones) "vdev %p req %p sector 0x%" PRIx64 " nr_zones %u" +virtio_blk_handle_zone_mgmt(void *vdev, void *req, uint8_t op, int64_t sector, int64_t len) "vdev %p req %p op 0x%x sector 0x%" PRIx64 " len 0x%" PRIx64 "" +virtio_blk_handle_zone_reset_all(void *vdev, void *req, int64_t sector, int64_t len) "vdev %p req %p sector 0x%" PRIx64 " cap 0x%" PRIx64 "" +virtio_blk_handle_zone_append(void *vdev, void *req, int64_t sector) "vdev %p req %p, append sector 0x%" PRIx64 "" # hd-geometry.c hd_geometry_lchs_guess(void *blk, int cyls, int heads, int secs) "blk %p LCHS %d %d %d" diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c index bf05251a75..8f65ea4659 100644 --- a/hw/block/virtio-blk.c +++ b/hw/block/virtio-blk.c @@ -676,6 +676,7 @@ static void virtio_blk_zone_report_complete(void *opaque, int ret) int64_t nz = data->zone_report_data.nr_zones; int8_t err_status = VIRTIO_BLK_S_OK; + trace_virtio_blk_zone_report_complete(vdev, req, nz, ret); if (ret) { err_status = VIRTIO_BLK_S_ZONE_INVALID_CMD; goto out; @@ -792,6 +793,8 @@ static void virtio_blk_handle_zone_report(VirtIOBlockReq *req, nr_zones = (req->in_len - sizeof(struct virtio_blk_inhdr) - sizeof(struct virtio_blk_zone_report)) / sizeof(struct virtio_blk_zone_descriptor); + trace_virtio_blk_handle_zone_report(vdev, req, + offset >> BDRV_SECTOR_BITS, nr_zones); zone_size = sizeof(BlockZoneDescriptor) * nr_zones; data = g_malloc(sizeof(ZoneCmdData)); @@ -814,7 +817,9 @@ static void virtio_blk_zone_mgmt_complete(void *opaque, int ret) { VirtIOBlockReq *req = opaque; VirtIOBlock *s = req->dev; + VirtIODevice *vdev = VIRTIO_DEVICE(s); int8_t err_status = VIRTIO_BLK_S_OK; + trace_virtio_blk_zone_mgmt_complete(vdev, req,ret); if (ret) { err_status = VIRTIO_BLK_S_ZONE_INVALID_CMD; @@ -841,6 +846,8 @@ static int virtio_blk_handle_zone_mgmt(VirtIOBlockReq *req, BlockZoneOp op) /* Entire drive capacity */ offset = 0; len = capacity; + trace_virtio_blk_handle_zone_reset_all(vdev, req, 0, + bs->total_sectors); } else { if (bs->bl.zone_size > capacity - offset) { /* The zoned device allows the last smaller zone. */ @@ -848,6 +855,9 @@ static int virtio_blk_handle_zone_mgmt(VirtIOBlockReq *req, BlockZoneOp op) } else { len = bs->bl.zone_size; } + trace_virtio_blk_handle_zone_mgmt(vdev, req, op, + offset >> BDRV_SECTOR_BITS, + len >> BDRV_SECTOR_BITS); } if (!check_zoned_request(s, offset, len, false, &err_status)) { @@ -888,6 +898,7 @@ static void virtio_blk_zone_append_complete(void *opaque, int ret) err_status = VIRTIO_BLK_S_ZONE_INVALID_CMD; goto out; } + trace_virtio_blk_zone_append_complete(vdev, req, append_sector, ret); out: aio_context_acquire(blk_get_aio_context(s->conf.conf.blk)); @@ -909,6 +920,7 @@ static int virtio_blk_handle_zone_append(VirtIOBlockReq *req, int64_t offset = virtio_ldq_p(vdev, &req->out.sector) << BDRV_SECTOR_BITS; int64_t len = iov_size(out_iov, out_num); + trace_virtio_blk_handle_zone_append(vdev, req, offset >> BDRV_SECTOR_BITS); if (!check_zoned_request(s, offset, len, true, &err_status)) { goto out; } From patchwork Mon May 8 05:19:16 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Li X-Patchwork-Id: 13234054 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id D8C1FC77B75 for ; Mon, 8 May 2023 05:20:43 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pvtHo-0005vO-Hs; Mon, 08 May 2023 01:19:48 -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 1pvtHm-0005uk-1l; Mon, 08 May 2023 01:19:46 -0400 Received: from mail-pf1-x430.google.com ([2607:f8b0:4864:20::430]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1pvtHk-0002xb-A6; Mon, 08 May 2023 01:19:45 -0400 Received: by mail-pf1-x430.google.com with SMTP id d2e1a72fcca58-6439d505274so2019549b3a.0; Sun, 07 May 2023 22:19:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1683523182; x=1686115182; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=vlz1D9sSRlg2wpkJDN4rWzGDm6M6wMtbI3+dKbQXJXY=; b=KzXhjhcMJs873dDzVV4MiL+3QhNqxt2D6XEZ4C3MGvV0ay4qbwRXjKTU5kto9umWk2 Xh7f754BDuax30tfNQFKujje4U4FkcfTkxBCfvxPLoJXnbcsCK8C3AZLU5GwR+Euvxra 7nLa/kxaUli/CMPOk3MZ9LQbg3N9c+WB/hBTjnAW/M7nykCiVcapsCx7xqo+B9hbbLGT s3Vi2QCgX4ULPfUnA1VYo0isUtSVMPsocHgQvYsXYqARe9tD+Y8QQd8JwRdNMcd09Ka0 QnlTykB2sWC3tnfaixxtjwcPksP9qFhHxAlZrxorQXopillDYj9xhf2ceYiMdtGgdT8Z 6u5g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1683523182; x=1686115182; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=vlz1D9sSRlg2wpkJDN4rWzGDm6M6wMtbI3+dKbQXJXY=; b=QbVFezuoFz7xNH48seGhQXNZrNWYp7QOLDwFJre1rCDE/BNZQMfbXRXeH0qe4VZDTR r4MmxQUl1PH5Hx/zpwe5BDzgd9eM0eX7HEl8hbuwDcmHxNgYRwrskdKojujN/I0F/Smk e3VkFxjBTtmx3W0y9sx+fYBYfVMLA7p93SPZ84Qm0rJNovOQcdbrFnbOkD2qGIcKxbOj kqX3KVNYOI+vyHd7rEyUXoozbzYjU0DGTqdU9Hw73CXO9GWwD9TD0hsviTmk9Wb1wLEA sd08cGEw8T96FWy9ITkDQG+ypbIWgt1sYVfcjOfxNn1yHZeNfl2i/3fQunU1vFex60LZ J7Ww== X-Gm-Message-State: AC+VfDwVWKpfj9T8QyAUd305xZfB8lDHVUGH8NsDh0LGssnPhMpRuH2Z 18OGHOLDpzal02v1nRt4xgUGPH+nYQ9XO6NA X-Google-Smtp-Source: ACHHUZ62H0WVyKpInYOzR7GjA7qkuV+r9sHWQbnEgd6C+ohCSeY3JDIOaIUw17qFpRPDqferhsSAAQ== X-Received: by 2002:a05:6a20:4326:b0:100:3258:d163 with SMTP id h38-20020a056a20432600b001003258d163mr3985520pzk.35.1683523181968; Sun, 07 May 2023 22:19:41 -0700 (PDT) Received: from fedlinux.. ([106.84.128.239]) by smtp.gmail.com with ESMTPSA id j1-20020aa783c1000000b0063a1e7d7439sm5247997pfn.69.2023.05.07.22.19.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 07 May 2023 22:19:41 -0700 (PDT) From: Sam Li To: qemu-devel@nongnu.org Cc: Raphael Norwitz , Hanna Reitz , Eric Blake , Stefan Hajnoczi , Kevin Wolf , Markus Armbruster , "Michael S. Tsirkin" , hare@suse.de, qemu-block@nongnu.org, dlemoal@kernel.org, dmitry.fomichev@wdc.com, Sam Li Subject: [PATCH v11 4/4] docs/zoned-storage:add zoned emulation use case Date: Mon, 8 May 2023 13:19:16 +0800 Message-Id: <20230508051916.178322-5-faithilikerun@gmail.com> X-Mailer: git-send-email 2.40.0 In-Reply-To: <20230508051916.178322-1-faithilikerun@gmail.com> References: <20230508051916.178322-1-faithilikerun@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::430; envelope-from=faithilikerun@gmail.com; helo=mail-pf1-x430.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 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, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 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: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Add the documentation about the example of using virtio-blk driver to pass the zoned block devices through to the guest. Signed-off-by: Sam Li --- docs/devel/zoned-storage.rst | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/docs/devel/zoned-storage.rst b/docs/devel/zoned-storage.rst index 6a36133e51..05ecf3729c 100644 --- a/docs/devel/zoned-storage.rst +++ b/docs/devel/zoned-storage.rst @@ -41,3 +41,20 @@ APIs for zoned storage emulation or testing. For example, to test zone_report on a null_blk device using qemu-io is: $ path/to/qemu-io --image-opts -n driver=host_device,filename=/dev/nullb0 -c "zrp offset nr_zones" + +To expose the host's zoned block device through virtio-blk, the command line +can be (includes the -device parameter): + -blockdev node-name=drive0,driver=host_device,filename=/dev/nullb0, + cache.direct=on \ + -device virtio-blk-pci,drive=drive0 +Or only use the -drive parameter: + -driver driver=host_device,file=/dev/nullb0,if=virtio,cache.direct=on + +Additionally, QEMU has several ways of supporting zoned storage, including: +(1) Using virtio-scsi: --device scsi-block allows for the passing through of +SCSI ZBC devices, enabling the attachment of ZBC or ZAC HDDs to QEMU. +(2) PCI device pass-through: While NVMe ZNS emulation is available for testing +purposes, it cannot yet pass through a zoned device from the host. To pass on +the NVMe ZNS device to the guest, use VFIO PCI pass the entire NVMe PCI adapter +through to the guest. Likewise, an HDD HBA can be passed on to QEMU all HDDs +attached to the HBA.