* [PATCH 0/2] virtio-blk: Add support for FUA write requests
@ 2026-10-21 6:22 Alberto Faria
2026-10-21 6:22 ` [PATCH 1/2] include: Add virtio-blk request flag FUA definitions Alberto Faria
2026-10-21 6:22 ` [PATCH 2/2] virtio-blk: Add support for FUA write requests Alberto Faria
0 siblings, 2 replies; 7+ messages in thread
From: Alberto Faria @ 2026-10-21 6:22 UTC (permalink / raw)
To: qemu-block, qemu-devel
Cc: Kevin Wolf, Hanna Reitz, Zhao Liu, Paolo Bonzini,
Michael S. Tsirkin, Stefan Hajnoczi, Cornelia Huck,
Philippe Mathieu-Daudé, Alberto Faria
virtio-blk FUA write support has been introduced to the virtio spec [1], and a
kernel patch is under review [2]. This patch enables FUA on the virtio-blk
device, so guests can submit FUA writes instead of the slower alternative of a
regular write followed by a flush.
A simple randwrite fio workload on a RAM disk (bs=4k, iodepth=1, direct=1,
sync=1) shows a throughput improvement of 17.1k IOPS to 27.7k IOPS (+62%).
[1] https://lore.kernel.org/virtio-comment/20251112055113.62207-1-afaria@redhat.com/
[2] https://lore.kernel.org/linux-block/20261021055235.648957-1-afaria@redhat.com/
Alberto Faria (2):
include: Add virtio-blk request flag FUA definitions
virtio-blk: Add support for FUA write requests
hw/block/virtio-blk.c | 27 +++++++++++++++++++++
hw/core/machine.c | 1 +
hw/virtio/virtio-qmp.c | 4 +++
include/hw/virtio/virtio-blk.h | 1 +
include/standard-headers/linux/virtio_blk.h | 13 ++++++++--
5 files changed, 44 insertions(+), 2 deletions(-)
--
2.56.0
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/2] include: Add virtio-blk request flag FUA definitions
2026-10-21 6:22 [PATCH 0/2] virtio-blk: Add support for FUA write requests Alberto Faria
@ 2026-10-21 6:22 ` Alberto Faria
2026-10-21 7:59 ` Cornelia Huck
2026-10-21 6:22 ` [PATCH 2/2] virtio-blk: Add support for FUA write requests Alberto Faria
1 sibling, 1 reply; 7+ messages in thread
From: Alberto Faria @ 2026-10-21 6:22 UTC (permalink / raw)
To: qemu-block, qemu-devel
Cc: Kevin Wolf, Hanna Reitz, Zhao Liu, Paolo Bonzini,
Michael S. Tsirkin, Stefan Hajnoczi, Cornelia Huck,
Philippe Mathieu-Daudé, Alberto Faria
Signed-off-by: Alberto Faria <afaria@redhat.com>
---
include/standard-headers/linux/virtio_blk.h | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/include/standard-headers/linux/virtio_blk.h b/include/standard-headers/linux/virtio_blk.h
index d7be3cf5e4..c6c8ce1eec 100644
--- a/include/standard-headers/linux/virtio_blk.h
+++ b/include/standard-headers/linux/virtio_blk.h
@@ -42,6 +42,8 @@
#define VIRTIO_BLK_F_WRITE_ZEROES 14 /* WRITE ZEROES is supported */
#define VIRTIO_BLK_F_SECURE_ERASE 16 /* Secure Erase is supported */
#define VIRTIO_BLK_F_ZONED 17 /* Zoned block device */
+#define VIRTIO_BLK_F_REQ_FLAGS 18 /* Request flags supported */
+#define VIRTIO_BLK_F_REQ_FLAGS_OUT_FUA 19 /* FUA flag supported */
/* Legacy feature bits */
#ifndef VIRTIO_BLK_NO_LEGACY
@@ -209,6 +211,9 @@ struct virtio_blk_config {
#define VIRTIO_BLK_T_BARRIER 0x80000000
#endif /* !VIRTIO_BLK_NO_LEGACY */
+/* Request flag bits */
+#define VIRTIO_BLK_REQ_FLAG_OUT_FUA 0
+
/*
* This comes first in the read scatter-gather list.
* For legacy virtio, if VIRTIO_F_ANY_LAYOUT is not negotiated,
@@ -217,8 +222,12 @@ struct virtio_blk_config {
struct virtio_blk_outhdr {
/* VIRTIO_BLK_T* */
__virtio32 type;
- /* io priority. */
- __virtio32 ioprio;
+ union {
+ /* io priority. */
+ __virtio32 ioprio;
+ /* Request flags. */
+ __virtio32 flags;
+ };
/* Sector (ie. 512 byte offset) */
__virtio64 sector;
};
--
2.56.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/2] virtio-blk: Add support for FUA write requests
2026-10-21 6:22 [PATCH 0/2] virtio-blk: Add support for FUA write requests Alberto Faria
2026-10-21 6:22 ` [PATCH 1/2] include: Add virtio-blk request flag FUA definitions Alberto Faria
@ 2026-10-21 6:22 ` Alberto Faria
2026-10-28 19:55 ` Stefan Hajnoczi
1 sibling, 1 reply; 7+ messages in thread
From: Alberto Faria @ 2026-10-21 6:22 UTC (permalink / raw)
To: qemu-block, qemu-devel
Cc: Kevin Wolf, Hanna Reitz, Zhao Liu, Paolo Bonzini,
Michael S. Tsirkin, Stefan Hajnoczi, Cornelia Huck,
Philippe Mathieu-Daudé, Alberto Faria
Signed-off-by: Alberto Faria <afaria@redhat.com>
---
hw/block/virtio-blk.c | 27 +++++++++++++++++++++++++++
hw/core/machine.c | 1 +
hw/virtio/virtio-qmp.c | 4 ++++
include/hw/virtio/virtio-blk.h | 1 +
4 files changed, 33 insertions(+)
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index 61c341ce2c..3e01e043bd 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -219,6 +219,7 @@ static inline void submit_requests(VirtIOBlock *s, MultiReqBuffer *mrb,
QEMUIOVector *qiov = &mrb->reqs[start]->qiov;
int64_t sector_num = mrb->reqs[start]->sector_num;
bool is_write = mrb->is_write;
+ bool is_fua = mrb->is_fua;
BdrvRequestFlags flags = 0;
if (num_reqs > 1) {
@@ -255,6 +256,9 @@ static inline void submit_requests(VirtIOBlock *s, MultiReqBuffer *mrb,
}
if (is_write) {
+ if (is_fua) {
+ flags |= BDRV_REQ_FUA;
+ }
blk_aio_pwritev(blk, sector_num << BDRV_SECTOR_BITS, qiov,
flags, virtio_blk_rw_complete,
mrb->reqs[start]);
@@ -829,6 +833,7 @@ out:
static int virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb)
{
uint32_t type;
+ uint32_t flags;
struct iovec *in_iov = req->elem.in_sg;
struct iovec *out_iov = req->elem.out_sg;
unsigned in_num = req->elem.in_num;
@@ -865,6 +870,7 @@ static int virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb)
&req->inhdr_undo);
type = virtio_ldl_p(vdev, &req->out.type);
+ flags = virtio_ldl_p(vdev, &req->out.flags);
/* VIRTIO_BLK_T_OUT defines the command direction. VIRTIO_BLK_T_BARRIER
* is an optional flag. Although a guest should not send this flag if
@@ -873,6 +879,9 @@ static int virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb)
case VIRTIO_BLK_T_IN:
{
bool is_write = type & VIRTIO_BLK_T_OUT;
+ bool is_fua = is_write &&
+ virtio_vdev_has_feature(vdev, VIRTIO_BLK_F_REQ_FLAGS_OUT_FUA) &&
+ (flags & (1U << VIRTIO_BLK_REQ_FLAG_OUT_FUA));
req->sector_num = virtio_ldq_p(vdev, &req->out.sector);
if (is_write) {
@@ -900,6 +909,7 @@ static int virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb)
* changes */
if (mrb->num_reqs > 0 && (mrb->num_reqs == VIRTIO_BLK_MAX_MERGE_REQS ||
is_write != mrb->is_write ||
+ is_fua != mrb->is_fua ||
!s->conf.request_merging)) {
virtio_blk_submit_multireq(s, mrb);
}
@@ -907,6 +917,7 @@ static int virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb)
assert(mrb->num_reqs < VIRTIO_BLK_MAX_MERGE_REQS);
mrb->reqs[mrb->num_reqs++] = req;
mrb->is_write = is_write;
+ mrb->is_fua = is_fua;
break;
}
case VIRTIO_BLK_T_FLUSH:
@@ -1283,6 +1294,10 @@ static uint64_t virtio_blk_get_features(VirtIODevice *vdev, uint64_t features,
/* Firstly sync all virtio-blk possible supported features */
features |= s->host_features;
+ if (virtio_has_feature(features, VIRTIO_BLK_F_REQ_FLAGS_OUT_FUA)) {
+ virtio_add_feature(&features, VIRTIO_BLK_F_REQ_FLAGS);
+ }
+
virtio_add_feature(&features, VIRTIO_BLK_F_SEG_MAX);
virtio_add_feature(&features, VIRTIO_BLK_F_GEOMETRY);
virtio_add_feature(&features, VIRTIO_BLK_F_TOPOLOGY);
@@ -1308,6 +1323,15 @@ static uint64_t virtio_blk_get_features(VirtIODevice *vdev, uint64_t features,
return features;
}
+static int virtio_blk_validate_features(VirtIODevice *vdev)
+{
+ if (virtio_vdev_has_feature(vdev, VIRTIO_BLK_F_REQ_FLAGS_OUT_FUA) &&
+ !virtio_vdev_has_feature(vdev, VIRTIO_BLK_F_REQ_FLAGS)) {
+ return -EINVAL;
+ }
+ return 0;
+}
+
static int virtio_blk_set_status(VirtIODevice *vdev, uint8_t status)
{
VirtIOBlock *s = VIRTIO_BLK(vdev);
@@ -1925,6 +1949,8 @@ static const Property virtio_blk_properties[] = {
conf.max_discard_sectors, BDRV_REQUEST_MAX_SECTORS),
DEFINE_PROP_UINT32("max-write-zeroes-sectors", VirtIOBlock,
conf.max_write_zeroes_sectors, BDRV_REQUEST_MAX_SECTORS),
+ DEFINE_PROP_BIT64("fua", VirtIOBlock, host_features,
+ VIRTIO_BLK_F_REQ_FLAGS_OUT_FUA, true),
DEFINE_PROP_BOOL("x-enable-wce-if-config-wce", VirtIOBlock,
conf.x_enable_wce_if_config_wce, true),
};
@@ -1942,6 +1968,7 @@ static void virtio_blk_class_init(ObjectClass *klass, const void *data)
vdc->get_config = virtio_blk_update_config;
vdc->set_config = virtio_blk_set_config;
vdc->get_features = virtio_blk_get_features;
+ vdc->validate_features = virtio_blk_validate_features;
vdc->set_status = virtio_blk_set_status;
vdc->reset = virtio_blk_reset;
vdc->save = virtio_blk_save_device;
diff --git a/hw/core/machine.c b/hw/core/machine.c
index d9ac4b419a..7fc1853dab 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -43,6 +43,7 @@
GlobalProperty hw_compat_11_1[] = {
{ "sysbus-ehci-usb", "x-migrate-fetch-addr-64bit", "off" },
{ "pci-ehci-usb", "x-migrate-fetch-addr-64bit", "off" },
+ { "virtio-blk-device", "fua", "off" },
};
const size_t hw_compat_11_1_len = G_N_ELEMENTS(hw_compat_11_1);
diff --git a/hw/virtio/virtio-qmp.c b/hw/virtio/virtio-qmp.c
index 5aaeebdd96..4aaab650c6 100644
--- a/hw/virtio/virtio-qmp.c
+++ b/hw/virtio/virtio-qmp.c
@@ -171,6 +171,10 @@ static const qmp_virtio_feature_map_t virtio_blk_feature_map[] = {
"VIRTIO_BLK_F_SECURE_ERASE: Secure erase supported"),
FEATURE_ENTRY(VIRTIO_BLK_F_ZONED, \
"VIRTIO_BLK_F_ZONED: Zoned block devices"),
+ FEATURE_ENTRY(VIRTIO_BLK_F_REQ_FLAGS, \
+ "VIRTIO_BLK_F_REQ_FLAGS: Request flags supported"),
+ FEATURE_ENTRY(VIRTIO_BLK_F_REQ_FLAGS_OUT_FUA, \
+ "VIRTIO_BLK_F_REQ_FLAGS_OUT_FUA: FUA flag for OUT requests"),
FEATURE_ENTRY(VIRTIO_BLK_F_BARRIER, \
"VIRTIO_BLK_F_BARRIER: Request barriers supported"),
FEATURE_ENTRY(VIRTIO_BLK_F_SCSI, \
diff --git a/include/hw/virtio/virtio-blk.h b/include/hw/virtio/virtio-blk.h
index 3d8dee7ec1..916df26b6f 100644
--- a/include/hw/virtio/virtio-blk.h
+++ b/include/hw/virtio/virtio-blk.h
@@ -98,6 +98,7 @@ typedef struct MultiReqBuffer {
VirtIOBlockReq *reqs[VIRTIO_BLK_MAX_MERGE_REQS];
unsigned int num_reqs;
bool is_write;
+ bool is_fua;
} MultiReqBuffer;
typedef struct VirtIOBlkClass {
--
2.56.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] include: Add virtio-blk request flag FUA definitions
2026-10-21 6:22 ` [PATCH 1/2] include: Add virtio-blk request flag FUA definitions Alberto Faria
@ 2026-10-21 7:59 ` Cornelia Huck
2026-10-21 12:22 ` Kevin Wolf
0 siblings, 1 reply; 7+ messages in thread
From: Cornelia Huck @ 2026-10-21 7:59 UTC (permalink / raw)
To: Alberto Faria, qemu-block, qemu-devel
Cc: Kevin Wolf, Hanna Reitz, Zhao Liu, Paolo Bonzini,
Michael S. Tsirkin, Stefan Hajnoczi, Philippe Mathieu-Daudé,
Alberto Faria
On Wed, Oct 21 2026, Alberto Faria <afaria@redhat.com> wrote:
> Signed-off-by: Alberto Faria <afaria@redhat.com>
> ---
> include/standard-headers/linux/virtio_blk.h | 13 +++++++++++--
> 1 file changed, 11 insertions(+), 2 deletions(-)
>
Maybe explicitly mark as *placeholder*, so it doesn't get merged
accidentally?
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] include: Add virtio-blk request flag FUA definitions
2026-10-21 7:59 ` Cornelia Huck
@ 2026-10-21 12:22 ` Kevin Wolf
2026-10-21 12:37 ` Cornelia Huck
0 siblings, 1 reply; 7+ messages in thread
From: Kevin Wolf @ 2026-10-21 12:22 UTC (permalink / raw)
To: Cornelia Huck
Cc: Alberto Faria, qemu-block, qemu-devel, Hanna Reitz, Zhao Liu,
Paolo Bonzini, Michael S. Tsirkin, Stefan Hajnoczi,
Philippe Mathieu-Daudé
Am 21.10.2026 um 09:59 hat Cornelia Huck geschrieben:
> On Wed, Oct 21 2026, Alberto Faria <afaria@redhat.com> wrote:
>
> > Signed-off-by: Alberto Faria <afaria@redhat.com>
> > ---
> > include/standard-headers/linux/virtio_blk.h | 13 +++++++++++--
> > 1 file changed, 11 insertions(+), 2 deletions(-)
>
> Maybe explicitly mark as *placeholder*, so it doesn't get merged
> accidentally?
What is the proper (or at least common) way to do this? Do we really
have to wait for Linux to merge the guest driver side of virtio device
changes before we can add the emulation in QEMU?
Kevin
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] include: Add virtio-blk request flag FUA definitions
2026-10-21 12:22 ` Kevin Wolf
@ 2026-10-21 12:37 ` Cornelia Huck
0 siblings, 0 replies; 7+ messages in thread
From: Cornelia Huck @ 2026-10-21 12:37 UTC (permalink / raw)
To: Kevin Wolf
Cc: Alberto Faria, qemu-block, qemu-devel, Hanna Reitz, Zhao Liu,
Paolo Bonzini, Michael S. Tsirkin, Stefan Hajnoczi,
Philippe Mathieu-Daudé
On Wed, Oct 21 2026, Kevin Wolf <kwolf@redhat.com> wrote:
> Am 21.10.2026 um 09:59 hat Cornelia Huck geschrieben:
>> On Wed, Oct 21 2026, Alberto Faria <afaria@redhat.com> wrote:
>>
>> > Signed-off-by: Alberto Faria <afaria@redhat.com>
>> > ---
>> > include/standard-headers/linux/virtio_blk.h | 13 +++++++++++--
>> > 1 file changed, 11 insertions(+), 2 deletions(-)
>>
>> Maybe explicitly mark as *placeholder*, so it doesn't get merged
>> accidentally?
>
> What is the proper (or at least common) way to do this? Do we really
> have to wait for Linux to merge the guest driver side of virtio device
> changes before we can add the emulation in QEMU?
If we have some changes in the synced-from-Linux headers, we really need
to do a proper header sync to get them (or the next sync might remove
the changes again...) So yes, this unfortunately needs to wait for a
kernel with the changes (can be -rc)...
***
The other question (not really related to this patch set, maybe
warranting a separate discussion): Should we move the host <-> guest
interface definition to a third place that both Linux and QEMU (and any
other piece of software) can sync from? Source-of-truth is the virtio
spec, so in a perfect world QEMU should not have to wait for a Linux
kernel with the definitions to be released once it has been enshrined
there. Grabbing everything from Linux is something that did get the job
done and avoided duplicating code, but maybe it's time to revisit this.
(We obviously should keep syncing headers for actual kernel <->
userspace interfaces.)
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] virtio-blk: Add support for FUA write requests
2026-10-21 6:22 ` [PATCH 2/2] virtio-blk: Add support for FUA write requests Alberto Faria
@ 2026-10-28 19:55 ` Stefan Hajnoczi
0 siblings, 0 replies; 7+ messages in thread
From: Stefan Hajnoczi @ 2026-10-28 19:55 UTC (permalink / raw)
To: Alberto Faria
Cc: qemu-block, qemu-devel, Kevin Wolf, Hanna Reitz, Zhao Liu,
Paolo Bonzini, Michael S. Tsirkin, Cornelia Huck,
Philippe Mathieu-Daudé
On Wed, Oct 21, 2026 at 07:22:57AM +0100, Alberto Faria wrote:
> Signed-off-by: Alberto Faria <afaria@redhat.com>
> ---
> hw/block/virtio-blk.c | 27 +++++++++++++++++++++++++++
> hw/core/machine.c | 1 +
> hw/virtio/virtio-qmp.c | 4 ++++
> include/hw/virtio/virtio-blk.h | 1 +
> 4 files changed, 33 insertions(+)
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-10-28 19:56 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-21 6:22 [PATCH 0/2] virtio-blk: Add support for FUA write requests Alberto Faria
2026-10-21 6:22 ` [PATCH 1/2] include: Add virtio-blk request flag FUA definitions Alberto Faria
2026-10-21 7:59 ` Cornelia Huck
2026-10-21 12:22 ` Kevin Wolf
2026-10-21 12:37 ` Cornelia Huck
2026-10-21 6:22 ` [PATCH 2/2] virtio-blk: Add support for FUA write requests Alberto Faria
2026-10-28 19:55 ` Stefan Hajnoczi
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.