1
The following changes since commit 560009f2c8b57b7cdd31a5693ea86ab369382f49:
1
The following changes since commit 887cba855bb6ff4775256f7968409281350b568c:
2
2
3
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging (2019-10-07 15:40:53 +0100)
3
configure: Fix cross-building for RISCV host (v5) (2023-07-11 17:56:09 +0100)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
https://github.com/stefanha/qemu.git tags/block-pull-request
7
https://gitlab.com/stefanha/qemu.git tags/block-pull-request
8
8
9
for you to fetch changes up to 4d804b5305ffb4d5fa414c38d4f1bdfb987c8d0b:
9
for you to fetch changes up to 75dcb4d790bbe5327169fd72b185960ca58e2fa6:
10
10
11
iotests/262: Switch source/dest VM launch order (2019-10-08 14:28:25 +0100)
11
virtio-blk: fix host notifier issues during dataplane start/stop (2023-07-12 15:20:32 -0400)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Pull request
14
Pull request
15
15
16
This pull request also contains the two commits from the previous pull request
17
that was dropped due to a mingw compilation error. The compilation should now
18
be fixed.
19
20
----------------------------------------------------------------
16
----------------------------------------------------------------
21
17
22
Max Reitz (2):
18
Stefan Hajnoczi (1):
23
block: Skip COR for inactive nodes
19
virtio-blk: fix host notifier issues during dataplane start/stop
24
iotests/262: Switch source/dest VM launch order
25
20
26
Sergio Lopez (1):
21
hw/block/dataplane/virtio-blk.c | 67 +++++++++++++++++++--------------
27
virtio-blk: schedule virtio_notify_config to run on main context
22
1 file changed, 38 insertions(+), 29 deletions(-)
28
29
Vladimir Sementsov-Ogievskiy (1):
30
util/ioc.c: try to reassure Coverity about qemu_iovec_init_extended
31
32
block/io.c | 41 +++++++++++++++++++++++++-------------
33
hw/block/virtio-blk.c | 16 ++++++++++++++-
34
util/iov.c | 5 +++--
35
tests/qemu-iotests/262 | 12 +++++------
36
tests/qemu-iotests/262.out | 6 +++---
37
5 files changed, 54 insertions(+), 26 deletions(-)
38
23
39
--
24
--
40
2.21.0
25
2.40.1
41
42
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
Make it more obvious, that filling qiov corresponds to qiov allocation,
4
which in turn corresponds to total_niov calculation, based on mid_niov
5
(not mid_len). Still add an assertion to show that there should be no
6
difference.
7
8
[Added mingw "error: 'mid_iov' may be used uninitialized in this
9
function" compiler error fix suggested by Vladimir.
10
--Stefan]
11
12
Reported-by: Coverity (CID 1405302)
13
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
14
Message-id: 20190910090310.14032-1-vsementsov@virtuozzo.com
15
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
17
Message-Id: <20190910090310.14032-1-vsementsov@virtuozzo.com>
18
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
19
20
fixup! util/ioc.c: try to reassure Coverity about qemu_iovec_init_extended
21
---
22
util/iov.c | 5 +++--
23
1 file changed, 3 insertions(+), 2 deletions(-)
24
25
diff --git a/util/iov.c b/util/iov.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/util/iov.c
28
+++ b/util/iov.c
29
@@ -XXX,XX +XXX,XX @@ void qemu_iovec_init_extended(
30
{
31
size_t mid_head, mid_tail;
32
int total_niov, mid_niov = 0;
33
- struct iovec *p, *mid_iov;
34
+ struct iovec *p, *mid_iov = NULL;
35
36
if (mid_len) {
37
mid_iov = qiov_slice(mid_qiov, mid_offset, mid_len,
38
@@ -XXX,XX +XXX,XX @@ void qemu_iovec_init_extended(
39
p++;
40
}
41
42
- if (mid_len) {
43
+ assert(!mid_niov == !mid_len);
44
+ if (mid_niov) {
45
memcpy(p, mid_iov, mid_niov * sizeof(*p));
46
p[0].iov_base = (uint8_t *)p[0].iov_base + mid_head;
47
p[0].iov_len -= mid_head;
48
--
49
2.21.0
50
51
diff view generated by jsdifflib
Deleted patch
1
From: Sergio Lopez <slp@redhat.com>
2
1
3
virtio_notify_config() needs to acquire the global mutex, which isn't
4
allowed from an iothread, and may lead to a deadlock like this:
5
6
- main thead
7
* Has acquired: qemu_global_mutex.
8
* Is trying the acquire: iothread AioContext lock via
9
AIO_WAIT_WHILE (after aio_poll).
10
11
- iothread
12
* Has acquired: AioContext lock.
13
* Is trying to acquire: qemu_global_mutex (via
14
virtio_notify_config->prepare_mmio_access).
15
16
If virtio_blk_resize() is called from an iothread, schedule
17
virtio_notify_config() to be run in the main context BH.
18
19
[Removed unnecessary newline as suggested by Kevin Wolf
20
<kwolf@redhat.com>.
21
--Stefan]
22
23
Signed-off-by: Sergio Lopez <slp@redhat.com>
24
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
25
Message-id: 20190916112411.21636-1-slp@redhat.com
26
Message-Id: <20190916112411.21636-1-slp@redhat.com>
27
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
28
---
29
hw/block/virtio-blk.c | 16 +++++++++++++++-
30
1 file changed, 15 insertions(+), 1 deletion(-)
31
32
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/hw/block/virtio-blk.c
35
+++ b/hw/block/virtio-blk.c
36
@@ -XXX,XX +XXX,XX @@
37
#include "qemu/iov.h"
38
#include "qemu/module.h"
39
#include "qemu/error-report.h"
40
+#include "qemu/main-loop.h"
41
#include "trace.h"
42
#include "hw/block/block.h"
43
#include "hw/qdev-properties.h"
44
@@ -XXX,XX +XXX,XX @@ static int virtio_blk_load_device(VirtIODevice *vdev, QEMUFile *f,
45
return 0;
46
}
47
48
+static void virtio_resize_cb(void *opaque)
49
+{
50
+ VirtIODevice *vdev = opaque;
51
+
52
+ assert(qemu_get_current_aio_context() == qemu_get_aio_context());
53
+ virtio_notify_config(vdev);
54
+}
55
+
56
static void virtio_blk_resize(void *opaque)
57
{
58
VirtIODevice *vdev = VIRTIO_DEVICE(opaque);
59
60
- virtio_notify_config(vdev);
61
+ /*
62
+ * virtio_notify_config() needs to acquire the global mutex,
63
+ * so it can't be called from an iothread. Instead, schedule
64
+ * it to be run in the main context BH.
65
+ */
66
+ aio_bh_schedule_oneshot(qemu_get_aio_context(), virtio_resize_cb, vdev);
67
}
68
69
static const BlockDevOps virtio_block_ops = {
70
--
71
2.21.0
72
73
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
The main loop thread can consume 100% CPU when using --device
2
virtio-blk-pci,iothread=<iothread>. ppoll() constantly returns but
3
reading virtqueue host notifiers fails with EAGAIN. The file descriptors
4
are stale and remain registered with the AioContext because of bugs in
5
the virtio-blk dataplane start/stop code.
2
6
3
We must not write data to inactive nodes, and a COR is certainly
7
The problem is that the dataplane start/stop code involves drain
4
something we can simply not do without upsetting anyone. So skip COR
8
operations, which call virtio_blk_drained_begin() and
5
operations on inactive nodes.
9
virtio_blk_drained_end() at points where the host notifier is not
10
operational:
11
- In virtio_blk_data_plane_start(), blk_set_aio_context() drains after
12
vblk->dataplane_started has been set to true but the host notifier has
13
not been attached yet.
14
- In virtio_blk_data_plane_stop(), blk_drain() and blk_set_aio_context()
15
drain after the host notifier has already been detached but with
16
vblk->dataplane_started still set to true.
6
17
7
Signed-off-by: Max Reitz <mreitz@redhat.com>
18
I would like to simplify ->ioeventfd_start/stop() to avoid interactions
8
Reviewed-by: Eric Blake <eblake@redhat.com>
19
with drain entirely, but couldn't find a way to do that. Instead, this
9
Message-id: 20191001174827.11081-2-mreitz@redhat.com
20
patch accepts the fragile nature of the code and reorders it so that
10
Message-Id: <20191001174827.11081-2-mreitz@redhat.com>
21
vblk->dataplane_started is false during drain operations. This way the
22
virtio_blk_drained_begin() and virtio_blk_drained_end() calls don't
23
touch the host notifier. The result is that
24
virtio_blk_data_plane_start() and virtio_blk_data_plane_stop() have
25
complete control over the host notifier and stale file descriptors are
26
no longer left in the AioContext.
27
28
This patch fixes the 100% CPU consumption in the main loop thread and
29
correctly moves host notifier processing to the IOThread.
30
31
Fixes: 1665d9326fd2 ("virtio-blk: implement BlockDevOps->drained_begin()")
32
Reported-by: Lukáš Doktor <ldoktor@redhat.com>
33
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
34
Tested-by: Lukas Doktor <ldoktor@redhat.com>
35
Message-id: 20230704151527.193586-1-stefanha@redhat.com
11
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
36
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
12
---
37
---
13
block/io.c | 41 +++++++++++++++++++++++++++--------------
38
hw/block/dataplane/virtio-blk.c | 67 +++++++++++++++++++--------------
14
1 file changed, 27 insertions(+), 14 deletions(-)
39
1 file changed, 38 insertions(+), 29 deletions(-)
15
40
16
diff --git a/block/io.c b/block/io.c
41
diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c
17
index XXXXXXX..XXXXXXX 100644
42
index XXXXXXX..XXXXXXX 100644
18
--- a/block/io.c
43
--- a/hw/block/dataplane/virtio-blk.c
19
+++ b/block/io.c
44
+++ b/hw/block/dataplane/virtio-blk.c
20
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child,
45
@@ -XXX,XX +XXX,XX @@ int virtio_blk_data_plane_start(VirtIODevice *vdev)
21
int max_transfer = MIN_NON_ZERO(bs->bl.max_transfer,
46
22
BDRV_REQUEST_MAX_BYTES);
47
memory_region_transaction_commit();
23
unsigned int progress = 0;
48
24
+ bool skip_write;
49
- /*
25
50
- * These fields are visible to the IOThread so we rely on implicit barriers
26
if (!drv) {
51
- * in aio_context_acquire() on the write side and aio_notify_accept() on
27
return -ENOMEDIUM;
52
- * the read side.
53
- */
54
- s->starting = false;
55
- vblk->dataplane_started = true;
56
trace_virtio_blk_data_plane_start(s);
57
58
old_context = blk_get_aio_context(s->conf->conf.blk);
59
@@ -XXX,XX +XXX,XX @@ int virtio_blk_data_plane_start(VirtIODevice *vdev)
60
event_notifier_set(virtio_queue_get_host_notifier(vq));
28
}
61
}
29
62
30
+ /*
63
+ /*
31
+ * Do not write anything when the BDS is inactive. That is not
64
+ * These fields must be visible to the IOThread when it processes the
32
+ * allowed, and it would not help.
65
+ * virtqueue, otherwise it will think dataplane has not started yet.
66
+ *
67
+ * Make sure ->dataplane_started is false when blk_set_aio_context() is
68
+ * called above so that draining does not cause the host notifier to be
69
+ * detached/attached prematurely.
33
+ */
70
+ */
34
+ skip_write = (bs->open_flags & BDRV_O_INACTIVE);
71
+ s->starting = false;
72
+ vblk->dataplane_started = true;
73
+ smp_wmb(); /* paired with aio_notify_accept() on the read side */
35
+
74
+
36
/* FIXME We cannot require callers to have write permissions when all they
75
/* Get this show started by hooking up our callbacks */
37
* are doing is a read request. If we did things right, write permissions
76
if (!blk_in_drain(s->conf->conf.blk)) {
38
* would be obtained anyway, but internally by the copy-on-read code. As
77
aio_context_acquire(s->ctx);
39
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child,
78
@@ -XXX,XX +XXX,XX @@ int virtio_blk_data_plane_start(VirtIODevice *vdev)
40
while (cluster_bytes) {
79
fail_guest_notifiers:
41
int64_t pnum;
80
vblk->dataplane_disabled = true;
42
81
s->starting = false;
43
- ret = bdrv_is_allocated(bs, cluster_offset,
82
- vblk->dataplane_started = true;
44
- MIN(cluster_bytes, max_transfer), &pnum);
83
return -ENOSYS;
45
- if (ret < 0) {
84
}
46
- /* Safe to treat errors in querying allocation as if
85
47
- * unallocated; we'll probably fail again soon on the
86
@@ -XXX,XX +XXX,XX @@ void virtio_blk_data_plane_stop(VirtIODevice *vdev)
48
- * read, but at least that will set a decent errno.
87
aio_wait_bh_oneshot(s->ctx, virtio_blk_data_plane_stop_bh, s);
49
- */
88
}
50
+ if (skip_write) {
89
51
+ ret = 1; /* "already allocated", so nothing will be copied */
90
+ /*
52
pnum = MIN(cluster_bytes, max_transfer);
91
+ * Batch all the host notifiers in a single transaction to avoid
53
- }
92
+ * quadratic time complexity in address_space_update_ioeventfds().
54
+ } else {
93
+ */
55
+ ret = bdrv_is_allocated(bs, cluster_offset,
94
+ memory_region_transaction_begin();
56
+ MIN(cluster_bytes, max_transfer), &pnum);
95
+
57
+ if (ret < 0) {
96
+ for (i = 0; i < nvqs; i++) {
58
+ /*
97
+ virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), i, false);
59
+ * Safe to treat errors in querying allocation as if
98
+ }
60
+ * unallocated; we'll probably fail again soon on the
99
+
61
+ * read, but at least that will set a decent errno.
100
+ /*
62
+ */
101
+ * The transaction expects the ioeventfds to be open when it
63
+ pnum = MIN(cluster_bytes, max_transfer);
102
+ * commits. Do it now, before the cleanup loop.
64
+ }
103
+ */
65
104
+ memory_region_transaction_commit();
66
- /* Stop at EOF if the image ends in the middle of the cluster */
105
+
67
- if (ret == 0 && pnum == 0) {
106
+ for (i = 0; i < nvqs; i++) {
68
- assert(progress >= bytes);
107
+ virtio_bus_cleanup_host_notifier(VIRTIO_BUS(qbus), i);
69
- break;
108
+ }
70
- }
109
+
71
+ /* Stop at EOF if the image ends in the middle of the cluster */
110
+ /*
72
+ if (ret == 0 && pnum == 0) {
111
+ * Set ->dataplane_started to false before draining so that host notifiers
73
+ assert(progress >= bytes);
112
+ * are not detached/attached anymore.
74
+ break;
113
+ */
75
+ }
114
+ vblk->dataplane_started = false;
76
115
+
77
- assert(skip_bytes < pnum);
116
aio_context_acquire(s->ctx);
78
+ assert(skip_bytes < pnum);
117
79
+ }
118
/* Wait for virtio_blk_dma_restart_bh() and in flight I/O to complete */
80
119
@@ -XXX,XX +XXX,XX @@ void virtio_blk_data_plane_stop(VirtIODevice *vdev)
81
if (ret <= 0) {
120
82
QEMUIOVector local_qiov;
121
aio_context_release(s->ctx);
122
123
- /*
124
- * Batch all the host notifiers in a single transaction to avoid
125
- * quadratic time complexity in address_space_update_ioeventfds().
126
- */
127
- memory_region_transaction_begin();
128
-
129
- for (i = 0; i < nvqs; i++) {
130
- virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), i, false);
131
- }
132
-
133
- /*
134
- * The transaction expects the ioeventfds to be open when it
135
- * commits. Do it now, before the cleanup loop.
136
- */
137
- memory_region_transaction_commit();
138
-
139
- for (i = 0; i < nvqs; i++) {
140
- virtio_bus_cleanup_host_notifier(VIRTIO_BUS(qbus), i);
141
- }
142
-
143
qemu_bh_cancel(s->bh);
144
notify_guest_bh(s); /* final chance to notify guest */
145
146
/* Clean up guest notifier (irq) */
147
k->set_guest_notifiers(qbus->parent, nvqs, false);
148
149
- vblk->dataplane_started = false;
150
s->stopping = false;
151
}
83
--
152
--
84
2.21.0
153
2.40.1
85
154
86
155
diff view generated by jsdifflib
Deleted patch
1
From: Max Reitz <mreitz@redhat.com>
2
1
3
Launching the destination VM before the source VM gives us a regression
4
test for HEAD^:
5
6
The guest device causes a read from the disk image through
7
guess_disk_lchs(). This will not work if the first sector (containing
8
the partition table) is yet unallocated, we use COR, and the node is
9
inactive.
10
11
By launching the source VM before the destination, however, the COR
12
filter on the source will allocate that area in the image shared between
13
both VMs, thus the problem will not become apparent.
14
15
Switching the launch order causes the sector to still be unallocated
16
when guess_disk_lchs() runs on the inactive node in the destination VM,
17
and thus we get our test case.
18
19
Signed-off-by: Max Reitz <mreitz@redhat.com>
20
Reviewed-by: Eric Blake <eblake@redhat.com>
21
Message-id: 20191001174827.11081-3-mreitz@redhat.com
22
Message-Id: <20191001174827.11081-3-mreitz@redhat.com>
23
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
24
---
25
tests/qemu-iotests/262 | 12 ++++++------
26
tests/qemu-iotests/262.out | 6 +++---
27
2 files changed, 9 insertions(+), 9 deletions(-)
28
29
diff --git a/tests/qemu-iotests/262 b/tests/qemu-iotests/262
30
index XXXXXXX..XXXXXXX 100755
31
--- a/tests/qemu-iotests/262
32
+++ b/tests/qemu-iotests/262
33
@@ -XXX,XX +XXX,XX @@ with iotests.FilePath('img') as img_path, \
34
35
os.mkfifo(fifo)
36
37
- iotests.log('Launching source VM...')
38
- add_opts(vm_a)
39
- vm_a.launch()
40
-
41
- vm_a.enable_migration_events('A')
42
-
43
iotests.log('Launching destination VM...')
44
add_opts(vm_b)
45
vm_b.add_incoming("exec: cat '%s'" % (fifo))
46
@@ -XXX,XX +XXX,XX @@ with iotests.FilePath('img') as img_path, \
47
48
vm_b.enable_migration_events('B')
49
50
+ iotests.log('Launching source VM...')
51
+ add_opts(vm_a)
52
+ vm_a.launch()
53
+
54
+ vm_a.enable_migration_events('A')
55
+
56
iotests.log('Starting migration to B...')
57
iotests.log(vm_a.qmp('migrate', uri='exec:cat >%s' % (fifo)))
58
with iotests.Timeout(3, 'Migration does not complete'):
59
diff --git a/tests/qemu-iotests/262.out b/tests/qemu-iotests/262.out
60
index XXXXXXX..XXXXXXX 100644
61
--- a/tests/qemu-iotests/262.out
62
+++ b/tests/qemu-iotests/262.out
63
@@ -XXX,XX +XXX,XX @@
64
-Launching source VM...
65
-Enabling migration QMP events on A...
66
-{"return": {}}
67
Launching destination VM...
68
Enabling migration QMP events on B...
69
{"return": {}}
70
+Launching source VM...
71
+Enabling migration QMP events on A...
72
+{"return": {}}
73
Starting migration to B...
74
{"return": {}}
75
{"data": {"status": "setup"}, "event": "MIGRATION", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
76
--
77
2.21.0
78
79
diff view generated by jsdifflib