1
The following changes since commit a0def594286d9110a6035e02eef558cf3cf5d847:
1
The following changes since commit 887cba855bb6ff4775256f7968409281350b568c:
2
2
3
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging (2017-01-30 10:23:20 +0000)
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
git://github.com/stefanha/qemu.git block-pull-request
7
https://gitlab.com/stefanha/qemu.git tags/block-pull-request
8
8
9
for you to fetch changes up to 81a9f2cb9336a7e9f50b0729b4c81d287e0015e9:
9
for you to fetch changes up to 75dcb4d790bbe5327169fd72b185960ca58e2fa6:
10
10
11
iothread: enable AioContext polling by default (2017-01-31 17:09:34 +0000)
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
15
15
----------------------------------------------------------------
16
----------------------------------------------------------------
16
17
17
Stefan Hajnoczi (1):
18
Stefan Hajnoczi (1):
18
iothread: enable AioContext polling by default
19
virtio-blk: fix host notifier issues during dataplane start/stop
19
20
20
iothread.c | 14 ++++++++++++++
21
hw/block/dataplane/virtio-blk.c | 67 +++++++++++++++++++--------------
21
1 file changed, 14 insertions(+)
22
1 file changed, 38 insertions(+), 29 deletions(-)
22
23
23
--
24
--
24
2.9.3
25
2.40.1
25
26
diff view generated by jsdifflib
1
IOThread AioContexts are likely to consist only of event sources like
1
The main loop thread can consume 100% CPU when using --device
2
virtqueue ioeventfds and LinuxAIO completion eventfds that are pollable
2
virtio-blk-pci,iothread=<iothread>. ppoll() constantly returns but
3
from userspace (without system calls).
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.
4
6
5
We recently merged the AioContext polling feature but didn't enable it
7
The problem is that the dataplane start/stop code involves drain
6
by default yet. I have gone back over the performance data on the
8
operations, which call virtio_blk_drained_begin() and
7
mailing list and picked a default polling value that gave good results.
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.
8
17
9
Let's enable AioContext polling by default so users don't have another
18
I would like to simplify ->ioeventfd_start/stop() to avoid interactions
10
switch they need to set manually. If performance regressions are found
19
with drain entirely, but couldn't find a way to do that. Instead, this
11
we can still disable this for the QEMU 2.9 release.
20
patch accepts the fragile nature of the code and reorders it so that
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.
12
27
13
Cc: Paolo Bonzini <pbonzini@redhat.com>
28
This patch fixes the 100% CPU consumption in the main loop thread and
14
Cc: Christian Borntraeger <borntraeger@de.ibm.com>
29
correctly moves host notifier processing to the IOThread.
15
Cc: Karl Rister <krister@redhat.com>
30
31
Fixes: 1665d9326fd2 ("virtio-blk: implement BlockDevOps->drained_begin()")
32
Reported-by: Lukáš Doktor <ldoktor@redhat.com>
16
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
33
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
17
Message-id: 20170126170119.27876-1-stefanha@redhat.com
34
Tested-by: Lukas Doktor <ldoktor@redhat.com>
35
Message-id: 20230704151527.193586-1-stefanha@redhat.com
18
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
36
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
19
---
37
---
20
iothread.c | 14 ++++++++++++++
38
hw/block/dataplane/virtio-blk.c | 67 +++++++++++++++++++--------------
21
1 file changed, 14 insertions(+)
39
1 file changed, 38 insertions(+), 29 deletions(-)
22
40
23
diff --git a/iothread.c b/iothread.c
41
diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c
24
index XXXXXXX..XXXXXXX 100644
42
index XXXXXXX..XXXXXXX 100644
25
--- a/iothread.c
43
--- a/hw/block/dataplane/virtio-blk.c
26
+++ b/iothread.c
44
+++ b/hw/block/dataplane/virtio-blk.c
27
@@ -XXX,XX +XXX,XX @@ typedef ObjectClass IOThreadClass;
45
@@ -XXX,XX +XXX,XX @@ int virtio_blk_data_plane_start(VirtIODevice *vdev)
28
#define IOTHREAD_CLASS(klass) \
46
29
OBJECT_CLASS_CHECK(IOThreadClass, klass, TYPE_IOTHREAD)
47
memory_region_transaction_commit();
30
48
31
+/* Benchmark results from 2016 on NVMe SSD drives show max polling times around
49
- /*
32
+ * 16-32 microseconds yield IOPS improvements for both iodepth=1 and iodepth=32
50
- * These fields are visible to the IOThread so we rely on implicit barriers
33
+ * workloads.
51
- * in aio_context_acquire() on the write side and aio_notify_accept() on
34
+ */
52
- * the read side.
35
+#define IOTHREAD_POLL_MAX_NS_DEFAULT 32768ULL
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));
61
}
62
63
+ /*
64
+ * These fields must be visible to the IOThread when it processes the
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.
70
+ */
71
+ s->starting = false;
72
+ vblk->dataplane_started = true;
73
+ smp_wmb(); /* paired with aio_notify_accept() on the read side */
36
+
74
+
37
static __thread IOThread *my_iothread;
75
/* Get this show started by hooking up our callbacks */
38
76
if (!blk_in_drain(s->conf->conf.blk)) {
39
AioContext *qemu_get_current_aio_context(void)
77
aio_context_acquire(s->ctx);
40
@@ -XXX,XX +XXX,XX @@ static int iothread_stop(Object *object, void *opaque)
78
@@ -XXX,XX +XXX,XX @@ int virtio_blk_data_plane_start(VirtIODevice *vdev)
41
return 0;
79
fail_guest_notifiers:
80
vblk->dataplane_disabled = true;
81
s->starting = false;
82
- vblk->dataplane_started = true;
83
return -ENOSYS;
42
}
84
}
43
85
44
+static void iothread_instance_init(Object *obj)
86
@@ -XXX,XX +XXX,XX @@ void virtio_blk_data_plane_stop(VirtIODevice *vdev)
45
+{
87
aio_wait_bh_oneshot(s->ctx, virtio_blk_data_plane_stop_bh, s);
46
+ IOThread *iothread = IOTHREAD(obj);
88
}
89
90
+ /*
91
+ * Batch all the host notifiers in a single transaction to avoid
92
+ * quadratic time complexity in address_space_update_ioeventfds().
93
+ */
94
+ memory_region_transaction_begin();
47
+
95
+
48
+ iothread->poll_max_ns = IOTHREAD_POLL_MAX_NS_DEFAULT;
96
+ for (i = 0; i < nvqs; i++) {
49
+}
97
+ virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), i, false);
98
+ }
50
+
99
+
51
static void iothread_instance_finalize(Object *obj)
100
+ /*
52
{
101
+ * The transaction expects the ioeventfds to be open when it
53
IOThread *iothread = IOTHREAD(obj);
102
+ * commits. Do it now, before the cleanup loop.
54
@@ -XXX,XX +XXX,XX @@ static const TypeInfo iothread_info = {
103
+ */
55
.parent = TYPE_OBJECT,
104
+ memory_region_transaction_commit();
56
.class_init = iothread_class_init,
105
+
57
.instance_size = sizeof(IOThread),
106
+ for (i = 0; i < nvqs; i++) {
58
+ .instance_init = iothread_instance_init,
107
+ virtio_bus_cleanup_host_notifier(VIRTIO_BUS(qbus), i);
59
.instance_finalize = iothread_instance_finalize,
108
+ }
60
.interfaces = (InterfaceInfo[]) {
109
+
61
{TYPE_USER_CREATABLE},
110
+ /*
111
+ * Set ->dataplane_started to false before draining so that host notifiers
112
+ * are not detached/attached anymore.
113
+ */
114
+ vblk->dataplane_started = false;
115
+
116
aio_context_acquire(s->ctx);
117
118
/* Wait for virtio_blk_dma_restart_bh() and in flight I/O to complete */
119
@@ -XXX,XX +XXX,XX @@ void virtio_blk_data_plane_stop(VirtIODevice *vdev)
120
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
}
62
--
152
--
63
2.9.3
153
2.40.1
64
154
65
155
diff view generated by jsdifflib