1
The following changes since commit 801f3db7564dcce8a37a70833c0abe40ec19f8ce:
1
The following changes since commit 15ef89d2a1a7b93845a6b09c2ee8e1979f6eb30b:
2
2
3
Merge remote-tracking branch 'remotes/philmd/tags/kconfig-20210720' into staging (2021-07-20 19:30:28 +0100)
3
Update version for v7.0.0-rc1 release (2022-03-22 22:58:44 +0000)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
https://gitlab.com/stefanha/qemu.git tags/block-pull-request
7
https://gitlab.com/stefanha/qemu.git tags/block-pull-request
8
8
9
for you to fetch changes up to d7ddd0a1618a75b31dc308bb37365ce1da972154:
9
for you to fetch changes up to 2539eade4f689eda7e9fe45486f18334bfbafaf0:
10
10
11
linux-aio: limit the batch size using `aio-max-batch` parameter (2021-07-21 13:47:50 +0100)
11
hw: Fix misleading hexadecimal format (2022-03-24 10:38:42 +0000)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Pull request
14
Pull request
15
15
16
Stefano's performance regression fix for commit 2558cb8dd4 ("linux-aio:
16
Philippe found cases where the 0x%d format string was used, leading to
17
increasing MAX_EVENTS to a larger hardcoded value").
17
misleading output. The patches look harmless and could save people time, so I
18
think it's worth including them in 7.0.
18
19
19
----------------------------------------------------------------
20
----------------------------------------------------------------
20
21
21
Stefano Garzarella (3):
22
Philippe Mathieu-Daudé (2):
22
iothread: generalize iothread_set_param/iothread_get_param
23
block: Fix misleading hexadecimal format
23
iothread: add aio-max-batch parameter
24
hw: Fix misleading hexadecimal format
24
linux-aio: limit the batch size using `aio-max-batch` parameter
25
25
26
qapi/misc.json | 6 ++-
26
block/parallels-ext.c | 2 +-
27
qapi/qom.json | 7 +++-
27
hw/i386/sgx.c | 2 +-
28
include/block/aio.h | 12 ++++++
28
hw/i386/trace-events | 6 +++---
29
include/sysemu/iothread.h | 3 ++
29
hw/misc/trace-events | 4 ++--
30
block/linux-aio.c | 9 ++++-
30
hw/scsi/trace-events | 4 ++--
31
iothread.c | 82 ++++++++++++++++++++++++++++++++++-----
31
5 files changed, 9 insertions(+), 9 deletions(-)
32
monitor/hmp-cmds.c | 2 +
33
util/aio-posix.c | 12 ++++++
34
util/aio-win32.c | 5 +++
35
util/async.c | 2 +
36
qemu-options.hx | 8 +++-
37
11 files changed, 134 insertions(+), 14 deletions(-)
38
32
39
--
33
--
40
2.31.1
34
2.35.1
41
35
diff view generated by jsdifflib
1
From: Stefano Garzarella <sgarzare@redhat.com>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
When there are multiple queues attached to the same AIO context,
3
"0x%u" format is very misleading, replace by "0x%x".
4
some requests may experience high latency, since in the worst case
5
the AIO engine queue is only flushed when it is full (MAX_EVENTS) or
6
there are no more queues plugged.
7
4
8
Commit 2558cb8dd4 ("linux-aio: increasing MAX_EVENTS to a larger
5
Found running:
9
hardcoded value") changed MAX_EVENTS from 128 to 1024, to increase
10
the number of in-flight requests. But this change also increased
11
the potential maximum batch to 1024 elements.
12
6
13
When there is a single queue attached to the AIO context, the issue
7
$ git grep -E '0x%[0-9]*([lL]*|" ?PRI)[dDuU]' block/
14
is mitigated from laio_io_unplug() that will flush the queue every
15
time is invoked since there can't be others queue plugged.
16
8
17
Let's use the new `aio-max-batch` IOThread parameter to mitigate
9
Inspired-by: Richard Henderson <richard.henderson@linaro.org>
18
this issue, limiting the number of requests in a batch.
10
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
19
11
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
20
We also define a default value (32): this value is obtained running
12
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
21
some benchmarks and it represents a good tradeoff between the latency
13
Reviewed-by: Denis V. Lunev <den@openvz.org>
22
increase while a request is queued and the cost of the io_submit(2)
14
Message-id: 20220323114718.58714-2-philippe.mathieu.daude@gmail.com
23
system call.
24
25
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
26
Message-id: 20210721094211.69853-4-sgarzare@redhat.com
27
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
15
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
28
---
16
---
29
block/linux-aio.c | 9 ++++++++-
17
block/parallels-ext.c | 2 +-
30
1 file changed, 8 insertions(+), 1 deletion(-)
18
1 file changed, 1 insertion(+), 1 deletion(-)
31
19
32
diff --git a/block/linux-aio.c b/block/linux-aio.c
20
diff --git a/block/parallels-ext.c b/block/parallels-ext.c
33
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
34
--- a/block/linux-aio.c
22
--- a/block/parallels-ext.c
35
+++ b/block/linux-aio.c
23
+++ b/block/parallels-ext.c
36
@@ -XXX,XX +XXX,XX @@
24
@@ -XXX,XX +XXX,XX @@ static int parallels_parse_format_extension(BlockDriverState *bs,
37
*/
25
break;
38
#define MAX_EVENTS 1024
26
39
27
default:
40
+/* Maximum number of requests in a batch. (default value) */
28
- error_setg(errp, "Unknown feature: 0x%" PRIu64, fh.magic);
41
+#define DEFAULT_MAX_BATCH 32
29
+ error_setg(errp, "Unknown feature: 0x%" PRIx64, fh.magic);
42
+
30
goto fail;
43
struct qemu_laiocb {
31
}
44
Coroutine *co;
45
LinuxAioState *ctx;
46
@@ -XXX,XX +XXX,XX @@ static int laio_do_submit(int fd, struct qemu_laiocb *laiocb, off_t offset,
47
LinuxAioState *s = laiocb->ctx;
48
struct iocb *iocbs = &laiocb->iocb;
49
QEMUIOVector *qiov = laiocb->qiov;
50
+ int64_t max_batch = s->aio_context->aio_max_batch ?: DEFAULT_MAX_BATCH;
51
+
52
+ /* limit the batch with the number of available events */
53
+ max_batch = MIN_NON_ZERO(MAX_EVENTS - s->io_q.in_flight, max_batch);
54
55
switch (type) {
56
case QEMU_AIO_WRITE:
57
@@ -XXX,XX +XXX,XX @@ static int laio_do_submit(int fd, struct qemu_laiocb *laiocb, off_t offset,
58
s->io_q.in_queue++;
59
if (!s->io_q.blocked &&
60
(!s->io_q.plugged ||
61
- s->io_q.in_flight + s->io_q.in_queue >= MAX_EVENTS)) {
62
+ s->io_q.in_queue >= max_batch)) {
63
ioq_submit(s);
64
}
65
32
66
--
33
--
67
2.31.1
34
2.35.1
68
35
36
diff view generated by jsdifflib
1
From: Stefano Garzarella <sgarzare@redhat.com>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Changes in preparation for next patches where we add a new
3
"0x%u" format is very misleading, replace by "0x%x".
4
parameter not related to the poll mechanism.
5
4
6
Let's add two new generic functions (iothread_set_param and
5
Found running:
7
iothread_get_param) that we use to set and get IOThread
8
parameters.
9
6
10
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
7
$ git grep -E '0x%[0-9]*([lL]*|" ?PRI)[dDuU]' hw/
11
Message-id: 20210721094211.69853-2-sgarzare@redhat.com
8
9
Inspired-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
12
Message-id: 20220323114718.58714-3-philippe.mathieu.daude@gmail.com
12
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
13
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
13
---
14
---
14
iothread.c | 27 +++++++++++++++++++++++----
15
hw/i386/sgx.c | 2 +-
15
1 file changed, 23 insertions(+), 4 deletions(-)
16
hw/i386/trace-events | 6 +++---
17
hw/misc/trace-events | 4 ++--
18
hw/scsi/trace-events | 4 ++--
19
4 files changed, 8 insertions(+), 8 deletions(-)
16
20
17
diff --git a/iothread.c b/iothread.c
21
diff --git a/hw/i386/sgx.c b/hw/i386/sgx.c
18
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
19
--- a/iothread.c
23
--- a/hw/i386/sgx.c
20
+++ b/iothread.c
24
+++ b/hw/i386/sgx.c
21
@@ -XXX,XX +XXX,XX @@ static PollParamInfo poll_shrink_info = {
25
@@ -XXX,XX +XXX,XX @@ void pc_machine_init_sgx_epc(PCMachineState *pcms)
22
"poll-shrink", offsetof(IOThread, poll_shrink),
23
};
24
25
-static void iothread_get_poll_param(Object *obj, Visitor *v,
26
+static void iothread_get_param(Object *obj, Visitor *v,
27
const char *name, void *opaque, Error **errp)
28
{
29
IOThread *iothread = IOTHREAD(obj);
30
@@ -XXX,XX +XXX,XX @@ static void iothread_get_poll_param(Object *obj, Visitor *v,
31
visit_type_int64(v, name, field, errp);
32
}
33
34
-static void iothread_set_poll_param(Object *obj, Visitor *v,
35
+static bool iothread_set_param(Object *obj, Visitor *v,
36
const char *name, void *opaque, Error **errp)
37
{
38
IOThread *iothread = IOTHREAD(obj);
39
@@ -XXX,XX +XXX,XX @@ static void iothread_set_poll_param(Object *obj, Visitor *v,
40
int64_t value;
41
42
if (!visit_type_int64(v, name, &value, errp)) {
43
- return;
44
+ return false;
45
}
26
}
46
27
47
if (value < 0) {
28
if ((sgx_epc->base + sgx_epc->size) < sgx_epc->base) {
48
error_setg(errp, "%s value must be in range [0, %" PRId64 "]",
29
- error_report("Size of all 'sgx-epc' =0x%"PRIu64" causes EPC to wrap",
49
info->name, INT64_MAX);
30
+ error_report("Size of all 'sgx-epc' =0x%"PRIx64" causes EPC to wrap",
50
- return;
31
sgx_epc->size);
51
+ return false;
32
exit(EXIT_FAILURE);
52
}
33
}
53
34
diff --git a/hw/i386/trace-events b/hw/i386/trace-events
54
*field = value;
35
index XXXXXXX..XXXXXXX 100644
55
36
--- a/hw/i386/trace-events
56
+ return true;
37
+++ b/hw/i386/trace-events
57
+}
38
@@ -XXX,XX +XXX,XX @@ vtd_fault_disabled(void) "Fault processing disabled for context entry"
58
+
39
vtd_replay_ce_valid(const char *mode, uint8_t bus, uint8_t dev, uint8_t fn, uint16_t domain, uint64_t hi, uint64_t lo) "%s: replay valid context device %02"PRIx8":%02"PRIx8".%02"PRIx8" domain 0x%"PRIx16" hi 0x%"PRIx64" lo 0x%"PRIx64
59
+static void iothread_get_poll_param(Object *obj, Visitor *v,
40
vtd_replay_ce_invalid(uint8_t bus, uint8_t dev, uint8_t fn) "replay invalid context device %02"PRIx8":%02"PRIx8".%02"PRIx8
60
+ const char *name, void *opaque, Error **errp)
41
vtd_page_walk_level(uint64_t addr, uint32_t level, uint64_t start, uint64_t end) "walk (base=0x%"PRIx64", level=%"PRIu32") iova range 0x%"PRIx64" - 0x%"PRIx64
61
+{
42
-vtd_page_walk_one(uint16_t domain, uint64_t iova, uint64_t gpa, uint64_t mask, int perm) "domain 0x%"PRIu16" iova 0x%"PRIx64" -> gpa 0x%"PRIx64" mask 0x%"PRIx64" perm %d"
62
+
43
+vtd_page_walk_one(uint16_t domain, uint64_t iova, uint64_t gpa, uint64_t mask, int perm) "domain 0x%"PRIx16" iova 0x%"PRIx64" -> gpa 0x%"PRIx64" mask 0x%"PRIx64" perm %d"
63
+ iothread_get_param(obj, v, name, opaque, errp);
44
vtd_page_walk_one_skip_map(uint64_t iova, uint64_t mask, uint64_t translated) "iova 0x%"PRIx64" mask 0x%"PRIx64" translated 0x%"PRIx64
64
+}
45
vtd_page_walk_one_skip_unmap(uint64_t iova, uint64_t mask) "iova 0x%"PRIx64" mask 0x%"PRIx64
65
+
46
vtd_page_walk_skip_read(uint64_t iova, uint64_t next) "Page walk skip iova 0x%"PRIx64" - 0x%"PRIx64" due to unable to read"
66
+static void iothread_set_poll_param(Object *obj, Visitor *v,
47
vtd_page_walk_skip_reserve(uint64_t iova, uint64_t next) "Page walk skip iova 0x%"PRIx64" - 0x%"PRIx64" due to rsrv set"
67
+ const char *name, void *opaque, Error **errp)
48
vtd_switch_address_space(uint8_t bus, uint8_t slot, uint8_t fn, bool on) "Device %02x:%02x.%x switching address space (iommu enabled=%d)"
68
+{
49
vtd_as_unmap_whole(uint8_t bus, uint8_t slot, uint8_t fn, uint64_t iova, uint64_t size) "Device %02x:%02x.%x start 0x%"PRIx64" size 0x%"PRIx64
69
+ IOThread *iothread = IOTHREAD(obj);
50
-vtd_translate_pt(uint16_t sid, uint64_t addr) "source id 0x%"PRIu16", iova 0x%"PRIx64
70
+
51
-vtd_pt_enable_fast_path(uint16_t sid, bool success) "sid 0x%"PRIu16" %d"
71
+ if (!iothread_set_param(obj, v, name, opaque, errp)) {
52
+vtd_translate_pt(uint16_t sid, uint64_t addr) "source id 0x%"PRIx16", iova 0x%"PRIx64
72
+ return;
53
+vtd_pt_enable_fast_path(uint16_t sid, bool success) "sid 0x%"PRIx16" %d"
73
+ }
54
vtd_irq_generate(uint64_t addr, uint64_t data) "addr 0x%"PRIx64" data 0x%"PRIx64
74
+
55
vtd_reg_read(uint64_t addr, uint64_t size) "addr 0x%"PRIx64" size 0x%"PRIx64
75
if (iothread->ctx) {
56
vtd_reg_write(uint64_t addr, uint64_t size, uint64_t val) "addr 0x%"PRIx64" size 0x%"PRIx64" value 0x%"PRIx64
76
aio_context_set_poll_params(iothread->ctx,
57
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
77
iothread->poll_max_ns,
58
index XXXXXXX..XXXXXXX 100644
59
--- a/hw/misc/trace-events
60
+++ b/hw/misc/trace-events
61
@@ -XXX,XX +XXX,XX @@
62
# See docs/devel/tracing.rst for syntax documentation.
63
64
# allwinner-cpucfg.c
65
-allwinner_cpucfg_cpu_reset(uint8_t cpu_id, uint32_t reset_addr) "id %u, reset_addr 0x%" PRIu32
66
+allwinner_cpucfg_cpu_reset(uint8_t cpu_id, uint32_t reset_addr) "id %u, reset_addr 0x%" PRIx32
67
allwinner_cpucfg_read(uint64_t offset, uint64_t data, unsigned size) "offset 0x%" PRIx64 " data 0x%" PRIx64 " size %" PRIu32
68
allwinner_cpucfg_write(uint64_t offset, uint64_t data, unsigned size) "offset 0x%" PRIx64 " data 0x%" PRIx64 " size %" PRIu32
69
70
@@ -XXX,XX +XXX,XX @@ imx7_gpr_write(uint64_t offset, uint64_t value) "addr 0x%08" PRIx64 "value 0x%08
71
72
# mos6522.c
73
mos6522_set_counter(int index, unsigned int val) "T%d.counter=%d"
74
-mos6522_get_next_irq_time(uint16_t latch, int64_t d, int64_t delta) "latch=%d counter=0x%"PRId64 " delta_next=0x%"PRId64
75
+mos6522_get_next_irq_time(uint16_t latch, int64_t d, int64_t delta) "latch=%d counter=0x%"PRIx64 " delta_next=0x%"PRIx64
76
mos6522_set_sr_int(void) "set sr_int"
77
mos6522_write(uint64_t addr, const char *name, uint64_t val) "reg=0x%"PRIx64 " [%s] val=0x%"PRIx64
78
mos6522_read(uint64_t addr, const char *name, unsigned val) "reg=0x%"PRIx64 " [%s] val=0x%x"
79
diff --git a/hw/scsi/trace-events b/hw/scsi/trace-events
80
index XXXXXXX..XXXXXXX 100644
81
--- a/hw/scsi/trace-events
82
+++ b/hw/scsi/trace-events
83
@@ -XXX,XX +XXX,XX @@ lsi_bad_phase_interrupt(void) "Phase mismatch interrupt"
84
lsi_bad_selection(uint32_t id) "Selected absent target %"PRIu32
85
lsi_do_dma_unavailable(void) "DMA no data available"
86
lsi_do_dma(uint64_t addr, int len) "DMA addr=0x%"PRIx64" len=%d"
87
-lsi_queue_command(uint32_t tag) "Queueing tag=0x%"PRId32
88
+lsi_queue_command(uint32_t tag) "Queueing tag=0x%"PRIx32
89
lsi_add_msg_byte_error(void) "MSG IN data too long"
90
lsi_add_msg_byte(uint8_t data) "MSG IN 0x%02x"
91
lsi_reselect(int id) "Reselected target %d"
92
@@ -XXX,XX +XXX,XX @@ lsi_do_msgout_noop(void) "MSG: No Operation"
93
lsi_do_msgout_extended(uint8_t msg, uint8_t len) "Extended message 0x%x (len %d)"
94
lsi_do_msgout_ignored(const char *msg) "%s (ignored)"
95
lsi_do_msgout_simplequeue(uint8_t select_tag) "SIMPLE queue tag=0x%x"
96
-lsi_do_msgout_abort(uint32_t tag) "MSG: ABORT TAG tag=0x%"PRId32
97
+lsi_do_msgout_abort(uint32_t tag) "MSG: ABORT TAG tag=0x%"PRIx32
98
lsi_do_msgout_clearqueue(uint32_t tag) "MSG: CLEAR QUEUE tag=0x%"PRIx32
99
lsi_do_msgout_busdevicereset(uint32_t tag) "MSG: BUS DEVICE RESET tag=0x%"PRIx32
100
lsi_do_msgout_select(int id) "Select LUN %d"
78
--
101
--
79
2.31.1
102
2.35.1
80
103
104
diff view generated by jsdifflib
Deleted patch
1
From: Stefano Garzarella <sgarzare@redhat.com>
2
1
3
The `aio-max-batch` parameter will be propagated to AIO engines
4
and it will be used to control the maximum number of queued requests.
5
6
When there are in queue a number of requests equal to `aio-max-batch`,
7
the engine invokes the system call to forward the requests to the kernel.
8
9
This parameter allows us to control the maximum batch size to reduce
10
the latency that requests might accumulate while queued in the AIO
11
engine queue.
12
13
If `aio-max-batch` is equal to 0 (default value), the AIO engine will
14
use its default maximum batch size value.
15
16
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
17
Message-id: 20210721094211.69853-3-sgarzare@redhat.com
18
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
19
---
20
qapi/misc.json | 6 ++++-
21
qapi/qom.json | 7 ++++-
22
include/block/aio.h | 12 +++++++++
23
include/sysemu/iothread.h | 3 +++
24
iothread.c | 55 +++++++++++++++++++++++++++++++++++----
25
monitor/hmp-cmds.c | 2 ++
26
util/aio-posix.c | 12 +++++++++
27
util/aio-win32.c | 5 ++++
28
util/async.c | 2 ++
29
qemu-options.hx | 8 ++++--
30
10 files changed, 103 insertions(+), 9 deletions(-)
31
32
diff --git a/qapi/misc.json b/qapi/misc.json
33
index XXXXXXX..XXXXXXX 100644
34
--- a/qapi/misc.json
35
+++ b/qapi/misc.json
36
@@ -XXX,XX +XXX,XX @@
37
# @poll-shrink: how many ns will be removed from polling time, 0 means that
38
# it's not configured (since 2.9)
39
#
40
+# @aio-max-batch: maximum number of requests in a batch for the AIO engine,
41
+# 0 means that the engine will use its default (since 6.1)
42
+#
43
# Since: 2.0
44
##
45
{ 'struct': 'IOThreadInfo',
46
@@ -XXX,XX +XXX,XX @@
47
'thread-id': 'int',
48
'poll-max-ns': 'int',
49
'poll-grow': 'int',
50
- 'poll-shrink': 'int' } }
51
+ 'poll-shrink': 'int',
52
+ 'aio-max-batch': 'int' } }
53
54
##
55
# @query-iothreads:
56
diff --git a/qapi/qom.json b/qapi/qom.json
57
index XXXXXXX..XXXXXXX 100644
58
--- a/qapi/qom.json
59
+++ b/qapi/qom.json
60
@@ -XXX,XX +XXX,XX @@
61
# algorithm detects it is spending too long polling without
62
# encountering events. 0 selects a default behaviour (default: 0)
63
#
64
+# @aio-max-batch: maximum number of requests in a batch for the AIO engine,
65
+# 0 means that the engine will use its default
66
+# (default:0, since 6.1)
67
+#
68
# Since: 2.0
69
##
70
{ 'struct': 'IothreadProperties',
71
'data': { '*poll-max-ns': 'int',
72
'*poll-grow': 'int',
73
- '*poll-shrink': 'int' } }
74
+ '*poll-shrink': 'int',
75
+ '*aio-max-batch': 'int' } }
76
77
##
78
# @MemoryBackendProperties:
79
diff --git a/include/block/aio.h b/include/block/aio.h
80
index XXXXXXX..XXXXXXX 100644
81
--- a/include/block/aio.h
82
+++ b/include/block/aio.h
83
@@ -XXX,XX +XXX,XX @@ struct AioContext {
84
int64_t poll_grow; /* polling time growth factor */
85
int64_t poll_shrink; /* polling time shrink factor */
86
87
+ /* AIO engine parameters */
88
+ int64_t aio_max_batch; /* maximum number of requests in a batch */
89
+
90
/*
91
* List of handlers participating in userspace polling. Protected by
92
* ctx->list_lock. Iterated and modified mostly by the event loop thread
93
@@ -XXX,XX +XXX,XX @@ void aio_context_set_poll_params(AioContext *ctx, int64_t max_ns,
94
int64_t grow, int64_t shrink,
95
Error **errp);
96
97
+/**
98
+ * aio_context_set_aio_params:
99
+ * @ctx: the aio context
100
+ * @max_batch: maximum number of requests in a batch, 0 means that the
101
+ * engine will use its default
102
+ */
103
+void aio_context_set_aio_params(AioContext *ctx, int64_t max_batch,
104
+ Error **errp);
105
+
106
#endif
107
diff --git a/include/sysemu/iothread.h b/include/sysemu/iothread.h
108
index XXXXXXX..XXXXXXX 100644
109
--- a/include/sysemu/iothread.h
110
+++ b/include/sysemu/iothread.h
111
@@ -XXX,XX +XXX,XX @@ struct IOThread {
112
int64_t poll_max_ns;
113
int64_t poll_grow;
114
int64_t poll_shrink;
115
+
116
+ /* AioContext AIO engine parameters */
117
+ int64_t aio_max_batch;
118
};
119
typedef struct IOThread IOThread;
120
121
diff --git a/iothread.c b/iothread.c
122
index XXXXXXX..XXXXXXX 100644
123
--- a/iothread.c
124
+++ b/iothread.c
125
@@ -XXX,XX +XXX,XX @@ static void iothread_init_gcontext(IOThread *iothread)
126
iothread->main_loop = g_main_loop_new(iothread->worker_context, TRUE);
127
}
128
129
+static void iothread_set_aio_context_params(IOThread *iothread, Error **errp)
130
+{
131
+ ERRP_GUARD();
132
+
133
+ aio_context_set_poll_params(iothread->ctx,
134
+ iothread->poll_max_ns,
135
+ iothread->poll_grow,
136
+ iothread->poll_shrink,
137
+ errp);
138
+ if (*errp) {
139
+ return;
140
+ }
141
+
142
+ aio_context_set_aio_params(iothread->ctx,
143
+ iothread->aio_max_batch,
144
+ errp);
145
+}
146
+
147
static void iothread_complete(UserCreatable *obj, Error **errp)
148
{
149
Error *local_error = NULL;
150
@@ -XXX,XX +XXX,XX @@ static void iothread_complete(UserCreatable *obj, Error **errp)
151
*/
152
iothread_init_gcontext(iothread);
153
154
- aio_context_set_poll_params(iothread->ctx,
155
- iothread->poll_max_ns,
156
- iothread->poll_grow,
157
- iothread->poll_shrink,
158
- &local_error);
159
+ iothread_set_aio_context_params(iothread, &local_error);
160
if (local_error) {
161
error_propagate(errp, local_error);
162
aio_context_unref(iothread->ctx);
163
@@ -XXX,XX +XXX,XX @@ static PollParamInfo poll_grow_info = {
164
static PollParamInfo poll_shrink_info = {
165
"poll-shrink", offsetof(IOThread, poll_shrink),
166
};
167
+static PollParamInfo aio_max_batch_info = {
168
+ "aio-max-batch", offsetof(IOThread, aio_max_batch),
169
+};
170
171
static void iothread_get_param(Object *obj, Visitor *v,
172
const char *name, void *opaque, Error **errp)
173
@@ -XXX,XX +XXX,XX @@ static void iothread_set_poll_param(Object *obj, Visitor *v,
174
}
175
}
176
177
+static void iothread_get_aio_param(Object *obj, Visitor *v,
178
+ const char *name, void *opaque, Error **errp)
179
+{
180
+
181
+ iothread_get_param(obj, v, name, opaque, errp);
182
+}
183
+
184
+static void iothread_set_aio_param(Object *obj, Visitor *v,
185
+ const char *name, void *opaque, Error **errp)
186
+{
187
+ IOThread *iothread = IOTHREAD(obj);
188
+
189
+ if (!iothread_set_param(obj, v, name, opaque, errp)) {
190
+ return;
191
+ }
192
+
193
+ if (iothread->ctx) {
194
+ aio_context_set_aio_params(iothread->ctx,
195
+ iothread->aio_max_batch,
196
+ errp);
197
+ }
198
+}
199
+
200
static void iothread_class_init(ObjectClass *klass, void *class_data)
201
{
202
UserCreatableClass *ucc = USER_CREATABLE_CLASS(klass);
203
@@ -XXX,XX +XXX,XX @@ static void iothread_class_init(ObjectClass *klass, void *class_data)
204
iothread_get_poll_param,
205
iothread_set_poll_param,
206
NULL, &poll_shrink_info);
207
+ object_class_property_add(klass, "aio-max-batch", "int",
208
+ iothread_get_aio_param,
209
+ iothread_set_aio_param,
210
+ NULL, &aio_max_batch_info);
211
}
212
213
static const TypeInfo iothread_info = {
214
@@ -XXX,XX +XXX,XX @@ static int query_one_iothread(Object *object, void *opaque)
215
info->poll_max_ns = iothread->poll_max_ns;
216
info->poll_grow = iothread->poll_grow;
217
info->poll_shrink = iothread->poll_shrink;
218
+ info->aio_max_batch = iothread->aio_max_batch;
219
220
QAPI_LIST_APPEND(*tail, info);
221
return 0;
222
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
223
index XXXXXXX..XXXXXXX 100644
224
--- a/monitor/hmp-cmds.c
225
+++ b/monitor/hmp-cmds.c
226
@@ -XXX,XX +XXX,XX @@ void hmp_info_iothreads(Monitor *mon, const QDict *qdict)
227
monitor_printf(mon, " poll-max-ns=%" PRId64 "\n", value->poll_max_ns);
228
monitor_printf(mon, " poll-grow=%" PRId64 "\n", value->poll_grow);
229
monitor_printf(mon, " poll-shrink=%" PRId64 "\n", value->poll_shrink);
230
+ monitor_printf(mon, " aio-max-batch=%" PRId64 "\n",
231
+ value->aio_max_batch);
232
}
233
234
qapi_free_IOThreadInfoList(info_list);
235
diff --git a/util/aio-posix.c b/util/aio-posix.c
236
index XXXXXXX..XXXXXXX 100644
237
--- a/util/aio-posix.c
238
+++ b/util/aio-posix.c
239
@@ -XXX,XX +XXX,XX @@ void aio_context_set_poll_params(AioContext *ctx, int64_t max_ns,
240
241
aio_notify(ctx);
242
}
243
+
244
+void aio_context_set_aio_params(AioContext *ctx, int64_t max_batch,
245
+ Error **errp)
246
+{
247
+ /*
248
+ * No thread synchronization here, it doesn't matter if an incorrect value
249
+ * is used once.
250
+ */
251
+ ctx->aio_max_batch = max_batch;
252
+
253
+ aio_notify(ctx);
254
+}
255
diff --git a/util/aio-win32.c b/util/aio-win32.c
256
index XXXXXXX..XXXXXXX 100644
257
--- a/util/aio-win32.c
258
+++ b/util/aio-win32.c
259
@@ -XXX,XX +XXX,XX @@ void aio_context_set_poll_params(AioContext *ctx, int64_t max_ns,
260
error_setg(errp, "AioContext polling is not implemented on Windows");
261
}
262
}
263
+
264
+void aio_context_set_aio_params(AioContext *ctx, int64_t max_batch,
265
+ Error **errp)
266
+{
267
+}
268
diff --git a/util/async.c b/util/async.c
269
index XXXXXXX..XXXXXXX 100644
270
--- a/util/async.c
271
+++ b/util/async.c
272
@@ -XXX,XX +XXX,XX @@ AioContext *aio_context_new(Error **errp)
273
ctx->poll_grow = 0;
274
ctx->poll_shrink = 0;
275
276
+ ctx->aio_max_batch = 0;
277
+
278
return ctx;
279
fail:
280
g_source_destroy(&ctx->source);
281
diff --git a/qemu-options.hx b/qemu-options.hx
282
index XXXXXXX..XXXXXXX 100644
283
--- a/qemu-options.hx
284
+++ b/qemu-options.hx
285
@@ -XXX,XX +XXX,XX @@ SRST
286
287
CN=laptop.example.com,O=Example Home,L=London,ST=London,C=GB
288
289
- ``-object iothread,id=id,poll-max-ns=poll-max-ns,poll-grow=poll-grow,poll-shrink=poll-shrink``
290
+ ``-object iothread,id=id,poll-max-ns=poll-max-ns,poll-grow=poll-grow,poll-shrink=poll-shrink,aio-max-batch=aio-max-batch``
291
Creates a dedicated event loop thread that devices can be
292
assigned to. This is known as an IOThread. By default device
293
emulation happens in vCPU threads or the main event loop thread.
294
@@ -XXX,XX +XXX,XX @@ SRST
295
the polling time when the algorithm detects it is spending too
296
long polling without encountering events.
297
298
- The polling parameters can be modified at run-time using the
299
+ The ``aio-max-batch`` parameter is the maximum number of requests
300
+ in a batch for the AIO engine, 0 means that the engine will use
301
+ its default.
302
+
303
+ The IOThread parameters can be modified at run-time using the
304
``qom-set`` command (where ``iothread1`` is the IOThread's
305
``id``):
306
307
--
308
2.31.1
309
diff view generated by jsdifflib