1
The following changes since commit fe8ee082db5038a05dbd8872e946049e9a9c550e:
1
The following changes since commit 013a18edbbc59cdad019100c7d03c0494642b74c:
2
2
3
Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2017-02-22' into staging (2017-02-24 15:00:51 +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
https://github.com/codyprime/qemu-kvm-jtc.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 1d393bdeae22fde2cb83c1ea719675747c85c40e:
10
for you to fetch changes up to ba607ca8bff4d2c2062902f8355657c865ac7c29:
10
11
11
RBD: Add support readv,writev for rbd (2017-02-24 12:43:01 -0500)
12
aio-posix: disable fdmon-io_uring when GSource is used (2020-05-18 18:16:00=
13
+0100)
12
14
13
----------------------------------------------------------------
15
----------------------------------------------------------------
14
Block patches for 2.9
16
Pull request
17
15
----------------------------------------------------------------
18
----------------------------------------------------------------
16
19
17
Peter Lieven (2):
20
Philippe Mathieu-Daud=C3=A9 (6):
18
block/nfs: convert to preadv / pwritev
21
tests/fuzz/Makefile: Do not link code using unavailable devices
19
block/nfs: try to avoid the bounce buffer in pwritev
22
Makefile: List fuzz targets in 'make help'
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
20
27
21
tianqing (1):
28
Stefan Hajnoczi (2):
22
RBD: Add support readv,writev for rbd
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
23
32
24
block/nfs.c | 62 +++++++++++++++++++++++++----------------------
33
Makefile | 6 +++-
25
block/rbd.c | 80 ++++++++++++++++++++++++++++++++++++++++++-------------------
34
tests/qtest/fuzz/Makefile.include | 6 ++--
26
2 files changed, 90 insertions(+), 52 deletions(-)
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(-)
27
42
28
--
43
--=20
29
2.9.3
44
2.25.3
30
45
31
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: Peter Lieven <pl@kamp.de>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
if the passed qiov contains exactly one iov we can
3
These typedefs are not used. Use a simple structure,
4
pass the buffer directly.
4
remote the typedefs.
5
5
6
Signed-off-by: Peter Lieven <pl@kamp.de>
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Reviewed-by: Jeff Cody <jcody@redhat.com>
7
Message-id: 20200514143433.18569-5-philmd@redhat.com
8
Message-id: 1487349541-10201-3-git-send-email-pl@kamp.de
8
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Signed-off-by: Jeff Cody <jcody@redhat.com>
10
---
9
---
11
block/nfs.c | 35 ++++++++++++++++++++++-------------
10
tests/qtest/fuzz/i440fx_fuzz.c | 10 ++++------
12
1 file changed, 22 insertions(+), 13 deletions(-)
11
1 file changed, 4 insertions(+), 6 deletions(-)
13
12
14
diff --git a/block/nfs.c b/block/nfs.c
13
diff --git a/tests/qtest/fuzz/i440fx_fuzz.c b/tests/qtest/fuzz/i440fx_fuzz.c
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/block/nfs.c
15
--- a/tests/qtest/fuzz/i440fx_fuzz.c
17
+++ b/block/nfs.c
16
+++ b/tests/qtest/fuzz/i440fx_fuzz.c
18
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn nfs_co_pwritev(BlockDriverState *bs, uint64_t offset,
17
@@ -XXX,XX +XXX,XX @@ static void i440fx_fuzz_qtest(QTestState *s,
19
NFSClient *client = bs->opaque;
18
* loop over the Data, breaking it up into actions. each action has an
20
NFSRPC task;
19
* opcode, address offset and value
21
char *buf = NULL;
20
*/
22
+ bool my_buffer = false;
21
- typedef struct QTestFuzzAction {
23
22
+ struct {
24
nfs_co_init_task(bs, &task);
23
uint8_t opcode;
25
24
uint8_t addr;
26
- buf = g_try_malloc(bytes);
25
uint32_t value;
27
- if (bytes && buf == NULL) {
26
- } QTestFuzzAction;
28
- return -ENOMEM;
27
- QTestFuzzAction a;
29
+ if (iov->niov != 1) {
28
+ } a;
30
+ buf = g_try_malloc(bytes);
29
31
+ if (bytes && buf == NULL) {
30
while (Size >= sizeof(a)) {
32
+ return -ENOMEM;
31
/* make a copy of the action so we can normalize the values in-place */
33
+ }
32
@@ -XXX,XX +XXX,XX @@ static void i440fx_fuzz_qos(QTestState *s,
34
+ qemu_iovec_to_buf(iov, 0, buf, bytes);
33
* Same as i440fx_fuzz_qtest, but using QOS. devfn is incorporated into the
35
+ my_buffer = true;
34
* value written over Port IO
36
+ } else {
35
*/
37
+ buf = iov->iov[0].iov_base;
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);
38
}
48
}
39
49
40
- qemu_iovec_to_buf(iov, 0, buf, bytes);
50
- QOSFuzzAction a;
41
-
51
while (Size >= sizeof(a)) {
42
if (nfs_pwrite_async(client->context, client->fh,
52
memcpy(&a, Data, sizeof(a));
43
offset, bytes, buf,
53
switch (a.opcode % ACTION_MAX) {
44
nfs_co_generic_cb, &task) != 0) {
45
+ if (my_buffer) {
46
+ g_free(buf);
47
+ }
48
+ return -ENOMEM;
49
+ }
50
+
51
+ nfs_set_events(client);
52
+ while (!task.complete) {
53
+ qemu_coroutine_yield();
54
+ }
55
+
56
+ if (my_buffer) {
57
g_free(buf);
58
- return -ENOMEM;
59
}
60
61
- nfs_set_events(client);
62
- while (!task.complete) {
63
- qemu_coroutine_yield();
64
- }
65
-
66
- g_free(buf);
67
-
68
if (task.ret != bytes) {
69
return task.ret < 0 ? task.ret : -EIO;
70
}
71
--
54
--
72
2.9.3
55
2.25.3
73
56
74
diff view generated by jsdifflib
1
From: Peter Lieven <pl@kamp.de>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Signed-off-by: Peter Lieven <pl@kamp.de>
3
Extract the generic pciconfig_fuzz_qos() method from
4
Reviewed-by: Jeff Cody <jcody@redhat.com>
4
i440fx_fuzz_qos(). This will help to write tests not
5
Message-id: 1487349541-10201-2-git-send-email-pl@kamp.de
5
specific to the i440FX controller.
6
Signed-off-by: Jeff Cody <jcody@redhat.com>
6
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20200514143433.18569-6-philmd@redhat.com
9
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
7
---
10
---
8
block/nfs.c | 33 +++++++++++++++------------------
11
tests/qtest/fuzz/i440fx_fuzz.c | 20 ++++++++++++++------
9
1 file changed, 15 insertions(+), 18 deletions(-)
12
1 file changed, 14 insertions(+), 6 deletions(-)
10
13
11
diff --git a/block/nfs.c b/block/nfs.c
14
diff --git a/tests/qtest/fuzz/i440fx_fuzz.c b/tests/qtest/fuzz/i440fx_fuzz.c
12
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
13
--- a/block/nfs.c
16
--- a/tests/qtest/fuzz/i440fx_fuzz.c
14
+++ b/block/nfs.c
17
+++ b/tests/qtest/fuzz/i440fx_fuzz.c
15
@@ -XXX,XX +XXX,XX @@ nfs_co_generic_cb(int ret, struct nfs_context *nfs, void *data,
18
@@ -XXX,XX +XXX,XX @@ static void i440fx_fuzz_qtest(QTestState *s,
16
nfs_co_generic_bh_cb, task);
19
flush_events(s);
17
}
20
}
18
21
19
-static int coroutine_fn nfs_co_readv(BlockDriverState *bs,
22
-static void i440fx_fuzz_qos(QTestState *s,
20
- int64_t sector_num, int nb_sectors,
23
+static void pciconfig_fuzz_qos(QTestState *s, QPCIBus *bus,
21
- QEMUIOVector *iov)
24
const unsigned char *Data, size_t Size) {
22
+static int coroutine_fn nfs_co_preadv(BlockDriverState *bs, uint64_t offset,
25
/*
23
+ uint64_t bytes, QEMUIOVector *iov,
26
* Same as i440fx_fuzz_qtest, but using QOS. devfn is incorporated into the
24
+ int flags)
27
@@ -XXX,XX +XXX,XX @@ static void i440fx_fuzz_qos(QTestState *s,
25
{
28
uint32_t value;
26
NFSClient *client = bs->opaque;
29
} a;
27
NFSRPC task;
30
28
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn nfs_co_readv(BlockDriverState *bs,
31
- static QPCIBus *bus;
29
task.iov = iov;
32
- if (!bus) {
30
33
- bus = qpci_new_pc(s, fuzz_qos_alloc);
31
if (nfs_pread_async(client->context, client->fh,
34
- }
32
- sector_num * BDRV_SECTOR_SIZE,
35
-
33
- nb_sectors * BDRV_SECTOR_SIZE,
36
while (Size >= sizeof(a)) {
34
- nfs_co_generic_cb, &task) != 0) {
37
memcpy(&a, Data, sizeof(a));
35
+ offset, bytes, nfs_co_generic_cb, &task) != 0) {
38
switch (a.opcode % ACTION_MAX) {
36
return -ENOMEM;
39
@@ -XXX,XX +XXX,XX @@ static void i440fx_fuzz_qos(QTestState *s,
37
}
40
flush_events(s);
38
39
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn nfs_co_readv(BlockDriverState *bs,
40
return 0;
41
}
41
}
42
42
43
-static int coroutine_fn nfs_co_writev(BlockDriverState *bs,
43
+static void i440fx_fuzz_qos(QTestState *s,
44
- int64_t sector_num, int nb_sectors,
44
+ const unsigned char *Data,
45
- QEMUIOVector *iov)
45
+ size_t Size)
46
+static int coroutine_fn nfs_co_pwritev(BlockDriverState *bs, uint64_t offset,
46
+{
47
+ uint64_t bytes, QEMUIOVector *iov,
47
+ static QPCIBus *bus;
48
+ int flags)
48
+
49
{
49
+ if (!bus) {
50
NFSClient *client = bs->opaque;
50
+ bus = qpci_new_pc(s, fuzz_qos_alloc);
51
NFSRPC task;
51
+ }
52
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn nfs_co_writev(BlockDriverState *bs,
52
+
53
53
+ pciconfig_fuzz_qos(s, bus, Data, Size);
54
nfs_co_init_task(bs, &task);
54
+}
55
55
+
56
- buf = g_try_malloc(nb_sectors * BDRV_SECTOR_SIZE);
56
static void i440fx_fuzz_qos_fork(QTestState *s,
57
- if (nb_sectors && buf == NULL) {
57
const unsigned char *Data, size_t Size) {
58
+ buf = g_try_malloc(bytes);
58
if (fork() == 0) {
59
+ if (bytes && buf == NULL) {
60
return -ENOMEM;
61
}
62
63
- qemu_iovec_to_buf(iov, 0, buf, nb_sectors * BDRV_SECTOR_SIZE);
64
+ qemu_iovec_to_buf(iov, 0, buf, bytes);
65
66
if (nfs_pwrite_async(client->context, client->fh,
67
- sector_num * BDRV_SECTOR_SIZE,
68
- nb_sectors * BDRV_SECTOR_SIZE,
69
- buf, nfs_co_generic_cb, &task) != 0) {
70
+ offset, bytes, buf,
71
+ nfs_co_generic_cb, &task) != 0) {
72
g_free(buf);
73
return -ENOMEM;
74
}
75
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn nfs_co_writev(BlockDriverState *bs,
76
77
g_free(buf);
78
79
- if (task.ret != nb_sectors * BDRV_SECTOR_SIZE) {
80
+ if (task.ret != bytes) {
81
return task.ret < 0 ? task.ret : -EIO;
82
}
83
84
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_nfs = {
85
.bdrv_create = nfs_file_create,
86
.bdrv_reopen_prepare = nfs_reopen_prepare,
87
88
- .bdrv_co_readv = nfs_co_readv,
89
- .bdrv_co_writev = nfs_co_writev,
90
+ .bdrv_co_preadv = nfs_co_preadv,
91
+ .bdrv_co_pwritev = nfs_co_pwritev,
92
.bdrv_co_flush_to_disk = nfs_co_flush,
93
94
.bdrv_detach_aio_context = nfs_detach_aio_context,
95
--
59
--
96
2.9.3
60
2.25.3
97
61
98
diff view generated by jsdifflib
New patch
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
2
3
Extract generic ioport_fuzz_qtest() method from
4
i440fx_fuzz_qtest(). This will help to write tests
5
not specific to the i440FX controller.
6
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20200514143433.18569-7-philmd@redhat.com
9
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
10
---
11
tests/qtest/fuzz/i440fx_fuzz.c | 11 +++++++++--
12
1 file changed, 9 insertions(+), 2 deletions(-)
13
14
diff --git a/tests/qtest/fuzz/i440fx_fuzz.c b/tests/qtest/fuzz/i440fx_fuzz.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/tests/qtest/fuzz/i440fx_fuzz.c
17
+++ b/tests/qtest/fuzz/i440fx_fuzz.c
18
@@ -XXX,XX +XXX,XX @@ enum action_id {
19
ACTION_MAX
20
};
21
22
-static void i440fx_fuzz_qtest(QTestState *s,
23
+static void ioport_fuzz_qtest(QTestState *s,
24
const unsigned char *Data, size_t Size) {
25
/*
26
* loop over the Data, breaking it up into actions. each action has an
27
@@ -XXX,XX +XXX,XX @@ static void i440fx_fuzz_qtest(QTestState *s,
28
flush_events(s);
29
}
30
31
+static void i440fx_fuzz_qtest(QTestState *s,
32
+ const unsigned char *Data,
33
+ size_t Size)
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 {
46
--
47
2.25.3
48
diff view generated by jsdifflib
New patch
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.
1
4
5
Don't delete fd handlers directly in fdmon_io_uring_destroy() for two
6
reasons:
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!
15
16
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
17
Tested-by: Oleksandr Natalenko <oleksandr@redhat.com>
18
Message-id: 20200511183630.279750-2-stefanha@redhat.com
19
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
20
---
21
util/aio-posix.c | 1 +
22
util/fdmon-io_uring.c | 13 ++++++++++---
23
2 files changed, 11 insertions(+), 3 deletions(-)
24
25
diff --git a/util/aio-posix.c b/util/aio-posix.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/util/aio-posix.c
28
+++ b/util/aio-posix.c
29
@@ -XXX,XX +XXX,XX @@ void aio_context_destroy(AioContext *ctx)
30
{
31
fdmon_io_uring_destroy(ctx);
32
fdmon_epoll_disable(ctx);
33
+ aio_free_deleted_handlers(ctx);
34
}
35
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;
63
--
64
2.25.3
65
diff view generated by jsdifflib
1
From: tianqing <tianqing@unitedstack.com>
1
The glib event loop does not call fdmon_io_uring_wait() so fd handlers
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.
2
5
3
Rbd can do readv and writev directly, so wo do not need to transform
6
This fixes a memory leak where AioHandlers would build up and increasing
4
iov to buf or vice versa any more.
7
amounts of CPU time were spent iterating them in aio_pending(). The
8
symptom is that guests become slow when QEMU is built with io_uring
9
support.
5
10
6
Signed-off-by: tianqing <tianqing@unitedstack.com>
11
Buglink: https://bugs.launchpad.net/qemu/+bug/1877716
7
Reviewed-by: Jeff Cody <jcody@redhat.com>
12
Fixes: 73fd282e7b6dd4e4ea1c3bbb3d302c8db51e4ccf ("aio-posix: add io_uring fd monitoring implementation")
8
Signed-off-by: Jeff Cody <jcody@redhat.com>
13
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
14
Tested-by: Oleksandr Natalenko <oleksandr@redhat.com>
15
Message-id: 20200511183630.279750-3-stefanha@redhat.com
16
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
9
---
17
---
10
block/rbd.c | 80 ++++++++++++++++++++++++++++++++++++++++++-------------------
18
include/block/aio.h | 3 +++
11
1 file changed, 56 insertions(+), 24 deletions(-)
19
util/aio-posix.c | 12 ++++++++++++
20
util/aio-win32.c | 4 ++++
21
util/async.c | 1 +
22
4 files changed, 20 insertions(+)
12
23
13
diff --git a/block/rbd.c b/block/rbd.c
24
diff --git a/include/block/aio.h b/include/block/aio.h
14
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
15
--- a/block/rbd.c
26
--- a/include/block/aio.h
16
+++ b/block/rbd.c
27
+++ b/include/block/aio.h
17
@@ -XXX,XX +XXX,XX @@
28
@@ -XXX,XX +XXX,XX @@ void aio_context_setup(AioContext *ctx);
18
#define RBD_MAX_SNAP_NAME_SIZE 128
29
*/
19
#define RBD_MAX_SNAPS 100
30
void aio_context_destroy(AioContext *ctx);
20
31
21
+/* The LIBRBD_SUPPORTS_IOVEC is defined in librbd.h */
32
+/* Used internally, do not call outside AioContext code */
22
+#ifdef LIBRBD_SUPPORTS_IOVEC
33
+void aio_context_use_g_source(AioContext *ctx);
23
+#define LIBRBD_USE_IOVEC 1
24
+#else
25
+#define LIBRBD_USE_IOVEC 0
26
+#endif
27
+
34
+
28
typedef enum {
35
/**
29
RBD_AIO_READ,
36
* aio_context_set_poll_params:
30
RBD_AIO_WRITE,
37
* @ctx: the aio context
31
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_set_conf(rados_t cluster, const char *conf,
38
diff --git a/util/aio-posix.c b/util/aio-posix.c
32
return ret;
39
index XXXXXXX..XXXXXXX 100644
40
--- a/util/aio-posix.c
41
+++ b/util/aio-posix.c
42
@@ -XXX,XX +XXX,XX @@ void aio_context_destroy(AioContext *ctx)
43
aio_free_deleted_handlers(ctx);
33
}
44
}
34
45
35
+static void qemu_rbd_memset(RADOSCB *rcb, int64_t offs)
46
+void aio_context_use_g_source(AioContext *ctx)
36
+{
47
+{
37
+ if (LIBRBD_USE_IOVEC) {
48
+ /*
38
+ RBDAIOCB *acb = rcb->acb;
49
+ * Disable io_uring when the glib main loop is used because it doesn't
39
+ iov_memset(acb->qiov->iov, acb->qiov->niov, offs, 0,
50
+ * support mixed glib/aio_poll() usage. It relies on aio_poll() being
40
+ acb->qiov->size - offs);
51
+ * called regularly so that changes to the monitored file descriptors are
41
+ } else {
52
+ * submitted, otherwise a list of pending fd handlers builds up.
42
+ memset(rcb->buf + offs, 0, rcb->size - offs);
53
+ */
43
+ }
54
+ fdmon_io_uring_destroy(ctx);
55
+ aio_free_deleted_handlers(ctx);
44
+}
56
+}
45
+
57
+
46
static int qemu_rbd_create(const char *filename, QemuOpts *opts, Error **errp)
58
void aio_context_set_poll_params(AioContext *ctx, int64_t max_ns,
59
int64_t grow, int64_t shrink, Error **errp)
47
{
60
{
48
Error *local_err = NULL;
61
diff --git a/util/aio-win32.c b/util/aio-win32.c
49
@@ -XXX,XX +XXX,XX @@ static void qemu_rbd_complete_aio(RADOSCB *rcb)
62
index XXXXXXX..XXXXXXX 100644
50
}
63
--- a/util/aio-win32.c
51
} else {
64
+++ b/util/aio-win32.c
52
if (r < 0) {
65
@@ -XXX,XX +XXX,XX @@ void aio_context_destroy(AioContext *ctx)
53
- memset(rcb->buf, 0, rcb->size);
66
{
54
+ qemu_rbd_memset(rcb, 0);
67
}
55
acb->ret = r;
68
56
acb->error = 1;
69
+void aio_context_use_g_source(AioContext *ctx)
57
} else if (r < rcb->size) {
70
+{
58
- memset(rcb->buf + r, 0, rcb->size - r);
71
+}
59
+ qemu_rbd_memset(rcb, r);
60
if (!acb->error) {
61
acb->ret = rcb->size;
62
}
63
@@ -XXX,XX +XXX,XX @@ static void qemu_rbd_complete_aio(RADOSCB *rcb)
64
65
g_free(rcb);
66
67
- if (acb->cmd == RBD_AIO_READ) {
68
- qemu_iovec_from_buf(acb->qiov, 0, acb->bounce, acb->qiov->size);
69
+ if (!LIBRBD_USE_IOVEC) {
70
+ if (acb->cmd == RBD_AIO_READ) {
71
+ qemu_iovec_from_buf(acb->qiov, 0, acb->bounce, acb->qiov->size);
72
+ }
73
+ qemu_vfree(acb->bounce);
74
}
75
- qemu_vfree(acb->bounce);
76
+
72
+
77
acb->common.cb(acb->common.opaque, (acb->ret > 0 ? 0 : acb->ret));
73
void aio_context_set_poll_params(AioContext *ctx, int64_t max_ns,
78
74
int64_t grow, int64_t shrink, Error **errp)
79
qemu_aio_unref(acb);
75
{
80
@@ -XXX,XX +XXX,XX @@ static BlockAIOCB *rbd_start_aio(BlockDriverState *bs,
76
diff --git a/util/async.c b/util/async.c
81
RBDAIOCB *acb;
77
index XXXXXXX..XXXXXXX 100644
82
RADOSCB *rcb = NULL;
78
--- a/util/async.c
83
rbd_completion_t c;
79
+++ b/util/async.c
84
- char *buf;
80
@@ -XXX,XX +XXX,XX @@ static GSourceFuncs aio_source_funcs = {
85
int r;
81
86
82
GSource *aio_get_g_source(AioContext *ctx)
87
BDRVRBDState *s = bs->opaque;
83
{
88
@@ -XXX,XX +XXX,XX @@ static BlockAIOCB *rbd_start_aio(BlockDriverState *bs,
84
+ aio_context_use_g_source(ctx);
89
acb->cmd = cmd;
85
g_source_ref(&ctx->source);
90
acb->qiov = qiov;
86
return &ctx->source;
91
assert(!qiov || qiov->size == size);
92
- if (cmd == RBD_AIO_DISCARD || cmd == RBD_AIO_FLUSH) {
93
- acb->bounce = NULL;
94
- } else {
95
- acb->bounce = qemu_try_blockalign(bs, qiov->size);
96
- if (acb->bounce == NULL) {
97
- goto failed;
98
+
99
+ rcb = g_new(RADOSCB, 1);
100
+
101
+ if (!LIBRBD_USE_IOVEC) {
102
+ if (cmd == RBD_AIO_DISCARD || cmd == RBD_AIO_FLUSH) {
103
+ acb->bounce = NULL;
104
+ } else {
105
+ acb->bounce = qemu_try_blockalign(bs, qiov->size);
106
+ if (acb->bounce == NULL) {
107
+ goto failed;
108
+ }
109
}
110
+ if (cmd == RBD_AIO_WRITE) {
111
+ qemu_iovec_to_buf(acb->qiov, 0, acb->bounce, qiov->size);
112
+ }
113
+ rcb->buf = acb->bounce;
114
}
115
+
116
acb->ret = 0;
117
acb->error = 0;
118
acb->s = s;
119
120
- if (cmd == RBD_AIO_WRITE) {
121
- qemu_iovec_to_buf(acb->qiov, 0, acb->bounce, qiov->size);
122
- }
123
-
124
- buf = acb->bounce;
125
-
126
- rcb = g_new(RADOSCB, 1);
127
rcb->acb = acb;
128
- rcb->buf = buf;
129
rcb->s = acb->s;
130
rcb->size = size;
131
r = rbd_aio_create_completion(rcb, (rbd_callback_t) rbd_finish_aiocb, &c);
132
@@ -XXX,XX +XXX,XX @@ static BlockAIOCB *rbd_start_aio(BlockDriverState *bs,
133
134
switch (cmd) {
135
case RBD_AIO_WRITE:
136
- r = rbd_aio_write(s->image, off, size, buf, c);
137
+#ifdef LIBRBD_SUPPORTS_IOVEC
138
+ r = rbd_aio_writev(s->image, qiov->iov, qiov->niov, off, c);
139
+#else
140
+ r = rbd_aio_write(s->image, off, size, rcb->buf, c);
141
+#endif
142
break;
143
case RBD_AIO_READ:
144
- r = rbd_aio_read(s->image, off, size, buf, c);
145
+#ifdef LIBRBD_SUPPORTS_IOVEC
146
+ r = rbd_aio_readv(s->image, qiov->iov, qiov->niov, off, c);
147
+#else
148
+ r = rbd_aio_read(s->image, off, size, rcb->buf, c);
149
+#endif
150
break;
151
case RBD_AIO_DISCARD:
152
r = rbd_aio_discard_wrapper(s->image, off, size, c);
153
@@ -XXX,XX +XXX,XX @@ static BlockAIOCB *rbd_start_aio(BlockDriverState *bs,
154
if (r < 0) {
155
goto failed_completion;
156
}
157
-
158
return &acb->common;
159
160
failed_completion:
161
rbd_aio_release(c);
162
failed:
163
g_free(rcb);
164
- qemu_vfree(acb->bounce);
165
+ if (!LIBRBD_USE_IOVEC) {
166
+ qemu_vfree(acb->bounce);
167
+ }
168
+
169
qemu_aio_unref(acb);
170
return NULL;
171
}
87
}
172
--
88
--
173
2.9.3
89
2.25.3
174
90
175
diff view generated by jsdifflib