]> git.proxmox.com Git - pve-qemu.git/blame - debian/patches/extra/0013-virtio-blk-avoid-using-ioeventfd-state-in-irqfd-cond.patch
add patch to fix deadlock with VirtIO block and iothread during QMP stop
[pve-qemu.git] / debian / patches / extra / 0013-virtio-blk-avoid-using-ioeventfd-state-in-irqfd-cond.patch
CommitLineData
ed159bc3
FE
1From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2From: Stefan Hajnoczi <stefanha@redhat.com>
3Date: Mon, 22 Jan 2024 12:26:25 -0500
4Subject: [PATCH] virtio-blk: avoid using ioeventfd state in irqfd conditional
5
6Requests that complete in an IOThread use irqfd to notify the guest
7while requests that complete in the main loop thread use the traditional
8qdev irq code path. The reason for this conditional is that the irq code
9path requires the BQL:
10
11 if (s->ioeventfd_started && !s->ioeventfd_disabled) {
12 virtio_notify_irqfd(vdev, req->vq);
13 } else {
14 virtio_notify(vdev, req->vq);
15 }
16
17There is a corner case where the conditional invokes the irq code path
18instead of the irqfd code path:
19
20 static void virtio_blk_stop_ioeventfd(VirtIODevice *vdev)
21 {
22 ...
23 /*
24 * Set ->ioeventfd_started to false before draining so that host notifiers
25 * are not detached/attached anymore.
26 */
27 s->ioeventfd_started = false;
28
29 /* Wait for virtio_blk_dma_restart_bh() and in flight I/O to complete */
30 blk_drain(s->conf.conf.blk);
31
32During blk_drain() the conditional produces the wrong result because
33ioeventfd_started is false.
34
35Use qemu_in_iothread() instead of checking the ioeventfd state.
36
37Cc: qemu-stable@nongnu.org
38Buglink: https://issues.redhat.com/browse/RHEL-15394
39Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
40Message-ID: <20240122172625.415386-1-stefanha@redhat.com>
41Reviewed-by: Kevin Wolf <kwolf@redhat.com>
42Signed-off-by: Kevin Wolf <kwolf@redhat.com>
43[FE: backport: dataplane -> ioeventfd rework didn't happen yet]
44Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
45---
46 hw/block/virtio-blk.c | 2 +-
47 1 file changed, 1 insertion(+), 1 deletion(-)
48
49diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
50index 39e7f23fab..61bd1f6859 100644
51--- a/hw/block/virtio-blk.c
52+++ b/hw/block/virtio-blk.c
53@@ -64,7 +64,7 @@ static void virtio_blk_req_complete(VirtIOBlockReq *req, unsigned char status)
54 iov_discard_undo(&req->inhdr_undo);
55 iov_discard_undo(&req->outhdr_undo);
56 virtqueue_push(req->vq, &req->elem, req->in_len);
57- if (s->dataplane_started && !s->dataplane_disabled) {
58+ if (qemu_in_iothread()) {
59 virtio_blk_data_plane_notify(s->dataplane, req->vq);
60 } else {
61 virtio_notify(vdev, req->vq);