All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/2] scsi-disk: Add FUA write support
@ 2025-05-02 12:11 Alberto Faria
  2025-05-02 12:11 ` [PATCH v3 1/2] scsi-disk: Add native " Alberto Faria
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Alberto Faria @ 2025-05-02 12:11 UTC (permalink / raw)
  To: qemu-devel
  Cc: Yanan Wang, Paolo Bonzini, Philippe Mathieu-Daudé, Zhao Liu,
	Marcel Apfelbaum, Eduardo Habkost, Fam Zheng, Kevin Wolf,
	qemu-block, Alberto Faria

Add scsi-disk support for Force Unit Access (FUA) writes. The first patch lets
us avoid FUA emulation when the underlying driver supports it natively. The
second patch makes scsi-disk devices advertise FUA support by default.

v3:
- Restore flush on VERIFY.
- Modify hw_compat_10_0 instead of hw_compat_9_2.

v2:
- Drop FUA write emulation logic since the block layer already does that.
- Add machine type compat for "dpofua".

Alberto Faria (2):
  scsi-disk: Add native FUA write support
  scsi-disk: Advertise FUA support by default

 hw/core/machine.c   |  4 +++-
 hw/scsi/scsi-disk.c | 55 +++++++++++++--------------------------------
 2 files changed, 19 insertions(+), 40 deletions(-)

-- 
2.49.0



^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v3 1/2] scsi-disk: Add native FUA write support
  2025-05-02 12:11 [PATCH v3 0/2] scsi-disk: Add FUA write support Alberto Faria
@ 2025-05-02 12:11 ` Alberto Faria
  2025-05-02 12:11 ` [PATCH v3 2/2] scsi-disk: Advertise FUA support by default Alberto Faria
  2025-05-13 12:45 ` [PATCH v3 0/2] scsi-disk: Add FUA write support Kevin Wolf
  2 siblings, 0 replies; 4+ messages in thread
From: Alberto Faria @ 2025-05-02 12:11 UTC (permalink / raw)
  To: qemu-devel
  Cc: Yanan Wang, Paolo Bonzini, Philippe Mathieu-Daudé, Zhao Liu,
	Marcel Apfelbaum, Eduardo Habkost, Fam Zheng, Kevin Wolf,
	qemu-block, Alberto Faria

Simply propagate the FUA flag on write requests to the driver. The block
layer will emulate it if necessary.

Signed-off-by: Alberto Faria <afaria@redhat.com>
---
 hw/scsi/scsi-disk.c | 53 +++++++++++++--------------------------------
 1 file changed, 15 insertions(+), 38 deletions(-)

diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index cb4af1b715..738d8df8ec 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -74,7 +74,7 @@ struct SCSIDiskClass {
      */
     DMAIOFunc       *dma_readv;
     DMAIOFunc       *dma_writev;
-    bool            (*need_fua_emulation)(SCSICommand *cmd);
+    bool            (*need_fua)(SCSICommand *cmd);
     void            (*update_sense)(SCSIRequest *r);
 };
 
@@ -85,7 +85,7 @@ typedef struct SCSIDiskReq {
     uint32_t sector_count;
     uint32_t buflen;
     bool started;
-    bool need_fua_emulation;
+    bool need_fua;
     struct iovec iov;
     QEMUIOVector qiov;
     BlockAcctCookie acct;
@@ -389,24 +389,6 @@ static bool scsi_is_cmd_fua(SCSICommand *cmd)
     }
 }
 
-static void scsi_write_do_fua(SCSIDiskReq *r)
-{
-    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
-
-    assert(r->req.aiocb == NULL);
-    assert(!r->req.io_canceled);
-
-    if (r->need_fua_emulation) {
-        block_acct_start(blk_get_stats(s->qdev.conf.blk), &r->acct, 0,
-                         BLOCK_ACCT_FLUSH);
-        r->req.aiocb = blk_aio_flush(s->qdev.conf.blk, scsi_aio_complete, r);
-        return;
-    }
-
-    scsi_req_complete(&r->req, GOOD);
-    scsi_req_unref(&r->req);
-}
-
 static void scsi_dma_complete_noio(SCSIDiskReq *r, int ret)
 {
     assert(r->req.aiocb == NULL);
@@ -416,12 +398,7 @@ static void scsi_dma_complete_noio(SCSIDiskReq *r, int ret)
 
     r->sector += r->sector_count;
     r->sector_count = 0;
-    if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
-        scsi_write_do_fua(r);
-        return;
-    } else {
-        scsi_req_complete(&r->req, GOOD);
-    }
+    scsi_req_complete(&r->req, GOOD);
 
 done:
     scsi_req_unref(&r->req);
