1
The following changes since commit 508ba0f7e2092d3ca56e3f75e894d52d8b94818e:
1
The following changes since commit 013a18edbbc59cdad019100c7d03c0494642b74c:
2
2
3
Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20171109' into staging (2017-11-13 11:41:47 +0000)
3
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-2020051=
4
4' into staging (2020-05-14 16:17:55 +0100)
4
5
5
are available in the git repository at:
6
are available in the Git repository at:
6
7
7
git://github.com/stefanha/qemu.git tags/block-pull-request
8
https://github.com/stefanha/qemu.git tags/block-pull-request
8
9
9
for you to fetch changes up to 0761562687e0d8135310a94b1d3e08376387c027:
10
for you to fetch changes up to ba607ca8bff4d2c2062902f8355657c865ac7c29:
10
11
11
qemu-iotests: Test I/O limits with removable media (2017-11-13 15:46:26 +0000)
12
aio-posix: disable fdmon-io_uring when GSource is used (2020-05-18 18:16:00=
13
+0100)
12
14
13
----------------------------------------------------------------
15
----------------------------------------------------------------
14
Pull request
16
Pull request
15
17
16
The following disk I/O throttling fixes solve recent bugs.
17
18
----------------------------------------------------------------
18
----------------------------------------------------------------
19
19
20
Alberto Garcia (3):
20
Philippe Mathieu-Daud=C3=A9 (6):
21
block: Check for inserted BlockDriverState in blk_io_limits_disable()
21
tests/fuzz/Makefile: Do not link code using unavailable devices
22
block: Leave valid throttle timers when removing a BDS from a backend
22
Makefile: List fuzz targets in 'make help'
23
qemu-iotests: Test I/O limits with removable media
23
tests/fuzz: Add missing space in test description
24
tests/fuzz: Remove unuseful/unused typedefs
25
tests/fuzz: Extract pciconfig_fuzz_qos() method
26
tests/fuzz: Extract ioport_fuzz_qtest() method
24
27
25
Stefan Hajnoczi (1):
28
Stefan Hajnoczi (2):
26
throttle-groups: drain before detaching ThrottleState
29
aio-posix: don't duplicate fd handler deletion in
30
fdmon_io_uring_destroy()
31
aio-posix: disable fdmon-io_uring when GSource is used
27
32
28
Zhengui (1):
33
Makefile | 6 +++-
29
block: all I/O should be completed before removing throttle timers.
34
tests/qtest/fuzz/Makefile.include | 6 ++--
35
include/block/aio.h | 3 ++
36
tests/qtest/fuzz/i440fx_fuzz.c | 47 ++++++++++++++++++++-----------
37
util/aio-posix.c | 13 +++++++++
38
util/aio-win32.c | 4 +++
39
util/async.c | 1 +
40
util/fdmon-io_uring.c | 13 +++++++--
41
8 files changed, 69 insertions(+), 24 deletions(-)
30
42
31
block/block-backend.c | 36 ++++++++++++++++++---------
43
--=20
32
block/throttle-groups.c | 6 +++++
44
2.25.3
33
tests/qemu-iotests/093 | 62 ++++++++++++++++++++++++++++++++++++++++++++++
34
tests/qemu-iotests/093.out | 4 +--
35
4 files changed, 94 insertions(+), 14 deletions(-)
36
45
37
--
38
2.13.6
39
40
diff view generated by jsdifflib
New patch
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
2
3
Some devices availability depends on CONFIG options.
4
Use these options to only link tests when requested device
5
is available.
6
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20200514143433.18569-2-philmd@redhat.com
9
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
10
---
11
tests/qtest/fuzz/Makefile.include | 6 +++---
12
1 file changed, 3 insertions(+), 3 deletions(-)
13
14
diff --git a/tests/qtest/fuzz/Makefile.include b/tests/qtest/fuzz/Makefile.include
15
index XXXXXXX..XXXXXXX 100644
16
--- a/tests/qtest/fuzz/Makefile.include
17
+++ b/tests/qtest/fuzz/Makefile.include
18
@@ -XXX,XX +XXX,XX @@ fuzz-obj-y += tests/qtest/fuzz/fork_fuzz.o
19
fuzz-obj-y += tests/qtest/fuzz/qos_fuzz.o
20
21
# Targets
22
-fuzz-obj-y += tests/qtest/fuzz/i440fx_fuzz.o
23
-fuzz-obj-y += tests/qtest/fuzz/virtio_net_fuzz.o
24
-fuzz-obj-y += tests/qtest/fuzz/virtio_scsi_fuzz.o
25
+fuzz-obj-$(CONFIG_PCI_I440FX) += tests/qtest/fuzz/i440fx_fuzz.o
26
+fuzz-obj-$(CONFIG_VIRTIO_NET) += tests/qtest/fuzz/virtio_net_fuzz.o
27
+fuzz-obj-$(CONFIG_SCSI) += tests/qtest/fuzz/virtio_scsi_fuzz.o
28
29
FUZZ_CFLAGS += -I$(SRC_PATH)/tests -I$(SRC_PATH)/tests/qtest
30
31
--
32
2.25.3
33
diff view generated by jsdifflib
New patch
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
2
3
List softmmu fuzz targets in 'make help' output:
4
5
$ make help
6
...
7
Architecture specific targets:
8
aarch64-softmmu/all - Build for aarch64-softmmu
9
aarch64-softmmu/fuzz - Build fuzzer for aarch64-softmmu
10
alpha-softmmu/all - Build for alpha-softmmu
11
alpha-softmmu/fuzz - Build fuzzer for alpha-softmmu
12
arm-softmmu/all - Build for arm-softmmu
13
arm-softmmu/fuzz - Build fuzzer for arm-softmmu
14
...
15
16
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
17
Message-id: 20200514143433.18569-3-philmd@redhat.com
18
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
19
---
20
Makefile | 6 +++++-
21
1 file changed, 5 insertions(+), 1 deletion(-)
22
23
diff --git a/Makefile b/Makefile
24
index XXXXXXX..XXXXXXX 100644
25
--- a/Makefile
26
+++ b/Makefile
27
@@ -XXX,XX +XXX,XX @@ endif
28
    @$(if $(TARGET_DIRS), \
29
        echo 'Architecture specific targets:'; \
30
        $(foreach t, $(TARGET_DIRS), \
31
-        $(call print-help-run,$(t)/all,Build for $(t));) \
32
+        $(call print-help-run,$(t)/all,Build for $(t)); \
33
+        $(if $(CONFIG_FUZZ), \
34
+            $(if $(findstring softmmu,$(t)), \
35
+                $(call print-help-run,$(t)/fuzz,Build fuzzer for $(t)); \
36
+        ))) \
37
        echo '')
