1
The following changes since commit 66234fee9c2d37bfbc523aa8d0ae5300a14cc10e:
1
The following changes since commit 6c769690ac845fa62642a5f93b4e4bd906adab95:
2
2
3
Merge remote-tracking branch 'remotes/alistair/tags/pull-riscv-to-apply-202=
3
Merge remote-tracking branch 'remotes/vsementsov/tags/pull-simplebench-2021-05-04' into staging (2021-05-21 12:02:34 +0100)
4
00603' into staging (2020-06-04 11:38:48 +0100)
5
4
6
are available in the Git repository at:
5
are available in the Git repository at:
7
6
8
https://github.com/stefanha/qemu.git tags/block-pull-request
7
https://gitlab.com/stefanha/qemu.git tags/block-pull-request
9
8
10
for you to fetch changes up to 7d2410cea154bf915fb30179ebda3b17ac36e70e:
9
for you to fetch changes up to 0a6f0c76a030710780ce10d6347a70f098024d21:
11
10
12
block: Factor out bdrv_run_co() (2020-06-05 09:54:48 +0100)
11
coroutine-sleep: introduce qemu_co_sleep (2021-05-21 18:22:33 +0100)
13
12
14
----------------------------------------------------------------
13
----------------------------------------------------------------
15
Pull request
14
Pull request
16
15
16
(Resent due to an email preparation mistake.)
17
17
----------------------------------------------------------------
18
----------------------------------------------------------------
18
19
19
Alexander Bulekov (4):
20
Paolo Bonzini (6):
20
fuzz: add datadir for oss-fuzz compatability
21
coroutine-sleep: use a stack-allocated timer
21
fuzz: fix typo in i440fx-qtest-reboot arguments
22
coroutine-sleep: disallow NULL QemuCoSleepState** argument
22
fuzz: add mangled object name to linker script
23
coroutine-sleep: allow qemu_co_sleep_wake that wakes nothing
23
fuzz: run the main-loop in fork-server process
24
coroutine-sleep: move timer out of QemuCoSleepState
25
coroutine-sleep: replace QemuCoSleepState pointer with struct in the
26
API
27
coroutine-sleep: introduce qemu_co_sleep
24
28
25
Philippe Mathieu-Daud=C3=A9 (4):
29
Philippe Mathieu-Daudé (1):
26
memory: Rename memory_region_do_writeback -> memory_region_writeback
30
bitops.h: Improve find_xxx_bit() documentation
27
memory: Extract memory_region_msync() from memory_region_writeback()
28
hw/block: Let the NVMe emulated device be target-agnostic
29
exec: Rename qemu_ram_writeback() as qemu_ram_msync()
30
31
31
Stefano Garzarella (2):
32
Zenghui Yu (1):
32
io_uring: retry io_uring_submit() if it fails with errno=3DEINTR
33
multi-process: Initialize variables declared with g_auto*
33
io_uring: use io_uring_cq_ready() to check for ready cqes
34
34
35
Vladimir Sementsov-Ogievskiy (1):
35
include/qemu/bitops.h | 15 ++++++--
36
block: Factor out bdrv_run_co()
36
include/qemu/coroutine.h | 27 ++++++++-----
37
block/block-copy.c | 10 ++---
38
block/nbd.c | 14 +++----
39
hw/remote/memory.c | 5 +--
40
hw/remote/proxy.c | 3 +-
41
util/qemu-coroutine-sleep.c | 75 +++++++++++++++++++------------------
42
7 files changed, 79 insertions(+), 70 deletions(-)
37
43
38
hw/block/Makefile.objs | 2 +-
44
--
39
include/exec/memory.h | 15 ++-
45
2.31.1
40
include/exec/ram_addr.h | 4 +-
41
include/sysemu/sysemu.h | 2 +
42
block/io.c | 193 +++++++++++-----------------
43
block/io_uring.c | 11 +-
44
exec.c | 2 +-
45
hw/block/nvme.c | 6 +-
46
memory.c | 12 +-
47
softmmu/vl.c | 2 +-
48
target/arm/helper.c | 2 +-
49
tests/qtest/fuzz/fuzz.c | 15 +++
50
tests/qtest/fuzz/i440fx_fuzz.c | 3 +-
51
tests/qtest/fuzz/virtio_net_fuzz.c | 2 +
52
tests/qtest/fuzz/virtio_scsi_fuzz.c | 2 +
53
tests/qtest/fuzz/fork_fuzz.ld | 5 +
54
16 files changed, 134 insertions(+), 144 deletions(-)
55
46
56
--=20
57
2.25.4
58
diff view generated by jsdifflib
Deleted patch
1
From: Stefano Garzarella <sgarzare@redhat.com>
2
1
3
As recently documented [1], io_uring_enter(2) syscall can return an
4
error (errno=EINTR) if the operation was interrupted by a delivery
5
of a signal before it could complete.
6
7
This should happen when IORING_ENTER_GETEVENTS flag is used, for
8
example during io_uring_submit_and_wait() or during io_uring_submit()
9
when IORING_SETUP_IOPOLL is enabled.
10
11
We shouldn't have this problem for now, but it's better to prevent it.
12
13
[1] https://github.com/axboe/liburing/commit/344355ec6619de8f4e64584c9736530b5346e4f4
14
15
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
16
Message-id: 20200519133041.112138-1-sgarzare@redhat.com
17
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
18
---
19
block/io_uring.c | 2 +-
20
1 file changed, 1 insertion(+), 1 deletion(-)
21
22
diff --git a/block/io_uring.c b/block/io_uring.c
23
index XXXXXXX..XXXXXXX 100644
24
--- a/block/io_uring.c
25
+++ b/block/io_uring.c
26
@@ -XXX,XX +XXX,XX @@ static int ioq_submit(LuringState *s)
27
trace_luring_io_uring_submit(s, ret);
28
/* Prevent infinite loop if submission is refused */
29
if (ret <= 0) {
30
- if (ret == -EAGAIN) {
31
+ if (ret == -EAGAIN || ret == -EINTR) {
32
continue;
33
}
34
break;
35
--
36
2.25.4
37
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Zenghui Yu <yuzenghui@huawei.com>
2
2
3
Now than the non-target specific memory_region_msync() function
3
Quote docs/devel/style.rst (section "Automatic memory deallocation"):
4
is available, use it to make this device target-agnostic.
5
4
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
* Variables declared with g_auto* MUST always be initialized,
7
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
6
otherwise the cleanup function will use uninitialized stack memory
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
9
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
8
Initialize @name properly to get rid of the compilation error (using
10
Message-id: 20200508062456.23344-4-philmd@redhat.com
9
gcc-7.3.0 on CentOS):
10
11
../hw/remote/proxy.c: In function 'pci_proxy_dev_realize':
12
/usr/include/glib-2.0/glib/glib-autocleanups.h:28:3: error: 'name' may be used uninitialized in this function [-Werror=maybe-uninitialized]
13
g_free (*pp);
14
^~~~~~~~~~~~
15
../hw/remote/proxy.c:350:30: note: 'name' was declared here
16
g_autofree char *name;
17
^~~~
18
19
Signed-off-by: Zenghui Yu <yuzenghui@huawei.com>
20
Reviewed-by: Jagannathan Raman <jag.raman@oracle.com>
21
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
22
Reviewed-by: Miroslav Rezanina <mrezanin@redhat.com>
23
Message-id: 20210312112143.1369-1-yuzenghui@huawei.com
11
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
24
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
12
---
25
---
13
hw/block/Makefile.objs | 2 +-
26
hw/remote/memory.c | 5 ++---
14
hw/block/nvme.c | 6 ++----
27
hw/remote/proxy.c | 3 +--
15
2 files changed, 3 insertions(+), 5 deletions(-)
28
2 files changed, 3 insertions(+), 5 deletions(-)
16
29
17
diff --git a/hw/block/Makefile.objs b/hw/block/Makefile.objs
30
diff --git a/hw/remote/memory.c b/hw/remote/memory.c
18
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/block/Makefile.objs
32
--- a/hw/remote/memory.c
20
+++ b/hw/block/Makefile.objs
33
+++ b/hw/remote/memory.c
21
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_SH4) += tc58128.o
34
@@ -XXX,XX +XXX,XX @@ void remote_sysmem_reconfig(MPQemuMsg *msg, Error **errp)
22
35
23
obj-$(CONFIG_VIRTIO_BLK) += virtio-blk.o
36
remote_sysmem_reset();
24
obj-$(CONFIG_VHOST_USER_BLK) += vhost-user-blk.o
37
25
-obj-$(CONFIG_NVME_PCI) += nvme.o
38
- for (region = 0; region < msg->num_fds; region++) {
26
+common-obj-$(CONFIG_NVME_PCI) += nvme.o
39
- g_autofree char *name;
27
40
+ for (region = 0; region < msg->num_fds; region++, suffix++) {
28
obj-y += dataplane/
41
+ g_autofree char *name = g_strdup_printf("remote-mem-%u", suffix);
29
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
42
subregion = g_new(MemoryRegion, 1);
43
- name = g_strdup_printf("remote-mem-%u", suffix++);
44
memory_region_init_ram_from_fd(subregion, NULL,
45
name, sysmem_info->sizes[region],
46
true, msg->fds[region],
47
diff --git a/hw/remote/proxy.c b/hw/remote/proxy.c
30
index XXXXXXX..XXXXXXX 100644
48
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/block/nvme.c
49
--- a/hw/remote/proxy.c
32
+++ b/hw/block/nvme.c
50
+++ b/hw/remote/proxy.c
33
@@ -XXX,XX +XXX,XX @@
51
@@ -XXX,XX +XXX,XX @@ static void probe_pci_info(PCIDevice *dev, Error **errp)
34
#include "qapi/visitor.h"
52
PCI_BASE_ADDRESS_SPACE_IO : PCI_BASE_ADDRESS_SPACE_MEMORY;
35
#include "sysemu/hostmem.h"
53
36
#include "sysemu/block-backend.h"
54
if (size) {
37
-#include "exec/ram_addr.h"
55
- g_autofree char *name;
38
-
56
+ g_autofree char *name = g_strdup_printf("bar-region-%d", i);
39
+#include "exec/memory.h"
57
pdev->region[i].dev = pdev;
40
#include "qemu/log.h"
58
pdev->region[i].present = true;
41
#include "qemu/module.h"
59
if (type == PCI_BASE_ADDRESS_SPACE_MEMORY) {
42
#include "qemu/cutils.h"
60
pdev->region[i].memory = true;
43
@@ -XXX,XX +XXX,XX @@ static uint64_t nvme_mmio_read(void *opaque, hwaddr addr, unsigned size)
61
}
44
*/
62
- name = g_strdup_printf("bar-region-%d", i);
45
if (addr == 0xE08 &&
63
memory_region_init_io(&pdev->region[i].mr, OBJECT(pdev),
46
(NVME_PMRCAP_PMRWBM(n->bar.pmrcap) & 0x02)) {
64
&proxy_mr_ops, &pdev->region[i],
47
- qemu_ram_writeback(n->pmrdev->mr.ram_block,
65
name, size);
48
- 0, n->pmrdev->size);
49
+ memory_region_msync(&n->pmrdev->mr, 0, n->pmrdev->size);
50
}
51
memcpy(&val, ptr + addr, size);
52
} else {
53
--
66
--
54
2.25.4
67
2.31.1
55
68
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Rename qemu_ram_writeback() as qemu_ram_msync() to better
3
Document the following functions return the bitmap size
4
match what it does.
4
if no matching bit is found:
5
5
6
Suggested-by: Stefan Hajnoczi <stefanha@redhat.com>
6
- find_first_bit
7
- find_next_bit
8
- find_last_bit
9
- find_first_zero_bit
10
- find_next_zero_bit
11
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
13
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
14
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20210510200758.2623154-2-philmd@redhat.com
10
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
11
Message-id: 20200508062456.23344-5-philmd@redhat.com
12
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
16
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
13
---
17
---
14
include/exec/ram_addr.h | 4 ++--
18
include/qemu/bitops.h | 15 ++++++++++++---
15
exec.c | 2 +-
19
1 file changed, 12 insertions(+), 3 deletions(-)
16
memory.c | 2 +-
17
3 files changed, 4 insertions(+), 4 deletions(-)
18
20
19
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
21
diff --git a/include/qemu/bitops.h b/include/qemu/bitops.h
20
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
21
--- a/include/exec/ram_addr.h
23
--- a/include/qemu/bitops.h
22
+++ b/include/exec/ram_addr.h
24
+++ b/include/qemu/bitops.h
23
@@ -XXX,XX +XXX,XX @@ void qemu_ram_free(RAMBlock *block);
25
@@ -XXX,XX +XXX,XX @@ static inline int test_bit(long nr, const unsigned long *addr)
24
26
* @addr: The address to start the search at
25
int qemu_ram_resize(RAMBlock *block, ram_addr_t newsize, Error **errp);
27
* @size: The maximum size to search
26
28
*
27
-void qemu_ram_writeback(RAMBlock *block, ram_addr_t start, ram_addr_t length);
29
- * Returns the bit number of the first set bit, or size.
28
+void qemu_ram_msync(RAMBlock *block, ram_addr_t start, ram_addr_t length);
30
+ * Returns the bit number of the last set bit,
29
31
+ * or @size if there is no set bit in the bitmap.
30
/* Clear whole block of mem */
31
static inline void qemu_ram_block_writeback(RAMBlock *block)
32
{
33
- qemu_ram_writeback(block, 0, block->used_length);
34
+ qemu_ram_msync(block, 0, block->used_length);
35
}
36
37
#define DIRTY_CLIENTS_ALL ((1 << DIRTY_MEMORY_NUM) - 1)
38
diff --git a/exec.c b/exec.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/exec.c
41
+++ b/exec.c
42
@@ -XXX,XX +XXX,XX @@ int qemu_ram_resize(RAMBlock *block, ram_addr_t newsize, Error **errp)
43
* Otherwise no-op.
44
* @Note: this is supposed to be a synchronous op.
45
*/
32
*/
46
-void qemu_ram_writeback(RAMBlock *block, ram_addr_t start, ram_addr_t length)
33
unsigned long find_last_bit(const unsigned long *addr,
47
+void qemu_ram_msync(RAMBlock *block, ram_addr_t start, ram_addr_t length)
34
unsigned long size);
48
{
35
@@ -XXX,XX +XXX,XX @@ unsigned long find_last_bit(const unsigned long *addr,
49
/* The requested range should fit in within the block range */
36
* @addr: The address to base the search on
50
g_assert((start + length) <= block->used_length);
37
* @offset: The bitnumber to start searching at
51
diff --git a/memory.c b/memory.c
38
* @size: The bitmap size in bits
52
index XXXXXXX..XXXXXXX 100644
39
+ *
53
--- a/memory.c
40
+ * Returns the bit number of the next set bit,
54
+++ b/memory.c
41
+ * or @size if there are no further set bits in the bitmap.
55
@@ -XXX,XX +XXX,XX @@ void memory_region_ram_resize(MemoryRegion *mr, ram_addr_t newsize, Error **errp
42
*/
56
void memory_region_msync(MemoryRegion *mr, hwaddr addr, hwaddr size)
43
unsigned long find_next_bit(const unsigned long *addr,
57
{
44
unsigned long size,
58
if (mr->ram_block) {
45
@@ -XXX,XX +XXX,XX @@ unsigned long find_next_bit(const unsigned long *addr,
59
- qemu_ram_writeback(mr->ram_block, addr, size);
46
* @addr: The address to base the search on
60
+ qemu_ram_msync(mr->ram_block, addr, size);
47
* @offset: The bitnumber to start searching at
61
}
48
* @size: The bitmap size in bits
62
}
49
+ *
63
50
+ * Returns the bit number of the next cleared bit,
51
+ * or @size if there are no further clear bits in the bitmap.
52
*/
53
54
unsigned long find_next_zero_bit(const unsigned long *addr,
55
@@ -XXX,XX +XXX,XX @@ unsigned long find_next_zero_bit(const unsigned long *addr,
56
* @addr: The address to start the search at
57
* @size: The maximum size to search
58
*
59
- * Returns the bit number of the first set bit.
60
+ * Returns the bit number of the first set bit,
61
+ * or @size if there is no set bit in the bitmap.
62
*/
63
static inline unsigned long find_first_bit(const unsigned long *addr,
64
unsigned long size)
65
@@ -XXX,XX +XXX,XX @@ static inline unsigned long find_first_bit(const unsigned long *addr,
66
* @addr: The address to start the search at
67
* @size: The maximum size to search
68
*
69
- * Returns the bit number of the first cleared bit.
70
+ * Returns the bit number of the first cleared bit,
71
+ * or @size if there is no clear bit in the bitmap.
72
*/
73
static inline unsigned long find_first_zero_bit(const unsigned long *addr,
74
unsigned long size)
64
--
75
--
65
2.25.4
76
2.31.1
66
77
diff view generated by jsdifflib
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
2
3
We have a few bdrv_*() functions that can either spawn a new coroutine
3
The lifetime of the timer is well-known (it cannot outlive
4
and wait for it with BDRV_POLL_WHILE() or use a fastpath if they are
4
qemu_co_sleep_ns_wakeable, because it's deleted by the time the
5
alreeady running in a coroutine. All of them duplicate basically the
5
coroutine resumes), so it is not necessary to place it on the heap.
6
same code.
7
6
8
Factor the common code into a new function bdrv_run_co().
7
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
9
8
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Message-id: 20210517100548.28806-2-pbonzini@redhat.com
11
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
12
Message-id: 20200520144901.16589-1-vsementsov@virtuozzo.com
13
[Factor out bdrv_run_co_entry too]
14
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
10
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
15
---
11
---
16
block/io.c | 193 ++++++++++++++++++++---------------------------------
12
util/qemu-coroutine-sleep.c | 9 ++++-----
17
1 file changed, 72 insertions(+), 121 deletions(-)
13
1 file changed, 4 insertions(+), 5 deletions(-)
18
14
19
diff --git a/block/io.c b/block/io.c
15
diff --git a/util/qemu-coroutine-sleep.c b/util/qemu-coroutine-sleep.c
20
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
21
--- a/block/io.c
17
--- a/util/qemu-coroutine-sleep.c
22
+++ b/block/io.c
18
+++ b/util/qemu-coroutine-sleep.c
23
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ static const char *qemu_co_sleep_ns__scheduled = "qemu_co_sleep_ns";
24
#include "qemu/main-loop.h"
20
25
#include "sysemu/replay.h"
21
struct QemuCoSleepState {
26
22
Coroutine *co;
27
-#define NOT_DONE 0x7fffffff /* used while emulated sync operation in progress */
23
- QEMUTimer *ts;
28
-
24
+ QEMUTimer ts;
29
/* Maximum bounce buffer for copy-on-read and write zeroes, in bytes */
25
QemuCoSleepState **user_state_pointer;
30
#define MAX_BOUNCE_BUFFER (32768 << BDRV_SECTOR_BITS)
26
};
31
27
32
@@ -XXX,XX +XXX,XX @@ static int bdrv_check_byte_request(BlockDriverState *bs, int64_t offset,
28
@@ -XXX,XX +XXX,XX @@ void qemu_co_sleep_wake(QemuCoSleepState *sleep_state)
33
return 0;
29
if (sleep_state->user_state_pointer) {
30
*sleep_state->user_state_pointer = NULL;
31
}
32
- timer_del(sleep_state->ts);
33
+ timer_del(&sleep_state->ts);
34
aio_co_wake(sleep_state->co);
34
}
35
}
35
36
36
+typedef int coroutine_fn BdrvRequestEntry(void *opaque);
37
@@ -XXX,XX +XXX,XX @@ void coroutine_fn qemu_co_sleep_ns_wakeable(QEMUClockType type, int64_t ns,
37
+typedef struct BdrvRunCo {
38
AioContext *ctx = qemu_get_current_aio_context();
38
+ BdrvRequestEntry *entry;
39
QemuCoSleepState state = {
39
+ void *opaque;
40
.co = qemu_coroutine_self(),
40
+ int ret;
41
- .ts = aio_timer_new(ctx, type, SCALE_NS, co_sleep_cb, &state),
41
+ bool done;
42
.user_state_pointer = sleep_state,
42
+ Coroutine *co; /* Coroutine, running bdrv_run_co_entry, for debugging */
43
};
43
+} BdrvRunCo;
44
44
+
45
@@ -XXX,XX +XXX,XX @@ void coroutine_fn qemu_co_sleep_ns_wakeable(QEMUClockType type, int64_t ns,
45
+static void coroutine_fn bdrv_run_co_entry(void *opaque)
46
abort();
46
+{
47
+ BdrvRunCo *arg = opaque;
48
+
49
+ arg->ret = arg->entry(arg->opaque);
50
+ arg->done = true;
51
+ aio_wait_kick();
52
+}
53
+
54
+static int bdrv_run_co(BlockDriverState *bs, BdrvRequestEntry *entry,
55
+ void *opaque)
56
+{
57
+ if (qemu_in_coroutine()) {
58
+ /* Fast-path if already in coroutine context */
59
+ return entry(opaque);
60
+ } else {
61
+ BdrvRunCo s = { .entry = entry, .opaque = opaque };
62
+
63
+ s.co = qemu_coroutine_create(bdrv_run_co_entry, &s);
64
+ bdrv_coroutine_enter(bs, s.co);
65
+
66
+ BDRV_POLL_WHILE(bs, !s.done);
67
+
68
+ return s.ret;
69
+ }
70
+}
71
+
72
typedef struct RwCo {
73
BdrvChild *child;
74
int64_t offset;
75
QEMUIOVector *qiov;
76
bool is_write;
77
- int ret;
78
BdrvRequestFlags flags;
79
} RwCo;
80
81
-static void coroutine_fn bdrv_rw_co_entry(void *opaque)
82
+static int coroutine_fn bdrv_rw_co_entry(void *opaque)
83
{
84
RwCo *rwco = opaque;
85
86
if (!rwco->is_write) {
87
- rwco->ret = bdrv_co_preadv(rwco->child, rwco->offset,
88
- rwco->qiov->size, rwco->qiov,
89
- rwco->flags);
90
+ return bdrv_co_preadv(rwco->child, rwco->offset,
91
+ rwco->qiov->size, rwco->qiov,
92
+ rwco->flags);
93
} else {
94
- rwco->ret = bdrv_co_pwritev(rwco->child, rwco->offset,
95
- rwco->qiov->size, rwco->qiov,
96
- rwco->flags);
97
+ return bdrv_co_pwritev(rwco->child, rwco->offset,
98
+ rwco->qiov->size, rwco->qiov,
99
+ rwco->flags);
100
}
47
}
101
- aio_wait_kick();
48
102
}
49
+ aio_timer_init(ctx, &state.ts, type, SCALE_NS, co_sleep_cb, &state);
103
50
if (sleep_state) {
104
/*
51
*sleep_state = &state;
105
@@ -XXX,XX +XXX,XX @@ static int bdrv_prwv_co(BdrvChild *child, int64_t offset,
52
}
106
QEMUIOVector *qiov, bool is_write,
53
- timer_mod(state.ts, qemu_clock_get_ns(type) + ns);
107
BdrvRequestFlags flags)
54
+ timer_mod(&state.ts, qemu_clock_get_ns(type) + ns);
108
{
55
qemu_coroutine_yield();
109
- Coroutine *co;
56
if (sleep_state) {
110
RwCo rwco = {
57
/*
111
.child = child,
58
@@ -XXX,XX +XXX,XX @@ void coroutine_fn qemu_co_sleep_ns_wakeable(QEMUClockType type, int64_t ns,
112
.offset = offset,
59
*/
113
.qiov = qiov,
60
assert(*sleep_state == NULL);
114
.is_write = is_write,
61
}
115
- .ret = NOT_DONE,
62
- timer_free(state.ts);
116
.flags = flags,
117
};
118
119
- if (qemu_in_coroutine()) {
120
- /* Fast-path if already in coroutine context */
121
- bdrv_rw_co_entry(&rwco);
122
- } else {
123
- co = qemu_coroutine_create(bdrv_rw_co_entry, &rwco);
124
- bdrv_coroutine_enter(child->bs, co);
125
- BDRV_POLL_WHILE(child->bs, rwco.ret == NOT_DONE);
126
- }
127
- return rwco.ret;
128
+ return bdrv_run_co(child->bs, bdrv_rw_co_entry, &rwco);
129
}
130
131
int bdrv_pwrite_zeroes(BdrvChild *child, int64_t offset,
132
@@ -XXX,XX +XXX,XX @@ typedef struct BdrvCoBlockStatusData {
133
int64_t *pnum;
134
int64_t *map;
135
BlockDriverState **file;
136
- int ret;
137
- bool done;
138
} BdrvCoBlockStatusData;
139
140
int coroutine_fn bdrv_co_block_status_from_file(BlockDriverState *bs,
141
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_block_status_above(BlockDriverState *bs,
142
}
143
144
/* Coroutine wrapper for bdrv_block_status_above() */
145
-static void coroutine_fn bdrv_block_status_above_co_entry(void *opaque)
146
+static int coroutine_fn bdrv_block_status_above_co_entry(void *opaque)
147
{
148
BdrvCoBlockStatusData *data = opaque;
149
150
- data->ret = bdrv_co_block_status_above(data->bs, data->base,
151
- data->want_zero,
152
- data->offset, data->bytes,
153
- data->pnum, data->map, data->file);
154
- data->done = true;
155
- aio_wait_kick();
156
+ return bdrv_co_block_status_above(data->bs, data->base,
157
+ data->want_zero,
158
+ data->offset, data->bytes,
159
+ data->pnum, data->map, data->file);
160
}
161
162
/*
163
@@ -XXX,XX +XXX,XX @@ static int bdrv_common_block_status_above(BlockDriverState *bs,
164
int64_t *map,
165
BlockDriverState **file)
166
{
167
- Coroutine *co;
168
BdrvCoBlockStatusData data = {
169
.bs = bs,
170
.base = base,
171
@@ -XXX,XX +XXX,XX @@ static int bdrv_common_block_status_above(BlockDriverState *bs,
172
.pnum = pnum,
173
.map = map,
174
.file = file,
175
- .done = false,
176
};
177
178
- if (qemu_in_coroutine()) {
179
- /* Fast-path if already in coroutine context */
180
- bdrv_block_status_above_co_entry(&data);
181
- } else {
182
- co = qemu_coroutine_create(bdrv_block_status_above_co_entry, &data);
183
- bdrv_coroutine_enter(bs, co);
184
- BDRV_POLL_WHILE(bs, !data.done);
185
- }
186
- return data.ret;
187
+ return bdrv_run_co(bs, bdrv_block_status_above_co_entry, &data);
188
}
189
190
int bdrv_block_status_above(BlockDriverState *bs, BlockDriverState *base,
191
@@ -XXX,XX +XXX,XX @@ typedef struct BdrvVmstateCo {
192
QEMUIOVector *qiov;
193
int64_t pos;
194
bool is_read;
195
- int ret;
196
} BdrvVmstateCo;
197
198
static int coroutine_fn
199
@@ -XXX,XX +XXX,XX @@ bdrv_co_rw_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos,
200
return ret;
201
}
202
203
-static void coroutine_fn bdrv_co_rw_vmstate_entry(void *opaque)
204
+static int coroutine_fn bdrv_co_rw_vmstate_entry(void *opaque)
205
{
206
BdrvVmstateCo *co = opaque;
207
- co->ret = bdrv_co_rw_vmstate(co->bs, co->qiov, co->pos, co->is_read);
208
- aio_wait_kick();
209
+
210
+ return bdrv_co_rw_vmstate(co->bs, co->qiov, co->pos, co->is_read);
211
}
212
213
static inline int
214
bdrv_rw_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos,
215
bool is_read)
216
{
217
- if (qemu_in_coroutine()) {
218
- return bdrv_co_rw_vmstate(bs, qiov, pos, is_read);
219
- } else {
220
- BdrvVmstateCo data = {
221
- .bs = bs,
222
- .qiov = qiov,
223
- .pos = pos,
224
- .is_read = is_read,
225
- .ret = -EINPROGRESS,
226
- };
227
- Coroutine *co = qemu_coroutine_create(bdrv_co_rw_vmstate_entry, &data);
228
+ BdrvVmstateCo data = {
229
+ .bs = bs,
230
+ .qiov = qiov,
231
+ .pos = pos,
232
+ .is_read = is_read,
233
+ };
234
235
- bdrv_coroutine_enter(bs, co);
236
- BDRV_POLL_WHILE(bs, data.ret == -EINPROGRESS);
237
- return data.ret;
238
- }
239
+ return bdrv_run_co(bs, bdrv_co_rw_vmstate_entry, &data);
240
}
241
242
int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
243
@@ -XXX,XX +XXX,XX @@ void bdrv_aio_cancel_async(BlockAIOCB *acb)
244
/**************************************************************/
245
/* Coroutine block device emulation */
246
247
-typedef struct FlushCo {
248
- BlockDriverState *bs;
249
- int ret;
250
-} FlushCo;
251
-
252
-
253
-static void coroutine_fn bdrv_flush_co_entry(void *opaque)
254
+static int coroutine_fn bdrv_flush_co_entry(void *opaque)
255
{
256
- FlushCo *rwco = opaque;
257
-
258
- rwco->ret = bdrv_co_flush(rwco->bs);
259
- aio_wait_kick();
260
+ return bdrv_co_flush(opaque);
261
}
262
263
int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
264
@@ -XXX,XX +XXX,XX @@ early_exit:
265
266
int bdrv_flush(BlockDriverState *bs)
267
{
268
- Coroutine *co;
269
- FlushCo flush_co = {
270
- .bs = bs,
271
- .ret = NOT_DONE,
272
- };
273
-
274
- if (qemu_in_coroutine()) {
275
- /* Fast-path if already in coroutine context */
276
- bdrv_flush_co_entry(&flush_co);
277
- } else {
278
- co = qemu_coroutine_create(bdrv_flush_co_entry, &flush_co);
279
- bdrv_coroutine_enter(bs, co);
280
- BDRV_POLL_WHILE(bs, flush_co.ret == NOT_DONE);
281
- }
282
-
283
- return flush_co.ret;
284
+ return bdrv_run_co(bs, bdrv_flush_co_entry, bs);
285
}
286
287
typedef struct DiscardCo {
288
BdrvChild *child;
289
int64_t offset;
290
int64_t bytes;
291
- int ret;
292
} DiscardCo;
293
-static void coroutine_fn bdrv_pdiscard_co_entry(void *opaque)
294
+
295
+static int coroutine_fn bdrv_pdiscard_co_entry(void *opaque)
296
{
297
DiscardCo *rwco = opaque;
298
299
- rwco->ret = bdrv_co_pdiscard(rwco->child, rwco->offset, rwco->bytes);
300
- aio_wait_kick();
301
+ return bdrv_co_pdiscard(rwco->child, rwco->offset, rwco->bytes);
302
}
303
304
int coroutine_fn bdrv_co_pdiscard(BdrvChild *child, int64_t offset,
305
@@ -XXX,XX +XXX,XX @@ out:
306
307
int bdrv_pdiscard(BdrvChild *child, int64_t offset, int64_t bytes)
308
{
309
- Coroutine *co;
310
DiscardCo rwco = {
311
.child = child,
312
.offset = offset,
313
.bytes = bytes,
314
- .ret = NOT_DONE,
315
};
316
317
- if (qemu_in_coroutine()) {
318
- /* Fast-path if already in coroutine context */
319
- bdrv_pdiscard_co_entry(&rwco);
320
- } else {
321
- co = qemu_coroutine_create(bdrv_pdiscard_co_entry, &rwco);
322
- bdrv_coroutine_enter(child->bs, co);
323
- BDRV_POLL_WHILE(child->bs, rwco.ret == NOT_DONE);
324
- }
325
-
326
- return rwco.ret;
327
+ return bdrv_run_co(child->bs, bdrv_pdiscard_co_entry, &rwco);
328
}
329
330
int bdrv_co_ioctl(BlockDriverState *bs, int req, void *buf)
331
@@ -XXX,XX +XXX,XX @@ typedef struct TruncateCo {
332
PreallocMode prealloc;
333
BdrvRequestFlags flags;
334
Error **errp;
335
- int ret;
336
} TruncateCo;
337
338
-static void coroutine_fn bdrv_truncate_co_entry(void *opaque)
339
+static int coroutine_fn bdrv_truncate_co_entry(void *opaque)
340
{
341
TruncateCo *tco = opaque;
342
- tco->ret = bdrv_co_truncate(tco->child, tco->offset, tco->exact,
343
- tco->prealloc, tco->flags, tco->errp);
344
- aio_wait_kick();
345
+
346
+ return bdrv_co_truncate(tco->child, tco->offset, tco->exact,
347
+ tco->prealloc, tco->flags, tco->errp);
348
}
349
350
int bdrv_truncate(BdrvChild *child, int64_t offset, bool exact,
351
PreallocMode prealloc, BdrvRequestFlags flags, Error **errp)
352
{
353
- Coroutine *co;
354
TruncateCo tco = {
355
.child = child,
356
.offset = offset,
357
@@ -XXX,XX +XXX,XX @@ int bdrv_truncate(BdrvChild *child, int64_t offset, bool exact,
358
.prealloc = prealloc,
359
.flags = flags,
360
.errp = errp,
361
- .ret = NOT_DONE,
362
};
363
364
- if (qemu_in_coroutine()) {
365
- /* Fast-path if already in coroutine context */
366
- bdrv_truncate_co_entry(&tco);
367
- } else {
368
- co = qemu_coroutine_create(bdrv_truncate_co_entry, &tco);
369
- bdrv_coroutine_enter(child->bs, co);
370
- BDRV_POLL_WHILE(child->bs, tco.ret == NOT_DONE);
371
- }
372
-
373
- return tco.ret;
374
+ return bdrv_run_co(child->bs, bdrv_truncate_co_entry, &tco);
375
}
63
}
376
--
64
--
377
2.25.4
65
2.31.1
378
66
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
2
3
We usually use '_do_' for internal functions. Rename
3
Simplify the code by removing conditionals. qemu_co_sleep_ns
4
memory_region_do_writeback() as memory_region_writeback().
4
can simply point the argument to an on-stack temporary.
5
5
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
7
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210517100548.28806-3-pbonzini@redhat.com
9
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
10
Message-id: 20200508062456.23344-2-philmd@redhat.com
11
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
12
---
10
---
13
include/exec/memory.h | 4 ++--
11
include/qemu/coroutine.h | 5 +++--
14
memory.c | 2 +-
12
util/qemu-coroutine-sleep.c | 18 +++++-------------
15
target/arm/helper.c | 2 +-
13
2 files changed, 8 insertions(+), 15 deletions(-)
16
3 files changed, 4 insertions(+), 4 deletions(-)
17
14
18
diff --git a/include/exec/memory.h b/include/exec/memory.h
15
diff --git a/include/qemu/coroutine.h b/include/qemu/coroutine.h
19
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
20
--- a/include/exec/memory.h
17
--- a/include/qemu/coroutine.h
21
+++ b/include/exec/memory.h
18
+++ b/include/qemu/coroutine.h
22
@@ -XXX,XX +XXX,XX @@ void *memory_region_get_ram_ptr(MemoryRegion *mr);
19
@@ -XXX,XX +XXX,XX @@ typedef struct QemuCoSleepState QemuCoSleepState;
23
void memory_region_ram_resize(MemoryRegion *mr, ram_addr_t newsize,
20
24
Error **errp);
25
/**
21
/**
26
- * memory_region_do_writeback: Trigger cache writeback or msync for
22
* Yield the coroutine for a given duration. During this yield, @sleep_state
27
+ * memory_region_writeback: Trigger cache writeback or msync for
23
- * (if not NULL) is set to an opaque pointer, which may be used for
28
* selected address range
24
+ * is set to an opaque pointer, which may be used for
29
*
25
* qemu_co_sleep_wake(). Be careful, the pointer is set back to zero when the
30
* @mr: the memory region to be updated
26
* timer fires. Don't save the obtained value to other variables and don't call
31
* @addr: the initial address of the range to be written back
27
* qemu_co_sleep_wake from another aio context.
32
* @size: the size of the range to be written back
28
@@ -XXX,XX +XXX,XX @@ void coroutine_fn qemu_co_sleep_ns_wakeable(QEMUClockType type, int64_t ns,
33
*/
29
QemuCoSleepState **sleep_state);
34
-void memory_region_do_writeback(MemoryRegion *mr, hwaddr addr, hwaddr size);
30
static inline void coroutine_fn qemu_co_sleep_ns(QEMUClockType type, int64_t ns)
35
+void memory_region_writeback(MemoryRegion *mr, hwaddr addr, hwaddr size);
31
{
32
- qemu_co_sleep_ns_wakeable(type, ns, NULL);
33
+ QemuCoSleepState *unused = NULL;
34
+ qemu_co_sleep_ns_wakeable(type, ns, &unused);
35
}
36
36
37
/**
37
/**
38
* memory_region_set_log: Turn dirty logging on or off for a region.
38
diff --git a/util/qemu-coroutine-sleep.c b/util/qemu-coroutine-sleep.c
39
diff --git a/memory.c b/memory.c
40
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
41
--- a/memory.c
40
--- a/util/qemu-coroutine-sleep.c
42
+++ b/memory.c
41
+++ b/util/qemu-coroutine-sleep.c
43
@@ -XXX,XX +XXX,XX @@ void memory_region_ram_resize(MemoryRegion *mr, ram_addr_t newsize, Error **errp
42
@@ -XXX,XX +XXX,XX @@ void qemu_co_sleep_wake(QemuCoSleepState *sleep_state)
43
qemu_co_sleep_ns__scheduled, NULL);
44
45
assert(scheduled == qemu_co_sleep_ns__scheduled);
46
- if (sleep_state->user_state_pointer) {
47
- *sleep_state->user_state_pointer = NULL;
48
- }
49
+ *sleep_state->user_state_pointer = NULL;
50
timer_del(&sleep_state->ts);
51
aio_co_wake(sleep_state->co);
44
}
52
}
45
53
@@ -XXX,XX +XXX,XX @@ void coroutine_fn qemu_co_sleep_ns_wakeable(QEMUClockType type, int64_t ns,
46
47
-void memory_region_do_writeback(MemoryRegion *mr, hwaddr addr, hwaddr size)
48
+void memory_region_writeback(MemoryRegion *mr, hwaddr addr, hwaddr size)
49
{
50
/*
51
* Might be extended case needed to cover
52
diff --git a/target/arm/helper.c b/target/arm/helper.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/target/arm/helper.c
55
+++ b/target/arm/helper.c
56
@@ -XXX,XX +XXX,XX @@ static void dccvap_writefn(CPUARMState *env, const ARMCPRegInfo *opaque,
57
mr = memory_region_from_host(haddr, &offset);
58
59
if (mr) {
60
- memory_region_do_writeback(mr, offset, dline_size);
61
+ memory_region_writeback(mr, offset, dline_size);
62
}
63
}
54
}
55
56
aio_timer_init(ctx, &state.ts, type, SCALE_NS, co_sleep_cb, &state);
57
- if (sleep_state) {
58
- *sleep_state = &state;
59
- }
60
+ *sleep_state = &state;
61
timer_mod(&state.ts, qemu_clock_get_ns(type) + ns);
62
qemu_coroutine_yield();
63
- if (sleep_state) {
64
- /*
65
- * Note that *sleep_state is cleared during qemu_co_sleep_wake
66
- * before resuming this coroutine.
67
- */
68
- assert(*sleep_state == NULL);
69
- }
70
+
71
+ /* qemu_co_sleep_wake clears *sleep_state before resuming this coroutine. */
72
+ assert(*sleep_state == NULL);
64
}
73
}
65
--
74
--
66
2.25.4
75
2.31.1
67
76
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
2
3
Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
3
All callers of qemu_co_sleep_wake are checking whether they are passing
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
4
a NULL argument inside the pointer-to-pointer: do the check in
5
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
5
qemu_co_sleep_wake itself.
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
7
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
7
As a side effect, qemu_co_sleep_wake can be called more than once and
8
Message-id: 20200508062456.23344-3-philmd@redhat.com
8
it will only wake the coroutine once; after the first time, the argument
9
will be set to NULL via *sleep_state->user_state_pointer. However, this
10
would not be safe unless co_sleep_cb keeps using the QemuCoSleepState*
11
directly, so make it go through the pointer-to-pointer instead.
12
13
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
14
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
15
Message-id: 20210517100548.28806-4-pbonzini@redhat.com
9
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
16
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
10
---
17
---
11
include/exec/memory.h | 13 ++++++++++++-
18
block/block-copy.c | 4 +---
12
memory.c | 10 ++++++++--
19
block/nbd.c | 8 ++------
13
2 files changed, 20 insertions(+), 3 deletions(-)
20
util/qemu-coroutine-sleep.c | 21 ++++++++++++---------
21
3 files changed, 15 insertions(+), 18 deletions(-)
14
22
15
diff --git a/include/exec/memory.h b/include/exec/memory.h
23
diff --git a/block/block-copy.c b/block/block-copy.c
16
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
17
--- a/include/exec/memory.h
25
--- a/block/block-copy.c
18
+++ b/include/exec/memory.h
26
+++ b/block/block-copy.c
19
@@ -XXX,XX +XXX,XX @@ void *memory_region_get_ram_ptr(MemoryRegion *mr);
27
@@ -XXX,XX +XXX,XX @@ out:
20
*/
28
21
void memory_region_ram_resize(MemoryRegion *mr, ram_addr_t newsize,
29
void block_copy_kick(BlockCopyCallState *call_state)
22
Error **errp);
30
{
23
+
31
- if (call_state->sleep_state) {
24
/**
32
- qemu_co_sleep_wake(call_state->sleep_state);
25
- * memory_region_writeback: Trigger cache writeback or msync for
33
- }
26
+ * memory_region_msync: Synchronize selected address range of
34
+ qemu_co_sleep_wake(call_state->sleep_state);
27
+ * a memory mapped region
35
}
28
+ *
36
29
+ * @mr: the memory region to be msync
37
/*
30
+ * @addr: the initial address of the range to be sync
38
diff --git a/block/nbd.c b/block/nbd.c
31
+ * @size: the size of the range to be sync
32
+ */
33
+void memory_region_msync(MemoryRegion *mr, hwaddr addr, hwaddr size);
34
+
35
+/**
36
+ * memory_region_writeback: Trigger cache writeback for
37
* selected address range
38
*
39
* @mr: the memory region to be updated
40
diff --git a/memory.c b/memory.c
41
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
42
--- a/memory.c
40
--- a/block/nbd.c
43
+++ b/memory.c
41
+++ b/block/nbd.c
44
@@ -XXX,XX +XXX,XX @@ void memory_region_ram_resize(MemoryRegion *mr, ram_addr_t newsize, Error **errp
42
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn nbd_client_co_drain_begin(BlockDriverState *bs)
45
qemu_ram_resize(mr->ram_block, newsize, errp);
43
BDRVNBDState *s = (BDRVNBDState *)bs->opaque;
44
45
s->drained = true;
46
- if (s->connection_co_sleep_ns_state) {
47
- qemu_co_sleep_wake(s->connection_co_sleep_ns_state);
48
- }
49
+ qemu_co_sleep_wake(s->connection_co_sleep_ns_state);
50
51
nbd_co_establish_connection_cancel(bs, false);
52
53
@@ -XXX,XX +XXX,XX @@ static void nbd_teardown_connection(BlockDriverState *bs)
54
55
s->state = NBD_CLIENT_QUIT;
56
if (s->connection_co) {
57
- if (s->connection_co_sleep_ns_state) {
58
- qemu_co_sleep_wake(s->connection_co_sleep_ns_state);
59
- }
60
+ qemu_co_sleep_wake(s->connection_co_sleep_ns_state);
61
nbd_co_establish_connection_cancel(bs, true);
62
}
63
if (qemu_in_coroutine()) {
64
diff --git a/util/qemu-coroutine-sleep.c b/util/qemu-coroutine-sleep.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/util/qemu-coroutine-sleep.c
67
+++ b/util/qemu-coroutine-sleep.c
68
@@ -XXX,XX +XXX,XX @@ struct QemuCoSleepState {
69
70
void qemu_co_sleep_wake(QemuCoSleepState *sleep_state)
71
{
72
- /* Write of schedule protected by barrier write in aio_co_schedule */
73
- const char *scheduled = qatomic_cmpxchg(&sleep_state->co->scheduled,
74
- qemu_co_sleep_ns__scheduled, NULL);
75
+ if (sleep_state) {
76
+ /* Write of schedule protected by barrier write in aio_co_schedule */
77
+ const char *scheduled = qatomic_cmpxchg(&sleep_state->co->scheduled,
78
+ qemu_co_sleep_ns__scheduled, NULL);
79
80
- assert(scheduled == qemu_co_sleep_ns__scheduled);
81
- *sleep_state->user_state_pointer = NULL;
82
- timer_del(&sleep_state->ts);
83
- aio_co_wake(sleep_state->co);
84
+ assert(scheduled == qemu_co_sleep_ns__scheduled);
85
+ *sleep_state->user_state_pointer = NULL;
86
+ timer_del(&sleep_state->ts);
87
+ aio_co_wake(sleep_state->co);
88
+ }
46
}
89
}
47
90
48
+void memory_region_msync(MemoryRegion *mr, hwaddr addr, hwaddr size)
91
static void co_sleep_cb(void *opaque)
49
+{
50
+ if (mr->ram_block) {
51
+ qemu_ram_writeback(mr->ram_block, addr, size);
52
+ }
53
+}
54
55
void memory_region_writeback(MemoryRegion *mr, hwaddr addr, hwaddr size)
56
{
92
{
57
@@ -XXX,XX +XXX,XX @@ void memory_region_writeback(MemoryRegion *mr, hwaddr addr, hwaddr size)
93
- qemu_co_sleep_wake(opaque);
58
* Might be extended case needed to cover
94
+ QemuCoSleepState **sleep_state = opaque;
59
* different types of memory regions
95
+ qemu_co_sleep_wake(*sleep_state);
60
*/
96
}
61
- if (mr->ram_block && mr->dirty_log_mask) {
97
62
- qemu_ram_writeback(mr->ram_block, addr, size);
98
void coroutine_fn qemu_co_sleep_ns_wakeable(QEMUClockType type, int64_t ns,
63
+ if (mr->dirty_log_mask) {
99
@@ -XXX,XX +XXX,XX @@ void coroutine_fn qemu_co_sleep_ns_wakeable(QEMUClockType type, int64_t ns,
64
+ memory_region_msync(mr, addr, size);
100
abort();
65
}
101
}
66
}
102
67
103
- aio_timer_init(ctx, &state.ts, type, SCALE_NS, co_sleep_cb, &state);
104
+ aio_timer_init(ctx, &state.ts, type, SCALE_NS, co_sleep_cb, sleep_state);
105
*sleep_state = &state;
106
timer_mod(&state.ts, qemu_clock_get_ns(type) + ns);
107
qemu_coroutine_yield();
68
--
108
--
69
2.25.4
109
2.31.1
70
110
diff view generated by jsdifflib
1
From: Stefano Garzarella <sgarzare@redhat.com>
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
2
3
In qemu_luring_poll_cb() we are not using the cqe peeked from the
3
This simplification is enabled by the previous patch. Now aio_co_wake
4
CQ ring. We are using io_uring_peek_cqe() only to see if there
4
will only be called once, therefore we do not care about a spurious
5
are cqes ready, so we can replace it with io_uring_cq_ready().
5
firing of the timer after a qemu_co_sleep_wake.
6
6
7
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
7
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
8
Message-id: 20200519134942.118178-1-sgarzare@redhat.com
8
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
9
Message-id: 20210517100548.28806-5-pbonzini@redhat.com
9
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
10
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
10
---
11
---
11
block/io_uring.c | 9 +++------
12
util/qemu-coroutine-sleep.c | 8 ++++----
12
1 file changed, 3 insertions(+), 6 deletions(-)
13
1 file changed, 4 insertions(+), 4 deletions(-)
13
14
14
diff --git a/block/io_uring.c b/block/io_uring.c
15
diff --git a/util/qemu-coroutine-sleep.c b/util/qemu-coroutine-sleep.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/block/io_uring.c
17
--- a/util/qemu-coroutine-sleep.c
17
+++ b/block/io_uring.c
18
+++ b/util/qemu-coroutine-sleep.c
18
@@ -XXX,XX +XXX,XX @@ static void qemu_luring_completion_cb(void *opaque)
19
@@ -XXX,XX +XXX,XX @@ static const char *qemu_co_sleep_ns__scheduled = "qemu_co_sleep_ns";
19
static bool qemu_luring_poll_cb(void *opaque)
20
21
struct QemuCoSleepState {
22
Coroutine *co;
23
- QEMUTimer ts;
24
QemuCoSleepState **user_state_pointer;
25
};
26
27
@@ -XXX,XX +XXX,XX @@ void qemu_co_sleep_wake(QemuCoSleepState *sleep_state)
28
29
assert(scheduled == qemu_co_sleep_ns__scheduled);
30
*sleep_state->user_state_pointer = NULL;
31
- timer_del(&sleep_state->ts);
32
aio_co_wake(sleep_state->co);
33
}
34
}
35
@@ -XXX,XX +XXX,XX @@ void coroutine_fn qemu_co_sleep_ns_wakeable(QEMUClockType type, int64_t ns,
36
QemuCoSleepState **sleep_state)
20
{
37
{
21
LuringState *s = opaque;
38
AioContext *ctx = qemu_get_current_aio_context();
22
- struct io_uring_cqe *cqes;
39
+ QEMUTimer ts;
23
40
QemuCoSleepState state = {
24
- if (io_uring_peek_cqe(&s->ring, &cqes) == 0) {
41
.co = qemu_coroutine_self(),
25
- if (cqes) {
42
.user_state_pointer = sleep_state,
26
- luring_process_completions_and_submit(s);
43
@@ -XXX,XX +XXX,XX @@ void coroutine_fn qemu_co_sleep_ns_wakeable(QEMUClockType type, int64_t ns,
27
- return true;
44
abort();
28
- }
29
+ if (io_uring_cq_ready(&s->ring)) {
30
+ luring_process_completions_and_submit(s);
31
+ return true;
32
}
45
}
33
46
34
return false;
47
- aio_timer_init(ctx, &state.ts, type, SCALE_NS, co_sleep_cb, sleep_state);
48
+ aio_timer_init(ctx, &ts, type, SCALE_NS, co_sleep_cb, sleep_state);
49
*sleep_state = &state;
50
- timer_mod(&state.ts, qemu_clock_get_ns(type) + ns);
51
+ timer_mod(&ts, qemu_clock_get_ns(type) + ns);
52
qemu_coroutine_yield();
53
+ timer_del(&ts);
54
55
/* qemu_co_sleep_wake clears *sleep_state before resuming this coroutine. */
56
assert(*sleep_state == NULL);
35
--
57
--
36
2.25.4
58
2.31.1
37
59
diff view generated by jsdifflib
Deleted patch
1
From: Alexander Bulekov <alxndr@bu.edu>
2
1
3
This allows us to keep pc-bios in executable_dir/pc-bios, rather than
4
executable_dir/../pc-bios, which is incompatible with oss-fuzz' file
5
structure.
6
7
Signed-off-by: Alexander Bulekov <alxndr@bu.edu>
8
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
9
Message-id: 20200512030133.29896-2-alxndr@bu.edu
10
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
11
---
12
include/sysemu/sysemu.h | 2 ++
13
softmmu/vl.c | 2 +-
14
tests/qtest/fuzz/fuzz.c | 15 +++++++++++++++
15
3 files changed, 18 insertions(+), 1 deletion(-)
16
17
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/sysemu/sysemu.h
20
+++ b/include/sysemu/sysemu.h
21
@@ -XXX,XX +XXX,XX @@ extern const char *qemu_name;
22
extern QemuUUID qemu_uuid;
23
extern bool qemu_uuid_set;
24
25
+void qemu_add_data_dir(const char *path);
26
+
27
void qemu_add_exit_notifier(Notifier *notify);
28
void qemu_remove_exit_notifier(Notifier *notify);
29
30
diff --git a/softmmu/vl.c b/softmmu/vl.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/softmmu/vl.c
33
+++ b/softmmu/vl.c
34
@@ -XXX,XX +XXX,XX @@ char *qemu_find_file(int type, const char *name)
35
return NULL;
36
}
37
38
-static void qemu_add_data_dir(const char *path)
39
+void qemu_add_data_dir(const char *path)
40
{
41
int i;
42
43
diff --git a/tests/qtest/fuzz/fuzz.c b/tests/qtest/fuzz/fuzz.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/tests/qtest/fuzz/fuzz.c
46
+++ b/tests/qtest/fuzz/fuzz.c
47
@@ -XXX,XX +XXX,XX @@ int LLVMFuzzerInitialize(int *argc, char ***argv, char ***envp)
48
{
49
50
char *target_name;
51
+ char *dir;
52
53
/* Initialize qgraph and modules */
54
qos_graph_init();
55
@@ -XXX,XX +XXX,XX @@ int LLVMFuzzerInitialize(int *argc, char ***argv, char ***envp)
56
target_name = strstr(**argv, "-target-");
57
if (target_name) { /* The binary name specifies the target */
58
target_name += strlen("-target-");
59
+ /*
60
+ * With oss-fuzz, the executable is kept in the root of a directory (we
61
+ * cannot assume the path). All data (including bios binaries) must be
62
+ * in the same dir, or a subdir. Thus, we cannot place the pc-bios so
63
+ * that it would be in exec_dir/../pc-bios.
64
+ * As a workaround, oss-fuzz allows us to use argv[0] to get the
65
+ * location of the executable. Using this we add exec_dir/pc-bios to
66
+ * the datadirs.
67
+ */
68
+ dir = g_build_filename(g_path_get_dirname(**argv), "pc-bios", NULL);
69
+ if (g_file_test(dir, G_FILE_TEST_IS_DIR)) {
70
+ qemu_add_data_dir(dir);
71
+ }
72
+ g_free(dir);
73
} else if (*argc > 1) { /* The target is specified as an argument */
74
target_name = (*argv)[1];
75
if (!strstr(target_name, "--fuzz-target=")) {
76
--
77
2.25.4
78
diff view generated by jsdifflib
1
From: Alexander Bulekov <alxndr@bu.edu>
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
2
3
Without this, the time since the last main-loop keeps increasing, as the
3
Right now, users of qemu_co_sleep_ns_wakeable are simply passing
4
fuzzer runs. The forked children need to handle all the "past-due"
4
a pointer to QemuCoSleepState by reference to the function. But
5
timers, slowing them down, over time. With this change, the
5
QemuCoSleepState really is just a Coroutine*; making the
6
parent/fork-server process runs the main-loop, while waiting on the
6
content of the struct public is just as efficient and lets us
7
child, ensuring that the timer events do not pile up, over time.
7
skip the user_state_pointer indirection.
8
8
9
Signed-off-by: Alexander Bulekov <alxndr@bu.edu>
9
Since the usage is changed, take the occasion to rename the
10
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
10
struct to QemuCoSleep.
11
Message-id: 20200512030133.29896-5-alxndr@bu.edu
11
12
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
13
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
14
Message-id: 20210517100548.28806-6-pbonzini@redhat.com
12
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
15
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
13
---
16
---
14
tests/qtest/fuzz/i440fx_fuzz.c | 1 +
17
include/qemu/coroutine.h | 23 +++++++++++----------
15
tests/qtest/fuzz/virtio_net_fuzz.c | 2 ++
18
block/block-copy.c | 8 ++++----
16
tests/qtest/fuzz/virtio_scsi_fuzz.c | 2 ++
19
block/nbd.c | 10 ++++-----
17
3 files changed, 5 insertions(+)
20
util/qemu-coroutine-sleep.c | 41 ++++++++++++++++---------------------
18
21
4 files changed, 39 insertions(+), 43 deletions(-)
19
diff --git a/tests/qtest/fuzz/i440fx_fuzz.c b/tests/qtest/fuzz/i440fx_fuzz.c
22
20
index XXXXXXX..XXXXXXX 100644
23
diff --git a/include/qemu/coroutine.h b/include/qemu/coroutine.h
21
--- a/tests/qtest/fuzz/i440fx_fuzz.c
24
index XXXXXXX..XXXXXXX 100644
22
+++ b/tests/qtest/fuzz/i440fx_fuzz.c
25
--- a/include/qemu/coroutine.h
23
@@ -XXX,XX +XXX,XX @@ static void i440fx_fuzz_qos_fork(QTestState *s,
26
+++ b/include/qemu/coroutine.h
24
i440fx_fuzz_qos(s, Data, Size);
27
@@ -XXX,XX +XXX,XX @@ void qemu_co_rwlock_wrlock(CoRwlock *lock);
25
_Exit(0);
28
*/
26
} else {
29
void qemu_co_rwlock_unlock(CoRwlock *lock);
27
+ flush_events(s);
30
28
wait(NULL);
31
-typedef struct QemuCoSleepState QemuCoSleepState;
32
+typedef struct QemuCoSleep {
33
+ Coroutine *to_wake;
34
+} QemuCoSleep;
35
36
/**
37
- * Yield the coroutine for a given duration. During this yield, @sleep_state
38
- * is set to an opaque pointer, which may be used for
39
- * qemu_co_sleep_wake(). Be careful, the pointer is set back to zero when the
40
- * timer fires. Don't save the obtained value to other variables and don't call
41
- * qemu_co_sleep_wake from another aio context.
42
+ * Yield the coroutine for a given duration. Initializes @w so that,
43
+ * during this yield, it can be passed to qemu_co_sleep_wake() to
44
+ * terminate the sleep.
45
*/
46
-void coroutine_fn qemu_co_sleep_ns_wakeable(QEMUClockType type, int64_t ns,
47
- QemuCoSleepState **sleep_state);
48
+void coroutine_fn qemu_co_sleep_ns_wakeable(QemuCoSleep *w,
49
+ QEMUClockType type, int64_t ns);
50
+
51
static inline void coroutine_fn qemu_co_sleep_ns(QEMUClockType type, int64_t ns)
52
{
53
- QemuCoSleepState *unused = NULL;
54
- qemu_co_sleep_ns_wakeable(type, ns, &unused);
55
+ QemuCoSleep w = { 0 };
56
+ qemu_co_sleep_ns_wakeable(&w, type, ns);
57
}
58
59
/**
60
@@ -XXX,XX +XXX,XX @@ static inline void coroutine_fn qemu_co_sleep_ns(QEMUClockType type, int64_t ns)
61
* qemu_co_sleep_ns() and should be checked to be non-NULL before calling
62
* qemu_co_sleep_wake().
63
*/
64
-void qemu_co_sleep_wake(QemuCoSleepState *sleep_state);
65
+void qemu_co_sleep_wake(QemuCoSleep *w);
66
67
/**
68
* Yield until a file descriptor becomes readable
69
diff --git a/block/block-copy.c b/block/block-copy.c
70
index XXXXXXX..XXXXXXX 100644
71
--- a/block/block-copy.c
72
+++ b/block/block-copy.c
73
@@ -XXX,XX +XXX,XX @@ typedef struct BlockCopyCallState {
74
/* State */
75
int ret;
76
bool finished;
77
- QemuCoSleepState *sleep_state;
78
+ QemuCoSleep sleep;
79
bool cancelled;
80
81
/* OUT parameters */
82
@@ -XXX,XX +XXX,XX @@ block_copy_dirty_clusters(BlockCopyCallState *call_state)
83
if (ns > 0) {
84
block_copy_task_end(task, -EAGAIN);
85
g_free(task);
86
- qemu_co_sleep_ns_wakeable(QEMU_CLOCK_REALTIME, ns,
87
- &call_state->sleep_state);
88
+ qemu_co_sleep_ns_wakeable(&call_state->sleep,
89
+ QEMU_CLOCK_REALTIME, ns);
90
continue;
91
}
92
}
93
@@ -XXX,XX +XXX,XX @@ out:
94
95
void block_copy_kick(BlockCopyCallState *call_state)
96
{
97
- qemu_co_sleep_wake(call_state->sleep_state);
98
+ qemu_co_sleep_wake(&call_state->sleep);
99
}
100
101
/*
102
diff --git a/block/nbd.c b/block/nbd.c
103
index XXXXXXX..XXXXXXX 100644
104
--- a/block/nbd.c
105
+++ b/block/nbd.c
106
@@ -XXX,XX +XXX,XX @@ typedef struct BDRVNBDState {
107
CoQueue free_sema;
108
Coroutine *connection_co;
109
Coroutine *teardown_co;
110
- QemuCoSleepState *connection_co_sleep_ns_state;
111
+ QemuCoSleep reconnect_sleep;
112
bool drained;
113
bool wait_drained_end;
114
int in_flight;
115
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn nbd_client_co_drain_begin(BlockDriverState *bs)
116
BDRVNBDState *s = (BDRVNBDState *)bs->opaque;
117
118
s->drained = true;
119
- qemu_co_sleep_wake(s->connection_co_sleep_ns_state);
120
+ qemu_co_sleep_wake(&s->reconnect_sleep);
121
122
nbd_co_establish_connection_cancel(bs, false);
123
124
@@ -XXX,XX +XXX,XX @@ static void nbd_teardown_connection(BlockDriverState *bs)
125
126
s->state = NBD_CLIENT_QUIT;
127
if (s->connection_co) {
128
- qemu_co_sleep_wake(s->connection_co_sleep_ns_state);
129
+ qemu_co_sleep_wake(&s->reconnect_sleep);
130
nbd_co_establish_connection_cancel(bs, true);
29
}
131
}
30
}
132
if (qemu_in_coroutine()) {
31
diff --git a/tests/qtest/fuzz/virtio_net_fuzz.c b/tests/qtest/fuzz/virtio_net_fuzz.c
133
@@ -XXX,XX +XXX,XX @@ static coroutine_fn void nbd_co_reconnect_loop(BDRVNBDState *s)
32
index XXXXXXX..XXXXXXX 100644
134
}
33
--- a/tests/qtest/fuzz/virtio_net_fuzz.c
135
bdrv_inc_in_flight(s->bs);
34
+++ b/tests/qtest/fuzz/virtio_net_fuzz.c
136
} else {
35
@@ -XXX,XX +XXX,XX @@ static void virtio_net_fork_fuzz(QTestState *s,
137
- qemu_co_sleep_ns_wakeable(QEMU_CLOCK_REALTIME, timeout,
36
flush_events(s);
138
- &s->connection_co_sleep_ns_state);
37
_Exit(0);
139
+ qemu_co_sleep_ns_wakeable(&s->reconnect_sleep,
38
} else {
140
+ QEMU_CLOCK_REALTIME, timeout);
39
+ flush_events(s);
141
if (s->drained) {
40
wait(NULL);
142
continue;
143
}
144
diff --git a/util/qemu-coroutine-sleep.c b/util/qemu-coroutine-sleep.c
145
index XXXXXXX..XXXXXXX 100644
146
--- a/util/qemu-coroutine-sleep.c
147
+++ b/util/qemu-coroutine-sleep.c
148
@@ -XXX,XX +XXX,XX @@
149
150
static const char *qemu_co_sleep_ns__scheduled = "qemu_co_sleep_ns";
151
152
-struct QemuCoSleepState {
153
+void qemu_co_sleep_wake(QemuCoSleep *w)
154
+{
155
Coroutine *co;
156
- QemuCoSleepState **user_state_pointer;
157
-};
158
159
-void qemu_co_sleep_wake(QemuCoSleepState *sleep_state)
160
-{
161
- if (sleep_state) {
162
+ co = w->to_wake;
163
+ w->to_wake = NULL;
164
+ if (co) {
165
/* Write of schedule protected by barrier write in aio_co_schedule */
166
- const char *scheduled = qatomic_cmpxchg(&sleep_state->co->scheduled,
167
+ const char *scheduled = qatomic_cmpxchg(&co->scheduled,
168
qemu_co_sleep_ns__scheduled, NULL);
169
170
assert(scheduled == qemu_co_sleep_ns__scheduled);
171
- *sleep_state->user_state_pointer = NULL;
172
- aio_co_wake(sleep_state->co);
173
+ aio_co_wake(co);
41
}
174
}
42
}
175
}
43
@@ -XXX,XX +XXX,XX @@ static void virtio_net_fork_fuzz_check_used(QTestState *s,
176
44
flush_events(s);
177
static void co_sleep_cb(void *opaque)
45
_Exit(0);
178
{
46
} else {
179
- QemuCoSleepState **sleep_state = opaque;
47
+ flush_events(s);
180
- qemu_co_sleep_wake(*sleep_state);
48
wait(NULL);
181
+ QemuCoSleep *w = opaque;
182
+ qemu_co_sleep_wake(w);
183
}
184
185
-void coroutine_fn qemu_co_sleep_ns_wakeable(QEMUClockType type, int64_t ns,
186
- QemuCoSleepState **sleep_state)
187
+void coroutine_fn qemu_co_sleep_ns_wakeable(QemuCoSleep *w,
188
+ QEMUClockType type, int64_t ns)
189
{
190
+ Coroutine *co = qemu_coroutine_self();
191
AioContext *ctx = qemu_get_current_aio_context();
192
QEMUTimer ts;
193
- QemuCoSleepState state = {
194
- .co = qemu_coroutine_self(),
195
- .user_state_pointer = sleep_state,
196
- };
197
198
- const char *scheduled = qatomic_cmpxchg(&state.co->scheduled, NULL,
199
- qemu_co_sleep_ns__scheduled);
200
+ const char *scheduled = qatomic_cmpxchg(&co->scheduled, NULL,
201
+ qemu_co_sleep_ns__scheduled);
202
if (scheduled) {
203
fprintf(stderr,
204
"%s: Co-routine was already scheduled in '%s'\n",
205
@@ -XXX,XX +XXX,XX @@ void coroutine_fn qemu_co_sleep_ns_wakeable(QEMUClockType type, int64_t ns,
206
abort();
49
}
207
}
50
}
208
51
diff --git a/tests/qtest/fuzz/virtio_scsi_fuzz.c b/tests/qtest/fuzz/virtio_scsi_fuzz.c
209
- aio_timer_init(ctx, &ts, type, SCALE_NS, co_sleep_cb, sleep_state);
52
index XXXXXXX..XXXXXXX 100644
210
- *sleep_state = &state;
53
--- a/tests/qtest/fuzz/virtio_scsi_fuzz.c
211
+ w->to_wake = co;
54
+++ b/tests/qtest/fuzz/virtio_scsi_fuzz.c
212
+ aio_timer_init(ctx, &ts, type, SCALE_NS, co_sleep_cb, w),
55
@@ -XXX,XX +XXX,XX @@ static void virtio_scsi_fork_fuzz(QTestState *s,
213
timer_mod(&ts, qemu_clock_get_ns(type) + ns);
56
flush_events(s);
214
qemu_coroutine_yield();
57
_Exit(0);
215
timer_del(&ts);
58
} else {
216
59
+ flush_events(s);
217
- /* qemu_co_sleep_wake clears *sleep_state before resuming this coroutine. */
60
wait(NULL);
218
- assert(*sleep_state == NULL);
61
}
219
+ /* w->to_wake is cleared before resuming this coroutine. */
62
}
220
+ assert(w->to_wake == NULL);
63
@@ -XXX,XX +XXX,XX @@ static void virtio_scsi_with_flag_fuzz(QTestState *s,
64
}
65
_Exit(0);
66
} else {
67
+ flush_events(s);
68
wait(NULL);
69
}
70
}
221
}
71
--
222
--
72
2.25.4
223
2.31.1
73
224
diff view generated by jsdifflib
1
From: Alexander Bulekov <alxndr@bu.edu>
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
2
3
Signed-off-by: Alexander Bulekov <alxndr@bu.edu>
3
Allow using QemuCoSleep to sleep forever until woken by qemu_co_sleep_wake.
4
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
4
This makes the logic of qemu_co_sleep_ns_wakeable easy to understand.
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
6
Message-id: 20200512030133.29896-3-alxndr@bu.edu
6
In the future we will introduce an API that can work even if the
7
sleep and wake happen from different threads. For now, initializing
8
w->to_wake after timer_mod is fine because the timer can only fire in
9
the same AioContext.
10
11
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
12
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
13
Message-id: 20210517100548.28806-7-pbonzini@redhat.com
7
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
14
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
8
---
15
---
9
tests/qtest/fuzz/i440fx_fuzz.c | 2 +-
16
include/qemu/coroutine.h | 5 +++++
10
1 file changed, 1 insertion(+), 1 deletion(-)
17
util/qemu-coroutine-sleep.c | 26 +++++++++++++++++++-------
18
2 files changed, 24 insertions(+), 7 deletions(-)
11
19
12
diff --git a/tests/qtest/fuzz/i440fx_fuzz.c b/tests/qtest/fuzz/i440fx_fuzz.c
20
diff --git a/include/qemu/coroutine.h b/include/qemu/coroutine.h
13
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
14
--- a/tests/qtest/fuzz/i440fx_fuzz.c
22
--- a/include/qemu/coroutine.h
15
+++ b/tests/qtest/fuzz/i440fx_fuzz.c
23
+++ b/include/qemu/coroutine.h
16
@@ -XXX,XX +XXX,XX @@ static void i440fx_fuzz_qos_fork(QTestState *s,
24
@@ -XXX,XX +XXX,XX @@ typedef struct QemuCoSleep {
25
void coroutine_fn qemu_co_sleep_ns_wakeable(QemuCoSleep *w,
26
QEMUClockType type, int64_t ns);
27
28
+/**
29
+ * Yield the coroutine until the next call to qemu_co_sleep_wake.
30
+ */
31
+void coroutine_fn qemu_co_sleep(QemuCoSleep *w);
32
+
33
static inline void coroutine_fn qemu_co_sleep_ns(QEMUClockType type, int64_t ns)
34
{
35
QemuCoSleep w = { 0 };
36
diff --git a/util/qemu-coroutine-sleep.c b/util/qemu-coroutine-sleep.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/util/qemu-coroutine-sleep.c
39
+++ b/util/qemu-coroutine-sleep.c
40
@@ -XXX,XX +XXX,XX @@ static void co_sleep_cb(void *opaque)
41
qemu_co_sleep_wake(w);
17
}
42
}
18
43
19
static const char *i440fx_qtest_argv = TARGET_NAME " -machine accel=qtest"
44
-void coroutine_fn qemu_co_sleep_ns_wakeable(QemuCoSleep *w,
20
- "-m 0 -display none";
45
- QEMUClockType type, int64_t ns)
21
+ " -m 0 -display none";
46
+void coroutine_fn qemu_co_sleep(QemuCoSleep *w)
22
static const char *i440fx_argv(FuzzTarget *t)
23
{
47
{
24
return i440fx_qtest_argv;
48
Coroutine *co = qemu_coroutine_self();
49
- AioContext *ctx = qemu_get_current_aio_context();
50
- QEMUTimer ts;
51
52
const char *scheduled = qatomic_cmpxchg(&co->scheduled, NULL,
53
qemu_co_sleep_ns__scheduled);
54
@@ -XXX,XX +XXX,XX @@ void coroutine_fn qemu_co_sleep_ns_wakeable(QemuCoSleep *w,
55
}
56
57
w->to_wake = co;
58
- aio_timer_init(ctx, &ts, type, SCALE_NS, co_sleep_cb, w),
59
- timer_mod(&ts, qemu_clock_get_ns(type) + ns);
60
qemu_coroutine_yield();
61
- timer_del(&ts);
62
63
/* w->to_wake is cleared before resuming this coroutine. */
64
assert(w->to_wake == NULL);
65
}
66
+
67
+void coroutine_fn qemu_co_sleep_ns_wakeable(QemuCoSleep *w,
68
+ QEMUClockType type, int64_t ns)
69
+{
70
+ AioContext *ctx = qemu_get_current_aio_context();
71
+ QEMUTimer ts;
72
+
73
+ aio_timer_init(ctx, &ts, type, SCALE_NS, co_sleep_cb, w);
74
+ timer_mod(&ts, qemu_clock_get_ns(type) + ns);
75
+
76
+ /*
77
+ * The timer will fire in the current AiOContext, so the callback
78
+ * must happen after qemu_co_sleep yields and there is no race
79
+ * between timer_mod and qemu_co_sleep.
80
+ */
81
+ qemu_co_sleep(w);
82
+ timer_del(&ts);
83
+}
25
--
84
--
26
2.25.4
85
2.31.1
27
86
diff view generated by jsdifflib
Deleted patch
1
From: Alexander Bulekov <alxndr@bu.edu>
2
1
3
Previously, we relied on "FuzzerTracePC*(.bss*)" to place libfuzzer's
4
fuzzer::TPC object into our contiguous shared-memory region. This does
5
not work for some libfuzzer builds, so this addition identifies the
6
region by its mangled name: *(.bss._ZN6fuzzer3TPCE);
7
8
Signed-off-by: Alexander Bulekov <alxndr@bu.edu>
9
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
10
Message-id: 20200512030133.29896-4-alxndr@bu.edu
11
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
12
---
13
tests/qtest/fuzz/fork_fuzz.ld | 5 +++++
14
1 file changed, 5 insertions(+)
15
16
diff --git a/tests/qtest/fuzz/fork_fuzz.ld b/tests/qtest/fuzz/fork_fuzz.ld
17
index XXXXXXX..XXXXXXX 100644
18
--- a/tests/qtest/fuzz/fork_fuzz.ld
19
+++ b/tests/qtest/fuzz/fork_fuzz.ld
20
@@ -XXX,XX +XXX,XX @@ SECTIONS
21
22
/* Internal Libfuzzer TracePC object which contains the ValueProfileMap */
23
FuzzerTracePC*(.bss*);
24
+ /*
25
+ * In case the above line fails, explicitly specify the (mangled) name of
26
+ * the object we care about
27
+ */
28
+ *(.bss._ZN6fuzzer3TPCE);
29
}
30
.data.fuzz_end : ALIGN(4K)
31
{
32
--
33
2.25.4
34
diff view generated by jsdifflib