@@ -564,7 +541,7 @@ static void scsi_read_data(SCSIRequest *req)
 
     first = !r->started;
     r->started = true;
-    if (first && r->need_fua_emulation) {
+    if (first && r->need_fua) {
         block_acct_start(blk_get_stats(s->qdev.conf.blk), &r->acct, 0,
                          BLOCK_ACCT_FLUSH);
         r->req.aiocb = blk_aio_flush(s->qdev.conf.blk, scsi_do_read_cb, r);
@@ -589,8 +566,7 @@ static void scsi_write_complete_noio(SCSIDiskReq *r, int ret)
     r->sector += n;
     r->sector_count -= n;
     if (r->sector_count == 0) {
-        scsi_write_do_fua(r);
-        return;
+        scsi_req_complete(&r->req, GOOD);
     } else {
         scsi_init_iovec(r, SCSI_DMA_BUF_SIZE);
         trace_scsi_disk_write_complete_noio(r->req.tag, r->qiov.size);
@@ -623,6 +599,7 @@ static void scsi_write_data(SCSIRequest *req)
     SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
     SCSIDiskClass *sdc = (SCSIDiskClass *) object_get_class(OBJECT(s));
+    BlockCompletionFunc *cb;
 
     /* No data transfer may already be in progress */
     assert(r->req.aiocb == NULL);
@@ -648,11 +625,10 @@ static void scsi_write_data(SCSIRequest *req)
 
     if (r->req.cmd.buf[0] == VERIFY_10 || r->req.cmd.buf[0] == VERIFY_12 ||
         r->req.cmd.buf[0] == VERIFY_16) {
-        if (r->req.sg) {
-            scsi_dma_complete_noio(r, 0);
-        } else {
-            scsi_write_complete_noio(r, 0);
-        }
+        block_acct_start(blk_get_stats(s->qdev.conf.blk), &r->acct, 0,
+                         BLOCK_ACCT_FLUSH);
+        cb = r->req.sg ? scsi_dma_complete : scsi_write_complete;
+        r->req.aiocb = blk_aio_flush(s->qdev.conf.blk, cb, r);
         return;
     }
 
@@ -2391,7 +2367,7 @@ static int32_t scsi_disk_dma_command(SCSIRequest *req, uint8_t *buf)
         scsi_check_condition(r, SENSE_CODE(LBA_OUT_OF_RANGE));
         return 0;
     }
-    r->need_fua_emulation = sdc->need_fua_emulation(&r->req.cmd);
+    r->need_fua = sdc->need_fua(&r->req.cmd);
     if (r->sector_count == 0) {
         scsi_req_complete(&r->req, GOOD);
     }
@@ -3137,7 +3113,8 @@ BlockAIOCB *scsi_dma_writev(int64_t offset, QEMUIOVector *iov,
 {
     SCSIDiskReq *r = opaque;
     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
-    return blk_aio_pwritev(s->qdev.conf.blk, offset, iov, 0, cb, cb_opaque);
+    int flags = r->need_fua ? BDRV_REQ_FUA : 0;
+    return blk_aio_pwritev(s->qdev.conf.blk, offset, iov, flags, cb, cb_opaque);
 }
 
 static char *scsi_property_get_loadparm(Object *obj, Error **errp)
@@ -3186,7 +3163,7 @@ static void scsi_disk_base_class_initfn(ObjectClass *klass, const void *data)
     device_class_set_legacy_reset(dc, scsi_disk_reset);
     sdc->dma_readv = scsi_dma_readv;
     sdc->dma_writev = scsi_dma_writev;
-    sdc->need_fua_emulation = scsi_is_cmd_fua;
+    sdc->need_fua  = scsi_is_cmd_fua;
 }
 
 static const TypeInfo scsi_disk_base_info = {
@@ -3338,7 +3315,7 @@ static void scsi_block_class_initfn(ObjectClass *klass, const void *data)
     sdc->dma_readv   = scsi_block_dma_readv;
     sdc->dma_writev  = scsi_block_dma_writev;
     sdc->update_sense = scsi_block_update_sense;
-    sdc->need_fua_emulation = scsi_block_no_fua;
+    sdc->need_fua    = scsi_block_no_fua;
     dc->desc = "SCSI block device passthrough";
     device_class_set_props(dc, scsi_block_properties);
     dc->vmsd  = &vmstate_scsi_disk_state;
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v3 2/2] scsi-disk: Advertise FUA support by default
  2025-05-02 12:11 [PATCH v3 0/2] scsi-disk: Add FUA write support Alberto Faria
  2025-05-02 12:11 ` [PATCH v3 1/2] scsi-disk: Add native " Alberto Faria
@ 2025-05-02 12:11 ` Alberto Faria
  2025-05-13 12:45 ` [PATCH v3 0/2] scsi-disk: Add FUA write support Kevin Wolf
  2 siblings, 0 replies; 4+ messages in thread
From: Alberto Faria @ 2025-05-02 12:11 UTC (permalink / raw)
  To: qemu-devel
  Cc: Yanan Wang, Paolo Bonzini, Philippe Mathieu-Daudé, Zhao Liu,
	Marcel Apfelbaum, Eduardo Habkost, Fam Zheng, Kevin Wolf,
	qemu-block, Alberto Faria

Allow the guest to submit FUA requests directly, instead of forcing it
to emulate them using a regular flush.

Signed-off-by: Alberto Faria <afaria@redhat.com>
---
 hw/core/machine.c   | 4 +++-
 hw/scsi/scsi-disk.c | 2 +-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/hw/core/machine.c b/hw/core/machine.c
index ed01798d37..0e3d8c4065 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -37,7 +37,9 @@
 #include "hw/virtio/virtio-iommu.h"
 #include "audio/audio.h"
 
-GlobalProperty hw_compat_10_0[] = {};
+GlobalProperty hw_compat_10_0[] = {
+    { "scsi-hd", "dpofua", "off" },
+};
 const size_t hw_compat_10_0_len = G_N_ELEMENTS(hw_compat_10_0);
 
 GlobalProperty hw_compat_9_2[] = {
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index 738d8df8ec..b4782c6248 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -3192,7 +3192,7 @@ static const Property scsi_hd_properties[] = {
     DEFINE_PROP_BIT("removable", SCSIDiskState, features,
                     SCSI_DISK_F_REMOVABLE, false),
     DEFINE_PROP_BIT("dpofua", SCSIDiskState, features,
-                    SCSI_DISK_F_DPOFUA, false),
+                    SCSI_DISK_F_DPOFUA, true),
     DEFINE_PROP_UINT64("wwn", SCSIDiskState, qdev.wwn, 0),
     DEFINE_PROP_UINT64("port_wwn", SCSIDiskState, qdev.port_wwn, 0),
     DEFINE_PROP_UINT16("port_index", SCSIDiskState, port_index, 0),
-- 
2.49.0



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH v3 0/2] scsi-disk: Add FUA write support
  2025-05-02 12:11 [PATCH v3 0/2] scsi-disk: Add FUA write support Alberto Faria
  2025-05-02 12:11 ` [PATCH v3 1/2] scsi-disk: Add native " Alberto Faria
  2025-05-02 12:11 ` [PATCH v3 2/2] scsi-disk: Advertise FUA support by default Alberto Faria
@ 2025-05-13 12:45 ` Kevin Wolf
  2 siblings, 0 replies; 4+ messages in thread
From: Kevin Wolf @ 2025-05-13 12:45 UTC (permalink / raw)
  To: Alberto Faria
  Cc: qemu-devel, Yanan Wang, Paolo Bonzini,
	Philippe Mathieu-Daudé, Zhao Liu, Marcel Apfelbaum,
	Eduardo Habkost, Fam Zheng, qemu-block

Am 02.05.2025 um 14:11 hat Alberto Faria geschrieben:
> Add scsi-disk support for Force Unit Access (FUA) writes. The first patch lets
> us avoid FUA emulation when the underlying driver supports it natively. The
> second patch makes scsi-disk devices advertise FUA support by default.
> 
> v3:
> - Restore flush on VERIFY.
> - Modify hw_compat_10_0 instead of hw_compat_9_2.
> 
> v2:
> - Drop FUA write emulation logic since the block layer already does that.
> - Add machine type compat for "dpofua".
> 
> Alberto Faria (2):
>   scsi-disk: Add native FUA write support
>   scsi-disk: Advertise FUA support by default

Thanks, applied to the block branch.

Kevin



^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2025-05-13 12:46 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-05-02 12:11 [PATCH v3 0/2] scsi-disk: Add FUA write support Alberto Faria
2025-05-02 12:11 ` [PATCH v3 1/2] scsi-disk: Add native " Alberto Faria
2025-05-02 12:11 ` [PATCH v3 2/2] scsi-disk: Advertise FUA support by default Alberto Faria
2025-05-13 12:45 ` [PATCH v3 0/2] scsi-disk: Add FUA write support Kevin Wolf

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.