38
    @$(if $(TOOLS), \
39
        echo 'Tools targets:'; \
40
--
41
2.25.3
42
diff view generated by jsdifflib
New patch
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
2
3
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
4
Message-id: 20200514143433.18569-4-philmd@redhat.com
5
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
6
---
7
tests/qtest/fuzz/i440fx_fuzz.c | 6 +++---
8
1 file changed, 3 insertions(+), 3 deletions(-)
9
10
diff --git a/tests/qtest/fuzz/i440fx_fuzz.c b/tests/qtest/fuzz/i440fx_fuzz.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/tests/qtest/fuzz/i440fx_fuzz.c
13
+++ b/tests/qtest/fuzz/i440fx_fuzz.c
14
@@ -XXX,XX +XXX,XX @@ static void register_pci_fuzz_targets(void)
15
/* Uses simple qtest commands and reboots to reset state */
16
fuzz_add_target(&(FuzzTarget){
17
.name = "i440fx-qtest-reboot-fuzz",
18
- .description = "Fuzz the i440fx using raw qtest commands and"
19
+ .description = "Fuzz the i440fx using raw qtest commands and "
20
"rebooting after each run",
21
.get_init_cmdline = i440fx_argv,
22
.fuzz = i440fx_fuzz_qtest});
23
@@ -XXX,XX +XXX,XX @@ static void register_pci_fuzz_targets(void)
24
/* Uses libqos and forks to prevent state leakage */
25
fuzz_add_qos_target(&(FuzzTarget){
26
.name = "i440fx-qos-fork-fuzz",
27
- .description = "Fuzz the i440fx using raw qtest commands and"
28
+ .description = "Fuzz the i440fx using raw qtest commands and "
29
"rebooting after each run",
30
.pre_vm_init = &fork_init,
31
.fuzz = i440fx_fuzz_qos_fork,},
32
@@ -XXX,XX +XXX,XX @@ static void register_pci_fuzz_targets(void)
33
*/
34
fuzz_add_qos_target(&(FuzzTarget){
35
.name = "i440fx-qos-noreset-fuzz",
36
- .description = "Fuzz the i440fx using raw qtest commands and"
37
+ .description = "Fuzz the i440fx using raw qtest commands and "
38
"rebooting after each run",
39
.fuzz = i440fx_fuzz_qos,},
40
"i440FX-pcihost",
41
--
42
2.25.3
43
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
If a BlockBackend has I/O limits set then its ThrottleGroupMember
3
These typedefs are not used. Use a simple structure,
4
structure uses the AioContext from its attached BlockDriverState.
4
remote the typedefs.
5
Those two contexts must be kept in sync manually. This is not
6
ideal and will be fixed in the future by removing the throttling
7
configuration from the BlockBackend and storing it in an implicit
8
filter node instead, but for now we have to live with this.
9
5
10
When you remove the BlockDriverState from the backend then the
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
11
throttle timers are destroyed. If a new BlockDriverState is later
7
Message-id: 20200514143433.18569-5-philmd@redhat.com
12
inserted then they are created again using the new AioContext.
13
14
There are a couple of problems with this:
15
16
a) The code manipulates the timers directly, leaving the
17
ThrottleGroupMember.aio_context field in an inconsisent state.
18
19
b) If you remove the I/O limits (e.g by destroying the backend)
20
when the timers are gone then throttle_group_unregister_tgm()
21
will attempt to destroy them again, crashing QEMU.
22
23
While b) could be fixed easily by allowing the timers to be freed
24
twice, this would result in a situation in which we can no longer
25
guarantee that a valid ThrottleState has a valid AioContext and
26
timers.
27
28
This patch ensures that the timers and AioContext are always valid
29
when I/O limits are set, regardless of whether the BlockBackend has a
30
BlockDriverState inserted or not.
31
32
[Fixed "There'a" typo as suggested by Max Reitz <mreitz@redhat.com>
33
--Stefan]
34
35
Reported-by: sochin jiang <sochin.jiang@huawei.com>
36
Signed-off-by: Alberto Garcia <berto@igalia.com>
37
Reviewed-by: Max Reitz <mreitz@redhat.com>
38
Message-id: e089c66e7c20289b046d782cea4373b765c5bc1d.1510339534.git.berto@igalia.com
39
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
8
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
40
---
9
---
41
block/block-backend.c | 16 ++++++++--------
10
tests/qtest/fuzz/i440fx_fuzz.c | 10 ++++------
42
1 file changed, 8 insertions(+), 8 deletions(-)
11
1 file changed, 4 insertions(+), 6 deletions(-)
43
12
44
diff --git a/block/block-backend.c b/block/block-backend.c
13
diff --git a/tests/qtest/fuzz/i440fx_fuzz.c b/tests/qtest/fuzz/i440fx_fuzz.c
45
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
46
--- a/block/block-backend.c
15
--- a/tests/qtest/fuzz/i440fx_fuzz.c
47
+++ b/block/block-backend.c
16
+++ b/tests/qtest/fuzz/i440fx_fuzz.c
48
@@ -XXX,XX +XXX,XX @@ BlockBackend *blk_by_public(BlockBackendPublic *public)
17
@@ -XXX,XX +XXX,XX @@ static void i440fx_fuzz_qtest(QTestState *s,
49
*/
18
* loop over the Data, breaking it up into actions. each action has an
50
void blk_remove_bs(BlockBackend *blk)
19
* opcode, address offset and value
51
{
20
*/
52
+ ThrottleGroupMember *tgm = &blk->public.throttle_group_member;
21
- typedef struct QTestFuzzAction {
53
BlockDriverState *bs;
22
+ struct {
54
- ThrottleTimers *tt;
23
uint8_t opcode;
55
24
uint8_t addr;
56
notifier_list_notify(&blk->remove_bs_notifiers, blk);
25
uint32_t value;
57
- if (blk->public.throttle_group_member.throttle_state) {
26
- } QTestFuzzAction;
58
- tt = &blk->public.throttle_group_member.throttle_timers;
27
- QTestFuzzAction a;
59
+ if (tgm->throttle_state) {
28
+ } a;
60
bs = blk_bs(blk);
29
61
bdrv_drained_begin(bs);
30
while (Size >= sizeof(a)) {
62
- throttle_timers_detach_aio_context(tt);
31
/* make a copy of the action so we can normalize the values in-place */
63
+ throttle_group_detach_aio_context(tgm);
32
@@ -XXX,XX +XXX,XX @@ static void i440fx_fuzz_qos(QTestState *s,
64
+ throttle_group_attach_aio_context(tgm, qemu_get_aio_context());
33
* Same as i440fx_fuzz_qtest, but using QOS. devfn is incorporated into the
65
bdrv_drained_end(bs);
34
* value written over Port IO
35
*/
36
- typedef struct QOSFuzzAction {
37
+ struct {
38
uint8_t opcode;
39
uint8_t offset;
40
int devfn;
41
uint32_t value;
42
- } QOSFuzzAction;
43
+ } a;
44
45
static QPCIBus *bus;
46
if (!bus) {
47
bus = qpci_new_pc(s, fuzz_qos_alloc);
66
}
48
}
67
49
68
@@ -XXX,XX +XXX,XX @@ void blk_remove_bs(BlockBackend *blk)
50
- QOSFuzzAction a;
69
*/
51
while (Size >= sizeof(a)) {
70
int blk_insert_bs(BlockBackend *blk, BlockDriverState *bs, Error **errp)
52
memcpy(&a, Data, sizeof(a));
71
{
53
switch (a.opcode % ACTION_MAX) {
72
+ ThrottleGroupMember *tgm = &blk->public.throttle_group_member;
73
blk->root = bdrv_root_attach_child(bs, "root", &child_root,
74
blk->perm, blk->shared_perm, blk, errp);
75
if (blk->root == NULL) {
76
@@ -XXX,XX +XXX,XX @@ int blk_insert_bs(BlockBackend *blk, BlockDriverState *bs, Error **errp)
77
bdrv_ref(bs);
78
79
notifier_list_notify(&blk->insert_bs_notifiers, blk);
80
- if (blk->public.throttle_group_member.throttle_state) {
81
- throttle_timers_attach_aio_context(
82
- &blk->public.throttle_group_member.throttle_timers,
83
- bdrv_get_aio_context(bs));
84
+ if (tgm->throttle_state) {
85
+ throttle_group_detach_aio_context(tgm);
86
+ throttle_group_attach_aio_context(tgm, bdrv_get_aio_context(bs));
87
}
88
89
return 0;
90
--
54
--
91
2.13.6
55
2.25.3
92
56
93
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
This test hotplugs a CD drive to a VM and checks that I/O limits can
3
Extract the generic pciconfig_fuzz_qos() method from
4
be set only when the drive has media inserted and that they are kept
4
i440fx_fuzz_qos(). This will help to write tests not
5
when the media is replaced.
5
specific to the i440FX controller.
6
6
7
This also tests the removal of a device with valid I/O limits set but
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
no media inserted. This involves deleting and disabling the limits
8
Message-id: 20200514143433.18569-6-philmd@redhat.com
9
of a BlockBackend without BlockDriverState, a scenario that has been
10
crashing until the fixes from the last couple of patches.
11
12
[Python PEP8 fixup: "Don't use spaces are the = sign when used to
13
indicate a keyword argument or a default parameter value"
14
--Stefan]
15
16
Signed-off-by: Alberto Garcia <berto@igalia.com>
17
Reviewed-by: Max Reitz <mreitz@redhat.com>
18
Message-id: 071eb397118ed207c5a7f01d58766e415ee18d6a.1510339534.git.berto@igalia.com
19
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
20
---
10
---
21
tests/qemu-iotests/093 | 62 ++++++++++++++++++++++++++++++++++++++++++++++
11
tests/qtest/fuzz/i440fx_fuzz.c | 20 ++++++++++++++------
22
tests/qemu-iotests/093.out | 4 +--
12
1 file changed, 14 insertions(+), 6 deletions(-)
23
2 files changed, 64 insertions(+), 2 deletions(-)
24
13
25
diff --git a/tests/qemu-iotests/093 b/tests/qemu-iotests/093
14
diff --git a/tests/qtest/fuzz/i440fx_fuzz.c b/tests/qtest/fuzz/i440fx_fuzz.c
26
index XXXXXXX..XXXXXXX 100755
15
index XXXXXXX..XXXXXXX 100644
27
--- a/tests/qemu-iotests/093
16
--- a/tests/qtest/fuzz/i440fx_fuzz.c
28
+++ b/tests/qemu-iotests/093
17
+++ b/tests/qtest/fuzz/i440fx_fuzz.c
29
@@ -XXX,XX +XXX,XX @@ class ThrottleTestGroupNames(iotests.QMPTestCase):
18
@@ -XXX,XX +XXX,XX @@ static void i440fx_fuzz_qtest(QTestState *s,
30
groupname = "group%d" % i
19
flush_events(s);
31
self.verify_name(devname, groupname)
20
}
32
21
33
+class ThrottleTestRemovableMedia(iotests.QMPTestCase):
22
-static void i440fx_fuzz_qos(QTestState *s,
34
+ def setUp(self):
23
+static void pciconfig_fuzz_qos(QTestState *s, QPCIBus *bus,
35
+ self.vm = iotests.VM()
24
const unsigned char *Data, size_t Size) {
36
+ if iotests.qemu_default_machine == 's390-ccw-virtio':
25
/*
37
+ self.vm.add_device("virtio-scsi-ccw,id=virtio-scsi")
26
* Same as i440fx_fuzz_qtest, but using QOS. devfn is incorporated into the
38
+ else:
27
@@ -XXX,XX +XXX,XX @@ static void i440fx_fuzz_qos(QTestState *s,
39
+ self.vm.add_device("virtio-scsi-pci,id=virtio-scsi")
28
uint32_t value;
40
+ self.vm.launch()
29
} a;
30
31
- static QPCIBus *bus;
32
- if (!bus) {
33
- bus = qpci_new_pc(s, fuzz_qos_alloc);
34
- }
35
-
36
while (Size >= sizeof(a)) {
37
memcpy(&a, Data, sizeof(a));
38
switch (a.opcode % ACTION_MAX) {
39
@@ -XXX,XX +XXX,XX @@ static void i440fx_fuzz_qos(QTestState *s,
40
flush_events(s);
41
}
42
43
+static void i440fx_fuzz_qos(QTestState *s,
44
+ const unsigned char *Data,
45
+ size_t Size)
46
+{
47
+ static QPCIBus *bus;
41
+
48
+
42
+ def tearDown(self):
49
+ if (!bus) {
43
+ self.vm.shutdown()
50
+ bus = qpci_new_pc(s, fuzz_qos_alloc);
51
+ }
44
+
52
+
45
+ def test_removable_media(self):
53
+ pciconfig_fuzz_qos(s, bus, Data, Size);
46
+ # Add a couple of dummy nodes named cd0 and cd1
54
+}
47
+ result = self.vm.qmp("blockdev-add", driver="null-aio",
48
+ node_name="cd0")
49
+ self.assert_qmp(result, 'return', {})
50
+ result = self.vm.qmp("blockdev-add", driver="null-aio",
51
+ node_name="cd1")
52
+ self.assert_qmp(result, 'return', {})
53
+
55
+
54
+ # Attach a CD drive with cd0 inserted
56
static void i440fx_fuzz_qos_fork(QTestState *s,
55
+ result = self.vm.qmp("device_add", driver="scsi-cd",
57
const unsigned char *Data, size_t Size) {
56
+ id="dev0", drive="cd0")
58
if (fork() == 0) {
57
+ self.assert_qmp(result, 'return', {})
58
+
59
+ # Set I/O limits
60
+ args = { "id": "dev0", "iops": 100, "iops_rd": 0, "iops_wr": 0,
61
+ "bps": 50, "bps_rd": 0, "bps_wr": 0 }
62
+ result = self.vm.qmp("block_set_io_throttle", conv_keys=False, **args)
63
+ self.assert_qmp(result, 'return', {})
64
+
65
+ # Check that the I/O limits have been set
66
+ result = self.vm.qmp("query-block")
67
+ self.assert_qmp(result, 'return[0]/inserted/iops', 100)
68
+ self.assert_qmp(result, 'return[0]/inserted/bps', 50)
69
+
70
+ # Now eject cd0 and insert cd1
71
+ result = self.vm.qmp("blockdev-open-tray", id='dev0')
72
+ self.assert_qmp(result, 'return', {})
73
+ result = self.vm.qmp("x-blockdev-remove-medium", id='dev0')
74
+ self.assert_qmp(result, 'return', {})
75
+ result = self.vm.qmp("x-blockdev-insert-medium", id='dev0', node_name='cd1')
76
+ self.assert_qmp(result, 'return', {})
77
+
78
+ # Check that the I/O limits are still the same
79
+ result = self.vm.qmp("query-block")
80
+ self.assert_qmp(result, 'return[0]/inserted/iops', 100)
81
+ self.assert_qmp(result, 'return[0]/inserted/bps', 50)
82
+
83
+ # Eject cd1
84
+ result = self.vm.qmp("x-blockdev-remove-medium", id='dev0')
85
+ self.assert_qmp(result, 'return', {})
86
+
87
+ # Check that we can't set limits if the device has no medium
88
+ result = self.vm.qmp("block_set_io_throttle", conv_keys=False, **args)
89
+ self.assert_qmp(result, 'error/class', 'GenericError')
90
+
91
+ # Remove the CD drive
92
+ result = self.vm.qmp("device_del", id='dev0')
93
+ self.assert_qmp(result, 'return', {})
94
+
95
96
if __name__ == '__main__':
97
iotests.main(supported_fmts=["raw"])
98
diff --git a/tests/qemu-iotests/093.out b/tests/qemu-iotests/093.out
99
index XXXXXXX..XXXXXXX 100644
100
--- a/tests/qemu-iotests/093.out
101
+++ b/tests/qemu-iotests/093.out
102
@@ -XXX,XX +XXX,XX @@
103
-.......
104
+........
105
----------------------------------------------------------------------
106
-Ran 7 tests
107
+Ran 8 tests
108
109
OK
110
--
59
--
111
2.13.6
60
2.25.3
112
61
113
diff view generated by jsdifflib
1
From: Zhengui <lizhengui@huawei.com>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
In blk_remove_bs, all I/O should be completed before removing throttle
3
Extract generic ioport_fuzz_qtest() method from
4
timers. If there has inflight I/O, removing throttle timers here will
4
i440fx_fuzz_qtest(). This will help to write tests
5
cause the inflight I/O never return.
5
not specific to the i440FX controller.
6
This patch add bdrv_drained_begin before throttle_timers_detach_aio_context
7
to let all I/O completed before removing throttle timers.
8
6
9
[Moved declaration of bs as suggested by Alberto Garcia
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
<berto@igalia.com>.
8
Message-id: 20200514143433.18569-7-philmd@redhat.com
11
--Stefan]
12
13
Signed-off-by: Zhengui <lizhengui@huawei.com>
14
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
15
Reviewed-by: Alberto Garcia <berto@igalia.com>
16
Message-id: 1508564040-120700-1-git-send-email-lizhengui@huawei.com
17
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
18
---
10
---
19
block/block-backend.c | 4 ++++
11
tests/qtest/fuzz/i440fx_fuzz.c | 11 +++++++++--
20
1 file changed, 4 insertions(+)
12
1 file changed, 9 insertions(+), 2 deletions(-)
21
13
22
diff --git a/block/block-backend.c b/block/block-backend.c
14
diff --git a/tests/qtest/fuzz/i440fx_fuzz.c b/tests/qtest/fuzz/i440fx_fuzz.c
23
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
24
--- a/block/block-backend.c
16
--- a/tests/qtest/fuzz/i440fx_fuzz.c
25
+++ b/block/block-backend.c
17
+++ b/tests/qtest/fuzz/i440fx_fuzz.c
26
@@ -XXX,XX +XXX,XX @@ BlockBackend *blk_by_public(BlockBackendPublic *public)
18
@@ -XXX,XX +XXX,XX @@ enum action_id {
27
*/
19
ACTION_MAX
28
void blk_remove_bs(BlockBackend *blk)
20
};
29
{
21
30
+ BlockDriverState *bs;
22
-static void i440fx_fuzz_qtest(QTestState *s,
31
ThrottleTimers *tt;
23
+static void ioport_fuzz_qtest(QTestState *s,
32
24
const unsigned char *Data, size_t Size) {
33
notifier_list_notify(&blk->remove_bs_notifiers, blk);
25
/*
34
if (blk->public.throttle_group_member.throttle_state) {
26
* loop over the Data, breaking it up into actions. each action has an
35
tt = &blk->public.throttle_group_member.throttle_timers;
27
@@ -XXX,XX +XXX,XX @@ static void i440fx_fuzz_qtest(QTestState *s,
36
+ bs = blk_bs(blk);
28
flush_events(s);
37
+ bdrv_drained_begin(bs);
29
}
38
throttle_timers_detach_aio_context(tt);
30
39
+ bdrv_drained_end(bs);
31
+static void i440fx_fuzz_qtest(QTestState *s,
40
}
32
+ const unsigned char *Data,
41
33
+ size_t Size)
42
blk_update_root_state(blk);
34
+{
35
+ ioport_fuzz_qtest(s, Data, Size);
36
+}
37
+
38
static void pciconfig_fuzz_qos(QTestState *s, QPCIBus *bus,
39
const unsigned char *Data, size_t Size) {
40
/*
41
- * Same as i440fx_fuzz_qtest, but using QOS. devfn is incorporated into the
42
+ * Same as ioport_fuzz_qtest, but using QOS. devfn is incorporated into the
43
* value written over Port IO
44
*/
45
struct {
43
--
46
--
44
2.13.6
47
2.25.3
45
48
46
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
The io_uring file descriptor monitoring implementation has an internal
2
list of fd handlers that are pending submission to io_uring.
3
fdmon_io_uring_destroy() deletes all fd handlers on the list.
2
4
3
When you set I/O limits using block_set_io_throttle or the command
5
Don't delete fd handlers directly in fdmon_io_uring_destroy() for two
4
line throttling.* options they are kept in the BlockBackend regardless
6
reasons:
5
of whether a BlockDriverState is attached to the backend or not.
7
1. This duplicates the aio-posix.c AioHandler deletion code and could
8
become outdated if the struct changes.
9
2. Only handlers with the FDMON_IO_URING_REMOVE flag set are safe to
10
remove. If the flag is not set then something still has a pointer to
11
the fd handler. Let aio-posix.c and its user worry about that. In
12
practice this isn't an issue because fdmon_io_uring_destroy() is only
13
called when shutting down so all users have removed their fd
14
handlers, but the next patch will need this!
6
15
7
Therefore when removing the limits using blk_io_limits_disable() we
16
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
8
need to check if there's a BDS before attempting to drain it, else it
17
Tested-by: Oleksandr Natalenko <oleksandr@redhat.com>
9
will crash QEMU. This can be reproduced very easily using HMP:
18
Message-id: 20200511183630.279750-2-stefanha@redhat.com
10
11
(qemu) drive_add 0 if=none,throttling.iops-total=5000
12
(qemu) drive_del none0
13
14
Reported-by: sochin jiang <sochin.jiang@huawei.com>
15
Signed-off-by: Alberto Garcia <berto@igalia.com>
16
Reviewed-by: Max Reitz <mreitz@redhat.com>
17
Message-id: 0d3a67ce8d948bb33e08672564714dcfb76a3d8c.1510339534.git.berto@igalia.com
18
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
19
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
19
---
20
---
20
block/block-backend.c | 14 ++++++++++----
21
util/aio-posix.c | 1 +
21
1 file changed, 10 insertions(+), 4 deletions(-)
22
util/fdmon-io_uring.c | 13 ++++++++++---
23
2 files changed, 11 insertions(+), 3 deletions(-)
22
24
23
diff --git a/block/block-backend.c b/block/block-backend.c
25
diff --git a/util/aio-posix.c b/util/aio-posix.c
24
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
25
--- a/block/block-backend.c
27
--- a/util/aio-posix.c
26
+++ b/block/block-backend.c
28
+++ b/util/aio-posix.c
27
@@ -XXX,XX +XXX,XX @@ void blk_set_io_limits(BlockBackend *blk, ThrottleConfig *cfg)
29
@@ -XXX,XX +XXX,XX @@ void aio_context_destroy(AioContext *ctx)
28
29
void blk_io_limits_disable(BlockBackend *blk)
30
{
30
{
31
- assert(blk->public.throttle_group_member.throttle_state);
31
fdmon_io_uring_destroy(ctx);
32
- bdrv_drained_begin(blk_bs(blk));
32
fdmon_epoll_disable(ctx);
33
- throttle_group_unregister_tgm(&blk->public.throttle_group_member);
33
+ aio_free_deleted_handlers(ctx);
34
- bdrv_drained_end(blk_bs(blk));
35
+ BlockDriverState *bs = blk_bs(blk);
36
+ ThrottleGroupMember *tgm = &blk->public.throttle_group_member;
37
+ assert(tgm->throttle_state);
38
+ if (bs) {
39
+ bdrv_drained_begin(bs);
40
+ }
41
+ throttle_group_unregister_tgm(tgm);
42
+ if (bs) {
43
+ bdrv_drained_end(bs);
44
+ }
45
}
34
}
46
35
47
/* should be called before blk_set_io_limits if a limit is set */
36
void aio_context_set_poll_params(AioContext *ctx, int64_t max_ns,
37
diff --git a/util/fdmon-io_uring.c b/util/fdmon-io_uring.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/util/fdmon-io_uring.c
40
+++ b/util/fdmon-io_uring.c
41
@@ -XXX,XX +XXX,XX @@ void fdmon_io_uring_destroy(AioContext *ctx)
42
43
io_uring_queue_exit(&ctx->fdmon_io_uring);
44
45
- /* No need to submit these anymore, just free them. */
46
+ /* Move handlers due to be removed onto the deleted list */
47
while ((node = QSLIST_FIRST_RCU(&ctx->submit_list))) {
48
+ unsigned flags = atomic_fetch_and(&node->flags,
49
+ ~(FDMON_IO_URING_PENDING |
50
+ FDMON_IO_URING_ADD |
51
+ FDMON_IO_URING_REMOVE));
52
+
53
+ if (flags & FDMON_IO_URING_REMOVE) {
54
+ QLIST_INSERT_HEAD_RCU(&ctx->deleted_aio_handlers, node, node_deleted);
55
+ }
56
+
57
QSLIST_REMOVE_HEAD_RCU(&ctx->submit_list, node_submitted);
58
- QLIST_REMOVE(node, node);
59
- g_free(node);
60
}
61
62
ctx->fdmon_ops = &fdmon_poll_ops;
48
--
63
--
49
2.13.6
64
2.25.3
50
65
51
diff view generated by jsdifflib
1
I/O requests hang after stop/cont commands at least since QEMU 2.10.0
1
The glib event loop does not call fdmon_io_uring_wait() so fd handlers
2
with -drive iops=100:
2
waiting to be submitted build up in the list. There is no benefit is
3
using io_uring when the glib GSource is being used, so disable it
4
instead of implementing a more complex fix.
3
5
4
(guest)$ dd if=/dev/zero of=/dev/vdb oflag=direct count=1000
6
This fixes a memory leak where AioHandlers would build up and increasing
5
(qemu) stop
7
amounts of CPU time were spent iterating them in aio_pending(). The
6
(qemu) cont
8
symptom is that guests become slow when QEMU is built with io_uring
7
...I/O is stuck...
9
support.
8
10
9
This happens because blk_set_aio_context() detaches the ThrottleState
11
Buglink: https://bugs.launchpad.net/qemu/+bug/1877716
10
while requests may still be in flight:
12
Fixes: 73fd282e7b6dd4e4ea1c3bbb3d302c8db51e4ccf ("aio-posix: add io_uring fd monitoring implementation")
11
12
if (tgm->throttle_state) {
13
throttle_group_detach_aio_context(tgm);
14
throttle_group_attach_aio_context(tgm, new_context);
15
}
16
17
This patch encloses the detach/attach calls in a drained region so no
18
I/O request is left hanging. Also add assertions so we don't make the
19
same mistake again in the future.
20
21
Reported-by: Yongxue Hong <yhong@redhat.com>
22
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
13
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
23
Reviewed-by: Alberto Garcia <berto@igalia.com>
14
Tested-by: Oleksandr Natalenko <oleksandr@redhat.com>
24
Message-id: 20171110151934.16883-1-stefanha@redhat.com
15
Message-id: 20200511183630.279750-3-stefanha@redhat.com
25
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
16
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
26
---
17
---
27
block/block-backend.c | 2 ++
18
include/block/aio.h | 3 +++
28
block/throttle-groups.c | 6 ++++++
19
util/aio-posix.c | 12 ++++++++++++
29
2 files changed, 8 insertions(+)
20
util/aio-win32.c | 4 ++++
21
util/async.c | 1 +
22
4 files changed, 20 insertions(+)
30
23
31
diff --git a/block/block-backend.c b/block/block-backend.c
24
diff --git a/include/block/aio.h b/include/block/aio.h
32
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
33
--- a/block/block-backend.c
26
--- a/include/block/aio.h
34
+++ b/block/block-backend.c
27
+++ b/include/block/aio.h
35
@@ -XXX,XX +XXX,XX @@ void blk_set_aio_context(BlockBackend *blk, AioContext *new_context)
28
@@ -XXX,XX +XXX,XX @@ void aio_context_setup(AioContext *ctx);
36
29
*/
37
if (bs) {
30
void aio_context_destroy(AioContext *ctx);
38
if (tgm->throttle_state) {
31
39
+ bdrv_drained_begin(bs);
32
+/* Used internally, do not call outside AioContext code */
40
throttle_group_detach_aio_context(tgm);
33
+void aio_context_use_g_source(AioContext *ctx);
41
throttle_group_attach_aio_context(tgm, new_context);
34
+
42
+ bdrv_drained_end(bs);
35
/**
43
}
36
* aio_context_set_poll_params:
44
bdrv_set_aio_context(bs, new_context);
37
* @ctx: the aio context
45
}
38
diff --git a/util/aio-posix.c b/util/aio-posix.c
46
diff --git a/block/throttle-groups.c b/block/throttle-groups.c
47
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
48
--- a/block/throttle-groups.c
40
--- a/util/aio-posix.c
49
+++ b/block/throttle-groups.c
41
+++ b/util/aio-posix.c
50
@@ -XXX,XX +XXX,XX @@ void throttle_group_attach_aio_context(ThrottleGroupMember *tgm,
42
@@ -XXX,XX +XXX,XX @@ void aio_context_destroy(AioContext *ctx)
51
void throttle_group_detach_aio_context(ThrottleGroupMember *tgm)
43
aio_free_deleted_handlers(ctx);
44
}
45
46
+void aio_context_use_g_source(AioContext *ctx)
47
+{
48
+ /*
49
+ * Disable io_uring when the glib main loop is used because it doesn't
50
+ * support mixed glib/aio_poll() usage. It relies on aio_poll() being
51
+ * called regularly so that changes to the monitored file descriptors are
52
+ * submitted, otherwise a list of pending fd handlers builds up.
53
+ */
54
+ fdmon_io_uring_destroy(ctx);
55
+ aio_free_deleted_handlers(ctx);
56
+}
57
+
58
void aio_context_set_poll_params(AioContext *ctx, int64_t max_ns,
59
int64_t grow, int64_t shrink, Error **errp)
52
{
60
{
53
ThrottleTimers *tt = &tgm->throttle_timers;
61
diff --git a/util/aio-win32.c b/util/aio-win32.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/util/aio-win32.c
64
+++ b/util/aio-win32.c
65
@@ -XXX,XX +XXX,XX @@ void aio_context_destroy(AioContext *ctx)
66
{
67
}
68
69
+void aio_context_use_g_source(AioContext *ctx)
70
+{
71
+}
54
+
72
+
55
+ /* Requests must have been drained */
73
void aio_context_set_poll_params(AioContext *ctx, int64_t max_ns,
56
+ assert(tgm->pending_reqs[0] == 0 && tgm->pending_reqs[1] == 0);
74
int64_t grow, int64_t shrink, Error **errp)
57
+ assert(qemu_co_queue_empty(&tgm->throttled_reqs[0]));
75
{
58
+ assert(qemu_co_queue_empty(&tgm->throttled_reqs[1]));
76
diff --git a/util/async.c b/util/async.c
59
+
77
index XXXXXXX..XXXXXXX 100644
60
throttle_timers_detach_aio_context(tt);
78
--- a/util/async.c
61
tgm->aio_context = NULL;
79
+++ b/util/async.c
80
@@ -XXX,XX +XXX,XX @@ static GSourceFuncs aio_source_funcs = {
81
82
GSource *aio_get_g_source(AioContext *ctx)
83
{
84
+ aio_context_use_g_source(ctx);
85
g_source_ref(&ctx->source);
86
return &ctx->source;
62
}
87
}
63
--
88
--
64
2.13.6
89
2.25.3
65
90
66
diff view generated by jsdifflib