qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Kevin Wolf <kwolf@redhat.com>
To: qemu-block@nongnu.org
Cc: kwolf@redhat.com, qemu-devel@nongnu.org
Subject: [PULL 11/14] virtio-blk: restart s->rq reqs in vq AioContexts
Date: Fri, 19 Jan 2024 19:13:24 +0100	[thread overview]
Message-ID: <20240119181327.236745-12-kwolf@redhat.com> (raw)
In-Reply-To: <20240119181327.236745-1-kwolf@redhat.com>

From: Stefan Hajnoczi <stefanha@redhat.com>

A virtio-blk device with the iothread-vq-mapping parameter has
per-virtqueue AioContexts. It is not thread-safe to process s->rq
requests in the BlockBackend AioContext since that may be different from
the virtqueue's AioContext to which this request belongs. The code
currently races and could crash.

Adapt virtio_blk_dma_restart_cb() to first split s->rq into per-vq lists
and then schedule a BH each vq's AioContext as necessary. This way
requests are safely processed in their vq's AioContext.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-ID: <20240119135748.270944-5-stefanha@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 hw/block/virtio-blk.c | 44 ++++++++++++++++++++++++++++++++-----------
 1 file changed, 33 insertions(+), 11 deletions(-)

diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index e342cb2cfb..4525988d92 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -1156,16 +1156,11 @@ static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq)
 
 static void virtio_blk_dma_restart_bh(void *opaque)
 {
-    VirtIOBlock *s = opaque;
+    VirtIOBlockReq *req = opaque;
+    VirtIOBlock *s = req->dev; /* we're called with at least one request */
 
-    VirtIOBlockReq *req;
     MultiReqBuffer mrb = {};
 
-    WITH_QEMU_LOCK_GUARD(&s->rq_lock) {
-        req = s->rq;
-        s->rq = NULL;
-    }
-
     while (req) {
         VirtIOBlockReq *next = req->next;
         if (virtio_blk_handle_request(req, &mrb)) {
@@ -1195,16 +1190,43 @@ static void virtio_blk_dma_restart_cb(void *opaque, bool running,
                                       RunState state)
 {
     VirtIOBlock *s = opaque;
+    uint16_t num_queues = s->conf.num_queues;
 
     if (!running) {
         return;
     }
 
-    /* Paired with dec in virtio_blk_dma_restart_bh() */
-    blk_inc_in_flight(s->conf.conf.blk);
+    /* Split the device-wide s->rq request list into per-vq request lists */
+    g_autofree VirtIOBlockReq **vq_rq = g_new0(VirtIOBlockReq *, num_queues);
+    VirtIOBlockReq *rq;
+
+    WITH_QEMU_LOCK_GUARD(&s->rq_lock) {
+        rq = s->rq;
+        s->rq = NULL;
+    }
+
+    while (rq) {
+        VirtIOBlockReq *next = rq->next;
+        uint16_t idx = virtio_get_queue_index(rq->vq);
+
+        rq->next = vq_rq[idx];
+        vq_rq[idx] = rq;
+        rq = next;
+    }
 
-    aio_bh_schedule_oneshot(blk_get_aio_context(s->conf.conf.blk),
-            virtio_blk_dma_restart_bh, s);
+    /* Schedule a BH to submit the requests in each vq's AioContext */
+    for (uint16_t i = 0; i < num_queues; i++) {
+        if (!vq_rq[i]) {
+            continue;
+        }
+
+        /* Paired with dec in virtio_blk_dma_restart_bh() */
+        blk_inc_in_flight(s->conf.conf.blk);
+
+        aio_bh_schedule_oneshot(s->vq_aio_context[i],
+                                virtio_blk_dma_restart_bh,
+                                vq_rq[i]);
+    }
 }
 
 static void virtio_blk_reset(VirtIODevice *vdev)
-- 
2.43.0



  parent reply	other threads:[~2024-01-19 18:15 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-01-19 18:13 [PULL 00/14] Block layer patches Kevin Wolf
2024-01-19 18:13 ` [PULL 01/14] block/blklogwrites: Fix a bug when logging "write zeroes" operations Kevin Wolf
2024-01-19 18:13 ` [PULL 02/14] string-output-visitor: Fix (pseudo) struct handling Kevin Wolf
2024-01-19 18:13 ` [PULL 03/14] commit: Allow users to request only format driver names in backing file format Kevin Wolf
2024-01-19 18:13 ` [PULL 04/14] stream: " Kevin Wolf
2024-01-19 18:13 ` [PULL 05/14] iotests: add filter_qmp_generated_node_ids() Kevin Wolf
2024-01-19 18:13 ` [PULL 06/14] iotests: port 141 to Python for reliable QMP testing Kevin Wolf
2024-01-19 18:13 ` [PULL 07/14] monitor: only run coroutine commands in qemu_aio_context Kevin Wolf
2024-01-19 18:13 ` [PULL 08/14] virtio-blk: move dataplane code into virtio-blk.c Kevin Wolf
2024-01-19 18:13 ` [PULL 09/14] virtio-blk: rename dataplane create/destroy functions Kevin Wolf
2024-01-19 18:13 ` [PULL 10/14] virtio-blk: rename dataplane to ioeventfd Kevin Wolf
2024-01-19 18:13 ` Kevin Wolf [this message]
2024-01-19 18:13 ` [PULL 12/14] virtio-blk: tolerate failure to set BlockBackend AioContext Kevin Wolf
2024-01-19 18:13 ` [PULL 13/14] virtio-blk: always set ioeventfd during startup Kevin Wolf
2024-01-19 18:13 ` [PULL 14/14] block/blklogwrites: Protect mutable driver state with a mutex Kevin Wolf
2024-01-20 17:21 ` [PULL 00/14] Block layer patches Peter Maydell
2024-01-22 11:14   ` Kevin Wolf
2024-01-22 11:44     ` Peter Maydell

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=20240119181327.236745-12-kwolf@redhat.com \
    --to=kwolf@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    /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).