1
The following changes since commit e5cd695266c5709308aa95b1baae499e4b5d4544:
1
The following changes since commit 9cf289af47bcfae5c75de37d8e5d6fd23705322c:
2
2
3
Merge remote-tracking branch 'remotes/cody/tags/block-pull-request' into staging (2018-05-08 17:05:58 +0100)
3
Merge tag 'qga-pull-request' of gitlab.com:marcandre.lureau/qemu into staging (2022-05-04 03:42:49 -0700)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
git://github.com/stefanha/qemu.git 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 31be8a2a97ecba7d31a82932286489cac318e9e9:
9
for you to fetch changes up to bef2e050d6a7feb865854c65570c496ac5a8cf53:
10
10
11
block/file-posix: add x-check-page-cache=on|off option (2018-05-11 16:43:05 +0100)
11
util/event-loop-base: Introduce options to set the thread pool size (2022-05-04 17:02:19 +0100)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Block pull request
14
Pull request
15
15
16
* Support -drive cache.direct=off live migration for POSIX files
16
Add new thread-pool-min/thread-pool-max parameters to control the thread pool
17
used for async I/O.
17
18
18
----------------------------------------------------------------
19
----------------------------------------------------------------
19
20
20
Joe Perches (4):
21
Nicolas Saenz Julienne (3):
21
checkpatch: add a --strict check for utf-8 in commit logs
22
Introduce event-loop-base abstract class
22
checkpatch: ignore email headers better
23
util/main-loop: Introduce the main loop into QOM
23
checkpatch: emit a warning on file add/move/delete
24
util/event-loop-base: Introduce options to set the thread pool size
24
checkpatch: reduce MAINTAINERS update message frequency
25
25
26
Pasi Savanainen (1):
26
qapi/qom.json | 43 ++++++++--
27
checkpatch: check utf-8 content from a commit log when it's missing
27
meson.build | 26 +++---
28
from charset
28
include/block/aio.h | 10 +++
29
29
include/block/thread-pool.h | 3 +
30
Stefan Hajnoczi (3):
30
include/qemu/main-loop.h | 10 +++
31
blockjob: drop block_job_pause/resume_all()
31
include/sysemu/event-loop-base.h | 41 +++++++++
32
block/file-posix: implement bdrv_co_invalidate_cache() on Linux
32
include/sysemu/iothread.h | 6 +-
33
block/file-posix: add x-check-page-cache=on|off option
33
event-loop-base.c | 140 +++++++++++++++++++++++++++++++
34
34
iothread.c | 68 +++++----------
35
qapi/block-core.json | 7 +-
35
util/aio-posix.c | 1 +
36
include/block/blockjob_int.h | 14 ----
36
util/async.c | 20 +++++
37
block/file-posix.c | 146 ++++++++++++++++++++++++++++++++++-
37
util/main-loop.c | 65 ++++++++++++++
38
blockjob.c | 27 -------
38
util/thread-pool.c | 55 +++++++++++-
39
scripts/checkpatch.pl | 56 +++++++++++++-
39
13 files changed, 419 insertions(+), 69 deletions(-)
40
5 files changed, 202 insertions(+), 48 deletions(-)
40
create mode 100644 include/sysemu/event-loop-base.h
41
create mode 100644 event-loop-base.c
41
42
42
--
43
--
43
2.17.0
44
2.35.1
44
45
diff view generated by jsdifflib
1
mincore(2) checks whether pages are resident. Use it to verify that
1
From: Nicolas Saenz Julienne <nsaenzju@redhat.com>
2
page cache has been dropped.
2
3
3
Introduce the 'event-loop-base' abstract class, it'll hold the
4
You can trigger a verification failure by mmapping the image file from
4
properties common to all event loops and provide the necessary hooks for
5
another process that loads a byte from a page, forcing it to become
5
their creation and maintenance. Then have iothread inherit from it.
6
resident. bdrv_co_invalidate_cache() will fail while that process is
6
7
alive.
7
EventLoopBaseClass is defined as user creatable and provides a hook for
8
8
its children to attach themselves to the user creatable class 'complete'
9
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
9
function. It also provides an update_params() callback to propagate
10
Reviewed-by: Fam Zheng <famz@redhat.com>
10
property changes onto its children.
11
Message-id: 20180427162312.18583-3-stefanha@redhat.com
11
12
The new 'event-loop-base' class will live in the root directory. It is
13
built on its own using the 'link_whole' option (there are no direct
14
function dependencies between the class and its children, it all happens
15
trough 'constructor' magic). And also imposes new compilation
16
dependencies:
17
18
qom <- event-loop-base <- blockdev (iothread.c)
19
20
And in subsequent patches:
21
22
qom <- event-loop-base <- qemuutil (util/main-loop.c)
23
24
All this forced some amount of reordering in meson.build:
25
26
- Moved qom build definition before qemuutil. Doing it the other way
27
around (i.e. moving qemuutil after qom) isn't possible as a lot of
28
core libraries that live in between the two depend on it.
29
30
- Process the 'hw' subdir earlier, as it introduces files into the
31
'qom' source set.
32
33
No functional changes intended.
34
35
Signed-off-by: Nicolas Saenz Julienne <nsaenzju@redhat.com>
36
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
37
Acked-by: Markus Armbruster <armbru@redhat.com>
38
Message-id: 20220425075723.20019-2-nsaenzju@redhat.com
12
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
39
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
13
---
40
---
14
qapi/block-core.json | 7 ++-
41
qapi/qom.json | 22 +++++--
15
block/file-posix.c | 100 ++++++++++++++++++++++++++++++++++++++++++-
42
meson.build | 23 ++++---
16
2 files changed, 104 insertions(+), 3 deletions(-)
43
include/sysemu/event-loop-base.h | 36 +++++++++++
17
44
include/sysemu/iothread.h | 6 +-
18
diff --git a/qapi/block-core.json b/qapi/block-core.json
45
event-loop-base.c | 104 +++++++++++++++++++++++++++++++
46
iothread.c | 65 ++++++-------------
47
6 files changed, 192 insertions(+), 64 deletions(-)
48
create mode 100644 include/sysemu/event-loop-base.h
49
create mode 100644 event-loop-base.c
50
51
diff --git a/qapi/qom.json b/qapi/qom.json
19
index XXXXXXX..XXXXXXX 100644
52
index XXXXXXX..XXXXXXX 100644
20
--- a/qapi/block-core.json
53
--- a/qapi/qom.json
21
+++ b/qapi/block-core.json
54
+++ b/qapi/qom.json
22
@@ -XXX,XX +XXX,XX @@
55
@@ -XXX,XX +XXX,XX @@
23
# @locking: whether to enable file locking. If set to 'auto', only enable
56
'*repeat': 'bool',
24
# when Open File Descriptor (OFD) locking API is available
57
'*grab-toggle': 'GrabToggleKeys' } }
25
# (default: auto, since 2.10)
58
26
+# @x-check-cache-dropped: whether to check that page cache was dropped on live
59
+##
27
+# migration. May cause noticeable delays if the image
60
+# @EventLoopBaseProperties:
28
+# file is large, do not use in production.
61
+#
29
+# (default: off) (since: 2.13)
62
+# Common properties for event loops
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)
67
+#
68
+# Since: 7.1
69
+##
70
+{ 'struct': 'EventLoopBaseProperties',
71
+ 'data': { '*aio-max-batch': 'int' } }
72
+
73
##
74
# @IothreadProperties:
30
#
75
#
31
# Since: 2.9
76
@@ -XXX,XX +XXX,XX @@
77
# algorithm detects it is spending too long polling without
78
# encountering events. 0 selects a default behaviour (default: 0)
79
#
80
-# @aio-max-batch: maximum number of requests in a batch for the AIO engine,
81
-# 0 means that the engine will use its default
82
-# (default:0, since 6.1)
83
+# The @aio-max-batch option is available since 6.1.
84
#
85
# Since: 2.0
32
##
86
##
33
@@ -XXX,XX +XXX,XX @@
87
{ 'struct': 'IothreadProperties',
34
'data': { 'filename': 'str',
88
+ 'base': 'EventLoopBaseProperties',
35
'*pr-manager': 'str',
89
'data': { '*poll-max-ns': 'int',
36
'*locking': 'OnOffAuto',
90
'*poll-grow': 'int',
37
- '*aio': 'BlockdevAioOptions' } }
91
- '*poll-shrink': 'int',
38
+ '*aio': 'BlockdevAioOptions',
92
- '*aio-max-batch': 'int' } }
39
+ '*x-check-cache-dropped': 'bool' } }
93
+ '*poll-shrink': 'int' } }
40
94
41
##
95
##
42
# @BlockdevOptionsNull:
96
# @MemoryBackendProperties:
43
diff --git a/block/file-posix.c b/block/file-posix.c
97
diff --git a/meson.build b/meson.build
44
index XXXXXXX..XXXXXXX 100644
98
index XXXXXXX..XXXXXXX 100644
45
--- a/block/file-posix.c
99
--- a/meson.build
46
+++ b/block/file-posix.c
100
+++ b/meson.build
47
@@ -XXX,XX +XXX,XX @@ typedef struct BDRVRawState {
101
@@ -XXX,XX +XXX,XX @@ subdir('qom')
48
bool page_cache_inconsistent:1;
102
subdir('authz')
49
bool has_fallocate;
103
subdir('crypto')
50
bool needs_alignment;
104
subdir('ui')
51
+ bool check_cache_dropped;
105
+subdir('hw')
52
106
53
PRManager *pr_mgr;
107
54
} BDRVRawState;
108
if enable_modules
55
@@ -XXX,XX +XXX,XX @@ typedef struct BDRVRawState {
109
@@ -XXX,XX +XXX,XX @@ if enable_modules
56
typedef struct BDRVRawReopenState {
110
modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
57
int fd;
111
endif
58
int open_flags;
112
59
+ bool check_cache_dropped;
113
+qom_ss = qom_ss.apply(config_host, strict: false)
60
} BDRVRawReopenState;
114
+libqom = static_library('qom', qom_ss.sources() + genh,
61
115
+ dependencies: [qom_ss.dependencies()],
62
static int fd_open(BlockDriverState *bs);
116
+ name_suffix: 'fa')
63
@@ -XXX,XX +XXX,XX @@ static QemuOptsList raw_runtime_opts = {
117
+qom = declare_dependency(link_whole: libqom)
64
.type = QEMU_OPT_STRING,
118
+
65
.help = "id of persistent reservation manager object (default: none)",
119
+event_loop_base = files('event-loop-base.c')
66
},
120
+event_loop_base = static_library('event-loop-base', sources: event_loop_base + genh,
67
+ {
121
+ build_by_default: true)
68
+ .name = "x-check-cache-dropped",
122
+event_loop_base = declare_dependency(link_whole: event_loop_base,
69
+ .type = QEMU_OPT_BOOL,
123
+ dependencies: [qom])
70
+ .help = "check that page cache was dropped on live migration (default: off)"
124
+
71
+ },
125
stub_ss = stub_ss.apply(config_all, strict: false)
72
{ /* end of list */ }
126
73
},
127
util_ss.add_all(trace_ss)
128
@@ -XXX,XX +XXX,XX @@ subdir('monitor')
129
subdir('net')
130
subdir('replay')
131
subdir('semihosting')
132
-subdir('hw')
133
subdir('tcg')
134
subdir('fpu')
135
subdir('accel')
136
@@ -XXX,XX +XXX,XX @@ qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
137
capture: true,
138
command: [undefsym, nm, '@INPUT@'])
139
140
-qom_ss = qom_ss.apply(config_host, strict: false)
141
-libqom = static_library('qom', qom_ss.sources() + genh,
142
- dependencies: [qom_ss.dependencies()],
143
- name_suffix: 'fa')
144
-
145
-qom = declare_dependency(link_whole: libqom)
146
-
147
authz_ss = authz_ss.apply(config_host, strict: false)
148
libauthz = static_library('authz', authz_ss.sources() + genh,
149
dependencies: [authz_ss.dependencies()],
150
@@ -XXX,XX +XXX,XX @@ libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
151
build_by_default: false)
152
153
blockdev = declare_dependency(link_whole: [libblockdev],
154
- dependencies: [block])
155
+ dependencies: [block, event_loop_base])
156
157
qmp_ss = qmp_ss.apply(config_host, strict: false)
158
libqmp = static_library('qmp', qmp_ss.sources() + genh,
159
diff --git a/include/sysemu/event-loop-base.h b/include/sysemu/event-loop-base.h
160
new file mode 100644
161
index XXXXXXX..XXXXXXX
162
--- /dev/null
163
+++ b/include/sysemu/event-loop-base.h
164
@@ -XXX,XX +XXX,XX @@
165
+/*
166
+ * QEMU event-loop backend
167
+ *
168
+ * Copyright (C) 2022 Red Hat Inc
169
+ *
170
+ * Authors:
171
+ * Nicolas Saenz Julienne <nsaenzju@redhat.com>
172
+ *
173
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
174
+ * See the COPYING file in the top-level directory.
175
+ */
176
+#ifndef QEMU_EVENT_LOOP_BASE_H
177
+#define QEMU_EVENT_LOOP_BASE_H
178
+
179
+#include "qom/object.h"
180
+#include "block/aio.h"
181
+#include "qemu/typedefs.h"
182
+
183
+#define TYPE_EVENT_LOOP_BASE "event-loop-base"
184
+OBJECT_DECLARE_TYPE(EventLoopBase, EventLoopBaseClass,
185
+ EVENT_LOOP_BASE)
186
+
187
+struct EventLoopBaseClass {
188
+ ObjectClass parent_class;
189
+
190
+ void (*init)(EventLoopBase *base, Error **errp);
191
+ void (*update_params)(EventLoopBase *base, Error **errp);
192
+};
193
+
194
+struct EventLoopBase {
195
+ Object parent;
196
+
197
+ /* AioContext AIO engine parameters */
198
+ int64_t aio_max_batch;
199
+};
200
+#endif
201
diff --git a/include/sysemu/iothread.h b/include/sysemu/iothread.h
202
index XXXXXXX..XXXXXXX 100644
203
--- a/include/sysemu/iothread.h
204
+++ b/include/sysemu/iothread.h
205
@@ -XXX,XX +XXX,XX @@
206
#include "block/aio.h"
207
#include "qemu/thread.h"
208
#include "qom/object.h"
209
+#include "sysemu/event-loop-base.h"
210
211
#define TYPE_IOTHREAD "iothread"
212
213
struct IOThread {
214
- Object parent_obj;
215
+ EventLoopBase parent_obj;
216
217
QemuThread thread;
218
AioContext *ctx;
219
@@ -XXX,XX +XXX,XX @@ struct IOThread {
220
int64_t poll_max_ns;
221
int64_t poll_grow;
222
int64_t poll_shrink;
223
-
224
- /* AioContext AIO engine parameters */
225
- int64_t aio_max_batch;
74
};
226
};
75
@@ -XXX,XX +XXX,XX @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
227
typedef struct IOThread IOThread;
76
}
228
229
diff --git a/event-loop-base.c b/event-loop-base.c
230
new file mode 100644
231
index XXXXXXX..XXXXXXX
232
--- /dev/null
233
+++ b/event-loop-base.c
234
@@ -XXX,XX +XXX,XX @@
235
+/*
236
+ * QEMU event-loop base
237
+ *
238
+ * Copyright (C) 2022 Red Hat Inc
239
+ *
240
+ * Authors:
241
+ * Stefan Hajnoczi <stefanha@redhat.com>
242
+ * Nicolas Saenz Julienne <nsaenzju@redhat.com>
243
+ *
244
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
245
+ * See the COPYING file in the top-level directory.
246
+ */
247
+
248
+#include "qemu/osdep.h"
249
+#include "qom/object_interfaces.h"
250
+#include "qapi/error.h"
251
+#include "sysemu/event-loop-base.h"
252
+
253
+typedef struct {
254
+ const char *name;
255
+ ptrdiff_t offset; /* field's byte offset in EventLoopBase struct */
256
+} EventLoopBaseParamInfo;
257
+
258
+static EventLoopBaseParamInfo aio_max_batch_info = {
259
+ "aio-max-batch", offsetof(EventLoopBase, aio_max_batch),
260
+};
261
+
262
+static void event_loop_base_get_param(Object *obj, Visitor *v,
263
+ const char *name, void *opaque, Error **errp)
264
+{
265
+ EventLoopBase *event_loop_base = EVENT_LOOP_BASE(obj);
266
+ EventLoopBaseParamInfo *info = opaque;
267
+ int64_t *field = (void *)event_loop_base + info->offset;
268
+
269
+ visit_type_int64(v, name, field, errp);
270
+}
271
+
272
+static void event_loop_base_set_param(Object *obj, Visitor *v,
273
+ const char *name, void *opaque, Error **errp)
274
+{
275
+ EventLoopBaseClass *bc = EVENT_LOOP_BASE_GET_CLASS(obj);
276
+ EventLoopBase *base = EVENT_LOOP_BASE(obj);
277
+ EventLoopBaseParamInfo *info = opaque;
278
+ int64_t *field = (void *)base + info->offset;
279
+ int64_t value;
280
+
281
+ if (!visit_type_int64(v, name, &value, errp)) {
282
+ return;
283
+ }
284
+
285
+ if (value < 0) {
286
+ error_setg(errp, "%s value must be in range [0, %" PRId64 "]",
287
+ info->name, INT64_MAX);
288
+ return;
289
+ }
290
+
291
+ *field = value;
292
+
293
+ if (bc->update_params) {
294
+ bc->update_params(base, errp);
295
+ }
296
+
297
+ return;
298
+}
299
+
300
+static void event_loop_base_complete(UserCreatable *uc, Error **errp)
301
+{
302
+ EventLoopBaseClass *bc = EVENT_LOOP_BASE_GET_CLASS(uc);
303
+ EventLoopBase *base = EVENT_LOOP_BASE(uc);
304
+
305
+ if (bc->init) {
306
+ bc->init(base, errp);
307
+ }
308
+}
309
+
310
+static void event_loop_base_class_init(ObjectClass *klass, void *class_data)
311
+{
312
+ UserCreatableClass *ucc = USER_CREATABLE_CLASS(klass);
313
+ ucc->complete = event_loop_base_complete;
314
+
315
+ object_class_property_add(klass, "aio-max-batch", "int",
316
+ event_loop_base_get_param,
317
+ event_loop_base_set_param,
318
+ NULL, &aio_max_batch_info);
319
+}
320
+
321
+static const TypeInfo event_loop_base_info = {
322
+ .name = TYPE_EVENT_LOOP_BASE,
323
+ .parent = TYPE_OBJECT,
324
+ .instance_size = sizeof(EventLoopBase),
325
+ .class_size = sizeof(EventLoopBaseClass),
326
+ .class_init = event_loop_base_class_init,
327
+ .abstract = true,
328
+ .interfaces = (InterfaceInfo[]) {
329
+ { TYPE_USER_CREATABLE },
330
+ { }
331
+ }
332
+};
333
+
334
+static void register_types(void)
335
+{
336
+ type_register_static(&event_loop_base_info);
337
+}
338
+type_init(register_types);
339
diff --git a/iothread.c b/iothread.c
340
index XXXXXXX..XXXXXXX 100644
341
--- a/iothread.c
342
+++ b/iothread.c
343
@@ -XXX,XX +XXX,XX @@
344
#include "qemu/module.h"
345
#include "block/aio.h"
346
#include "block/block.h"
347
+#include "sysemu/event-loop-base.h"
348
#include "sysemu/iothread.h"
349
#include "qapi/error.h"
350
#include "qapi/qapi-commands-misc.h"
351
@@ -XXX,XX +XXX,XX @@ static void iothread_init_gcontext(IOThread *iothread)
352
iothread->main_loop = g_main_loop_new(iothread->worker_context, TRUE);
353
}
354
355
-static void iothread_set_aio_context_params(IOThread *iothread, Error **errp)
356
+static void iothread_set_aio_context_params(EventLoopBase *base, Error **errp)
357
{
358
+ IOThread *iothread = IOTHREAD(base);
359
ERRP_GUARD();
360
361
+ if (!iothread->ctx) {
362
+ return;
363
+ }
364
+
365
aio_context_set_poll_params(iothread->ctx,
366
iothread->poll_max_ns,
367
iothread->poll_grow,
368
@@ -XXX,XX +XXX,XX @@ static void iothread_set_aio_context_params(IOThread *iothread, Error **errp)
77
}
369
}
78
370
79
+ s->check_cache_dropped = qemu_opt_get_bool(opts, "x-check-cache-dropped",
371
aio_context_set_aio_params(iothread->ctx,
80
+ false);
372
- iothread->aio_max_batch,
81
+
373
+ iothread->parent_obj.aio_max_batch,
82
s->open_flags = open_flags;
374
errp);
83
raw_parse_flags(bdrv_flags, &s->open_flags);
375
}
84
376
85
@@ -XXX,XX +XXX,XX @@ static int raw_reopen_prepare(BDRVReopenState *state,
377
-static void iothread_complete(UserCreatable *obj, Error **errp)
378
+
379
+static void iothread_init(EventLoopBase *base, Error **errp)
86
{
380
{
87
BDRVRawState *s;
381
Error *local_error = NULL;
88
BDRVRawReopenState *rs;
382
- IOThread *iothread = IOTHREAD(obj);
89
+ QemuOpts *opts;
383
+ IOThread *iothread = IOTHREAD(base);
90
int ret = 0;
384
char *thread_name;
91
Error *local_err = NULL;
385
92
386
iothread->stopping = false;
93
@@ -XXX,XX +XXX,XX @@ static int raw_reopen_prepare(BDRVReopenState *state,
387
@@ -XXX,XX +XXX,XX @@ static void iothread_complete(UserCreatable *obj, Error **errp)
94
388
*/
95
state->opaque = g_new0(BDRVRawReopenState, 1);
389
iothread_init_gcontext(iothread);
96
rs = state->opaque;
390
97
+ rs->fd = -1;
391
- iothread_set_aio_context_params(iothread, &local_error);
98
+
392
+ iothread_set_aio_context_params(base, &local_error);
99
+ /* Handle options changes */
393
if (local_error) {
100
+ opts = qemu_opts_create(&raw_runtime_opts, NULL, 0, &error_abort);
394
error_propagate(errp, local_error);
101
+ qemu_opts_absorb_qdict(opts, state->options, &local_err);
395
aio_context_unref(iothread->ctx);
102
+ if (local_err) {
396
@@ -XXX,XX +XXX,XX @@ static void iothread_complete(UserCreatable *obj, Error **errp)
103
+ error_propagate(errp, local_err);
397
* to inherit.
104
+ ret = -EINVAL;
398
*/
105
+ goto out;
399
thread_name = g_strdup_printf("IO %s",
106
+ }
400
- object_get_canonical_path_component(OBJECT(obj)));
107
+
401
+ object_get_canonical_path_component(OBJECT(base)));
108
+ rs->check_cache_dropped = qemu_opt_get_bool(opts, "x-check-cache-dropped",
402
qemu_thread_create(&iothread->thread, thread_name, iothread_run,
109
+ s->check_cache_dropped);
403
iothread, QEMU_THREAD_JOINABLE);
110
404
g_free(thread_name);
111
if (s->type == FTYPE_CD) {
405
@@ -XXX,XX +XXX,XX @@ static IOThreadParamInfo poll_grow_info = {
112
rs->open_flags |= O_NONBLOCK;
406
static IOThreadParamInfo poll_shrink_info = {
113
@@ -XXX,XX +XXX,XX @@ static int raw_reopen_prepare(BDRVReopenState *state,
407
"poll-shrink", offsetof(IOThread, poll_shrink),
114
408
};
115
raw_parse_flags(state->flags, &rs->open_flags);
409
-static IOThreadParamInfo aio_max_batch_info = {
116
410
- "aio-max-batch", offsetof(IOThread, aio_max_batch),
117
- rs->fd = -1;
411
-};
118
-
412
119
int fcntl_flags = O_APPEND | O_NONBLOCK;
413
static void iothread_get_param(Object *obj, Visitor *v,
120
#ifdef O_NOATIME
414
const char *name, IOThreadParamInfo *info, Error **errp)
121
fcntl_flags |= O_NOATIME;
415
@@ -XXX,XX +XXX,XX @@ static void iothread_set_poll_param(Object *obj, Visitor *v,
122
@@ -XXX,XX +XXX,XX @@ static int raw_reopen_prepare(BDRVReopenState *state,
123
}
124
}
416
}
125
126
+out:
127
+ qemu_opts_del(opts);
128
return ret;
129
}
417
}
130
418
131
@@ -XXX,XX +XXX,XX @@ static void raw_reopen_commit(BDRVReopenState *state)
419
-static void iothread_get_aio_param(Object *obj, Visitor *v,
132
BDRVRawReopenState *rs = state->opaque;
420
- const char *name, void *opaque, Error **errp)
133
BDRVRawState *s = state->bs->opaque;
421
-{
134
422
- IOThreadParamInfo *info = opaque;
135
+ s->check_cache_dropped = rs->check_cache_dropped;
423
-
136
s->open_flags = rs->open_flags;
424
- iothread_get_param(obj, v, name, info, errp);
137
425
-}
138
qemu_close(s->fd);
426
-
139
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_block_status(BlockDriverState *bs,
427
-static void iothread_set_aio_param(Object *obj, Visitor *v,
140
return ret | BDRV_BLOCK_OFFSET_VALID;
428
- const char *name, void *opaque, Error **errp)
429
-{
430
- IOThread *iothread = IOTHREAD(obj);
431
- IOThreadParamInfo *info = opaque;
432
-
433
- if (!iothread_set_param(obj, v, name, info, errp)) {
434
- return;
435
- }
436
-
437
- if (iothread->ctx) {
438
- aio_context_set_aio_params(iothread->ctx,
439
- iothread->aio_max_batch,
440
- errp);
441
- }
442
-}
443
-
444
static void iothread_class_init(ObjectClass *klass, void *class_data)
445
{
446
- UserCreatableClass *ucc = USER_CREATABLE_CLASS(klass);
447
- ucc->complete = iothread_complete;
448
+ EventLoopBaseClass *bc = EVENT_LOOP_BASE_CLASS(klass);
449
+
450
+ bc->init = iothread_init;
451
+ bc->update_params = iothread_set_aio_context_params;
452
453
object_class_property_add(klass, "poll-max-ns", "int",
454
iothread_get_poll_param,
455
@@ -XXX,XX +XXX,XX @@ static void iothread_class_init(ObjectClass *klass, void *class_data)
456
iothread_get_poll_param,
457
iothread_set_poll_param,
458
NULL, &poll_shrink_info);
459
- object_class_property_add(klass, "aio-max-batch", "int",
460
- iothread_get_aio_param,
461
- iothread_set_aio_param,
462
- NULL, &aio_max_batch_info);
141
}
463
}
142
464
143
+#if defined(__linux__)
465
static const TypeInfo iothread_info = {
144
+/* Verify that the file is not in the page cache */
466
.name = TYPE_IOTHREAD,
145
+static void check_cache_dropped(BlockDriverState *bs, Error **errp)
467
- .parent = TYPE_OBJECT,
146
+{
468
+ .parent = TYPE_EVENT_LOOP_BASE,
147
+ const size_t window_size = 128 * 1024 * 1024;
469
.class_init = iothread_class_init,
148
+ BDRVRawState *s = bs->opaque;
470
.instance_size = sizeof(IOThread),
149
+ void *window = NULL;
471
.instance_init = iothread_instance_init,
150
+ size_t length = 0;
472
.instance_finalize = iothread_instance_finalize,
151
+ unsigned char *vec;
473
- .interfaces = (InterfaceInfo[]) {
152
+ size_t page_size;
474
- {TYPE_USER_CREATABLE},
153
+ off_t offset;
475
- {}
154
+ off_t end;
476
- },
155
+
477
};
156
+ /* mincore(2) page status information requires 1 byte per page */
478
157
+ page_size = sysconf(_SC_PAGESIZE);
479
static void iothread_register_types(void)
158
+ vec = g_malloc(DIV_ROUND_UP(window_size, page_size));
480
@@ -XXX,XX +XXX,XX @@ static int query_one_iothread(Object *object, void *opaque)
159
+
481
info->poll_max_ns = iothread->poll_max_ns;
160
+ end = raw_getlength(bs);
482
info->poll_grow = iothread->poll_grow;
161
+
483
info->poll_shrink = iothread->poll_shrink;
162
+ for (offset = 0; offset < end; offset += window_size) {
484
- info->aio_max_batch = iothread->aio_max_batch;
163
+ void *new_window;
485
+ info->aio_max_batch = iothread->parent_obj.aio_max_batch;
164
+ size_t new_length;
486
165
+ size_t vec_end;
487
QAPI_LIST_APPEND(*tail, info);
166
+ size_t i;
488
return 0;
167
+ int ret;
168
+
169
+ /* Unmap previous window if size has changed */
170
+ new_length = MIN(end - offset, window_size);
171
+ if (new_length != length) {
172
+ munmap(window, length);
173
+ window = NULL;
174
+ length = 0;
175
+ }
176
+
177
+ new_window = mmap(window, new_length, PROT_NONE, MAP_PRIVATE,
178
+ s->fd, offset);
179
+ if (new_window == MAP_FAILED) {
180
+ error_setg_errno(errp, errno, "mmap failed");
181
+ break;
182
+ }
183
+
184
+ window = new_window;
185
+ length = new_length;
186
+
187
+ ret = mincore(window, length, vec);
188
+ if (ret < 0) {
189
+ error_setg_errno(errp, errno, "mincore failed");
190
+ break;
191
+ }
192
+
193
+ vec_end = DIV_ROUND_UP(length, page_size);
194
+ for (i = 0; i < vec_end; i++) {
195
+ if (vec[i] & 0x1) {
196
+ error_setg(errp, "page cache still in use!");
197
+ break;
198
+ }
199
+ }
200
+ }
201
+
202
+ if (window) {
203
+ munmap(window, length);
204
+ }
205
+
206
+ g_free(vec);
207
+}
208
+#endif /* __linux__ */
209
+
210
static void coroutine_fn raw_co_invalidate_cache(BlockDriverState *bs,
211
Error **errp)
212
{
213
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn raw_co_invalidate_cache(BlockDriverState *bs,
214
error_setg_errno(errp, ret, "fadvise failed");
215
return;
216
}
217
+
218
+ if (s->check_cache_dropped) {
219
+ check_cache_dropped(bs, errp);
220
+ }
221
#else /* __linux__ */
222
/* Do nothing. Live migration to a remote host with cache.direct=off is
223
* unsupported on other host operating systems. Cache consistency issues
224
--
489
--
225
2.17.0
490
2.35.1
226
227
diff view generated by jsdifflib
1
Commit 8119334918e86f45877cfc139192d54f2449a239 ("block: Don't
1
From: Nicolas Saenz Julienne <nsaenzju@redhat.com>
2
block_job_pause_all() in bdrv_drain_all()") removed the only callers of
2
3
block_job_pause/resume_all().
3
'event-loop-base' provides basic property handling for all 'AioContext'
4
4
based event loops. So let's define a new 'MainLoopClass' that inherits
5
Pausing and resuming now happens in child_job_drained_begin/end() so
5
from it. This will permit tweaking the main loop's properties through
6
it's no longer necessary to globally pause/resume jobs.
6
qapi as well as through the command line using the '-object' keyword[1].
7
7
Only one instance of 'MainLoopClass' might be created at any time.
8
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
8
9
Reviewed-by: John Snow <jsnow@redhat.com>
9
'EventLoopBaseClass' learns a new callback, 'can_be_deleted()' so as to
10
Reviewed-by: Alberto Garcia <berto@igalia.com>
10
mark 'MainLoop' as non-deletable.
11
Message-id: 20180424085240.5798-1-stefanha@redhat.com
11
12
[1] For example:
13
-object main-loop,id=main-loop,aio-max-batch=<value>
14
15
Signed-off-by: Nicolas Saenz Julienne <nsaenzju@redhat.com>
16
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
17
Acked-by: Markus Armbruster <armbru@redhat.com>
18
Message-id: 20220425075723.20019-3-nsaenzju@redhat.com
12
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
19
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
13
---
20
---
14
include/block/blockjob_int.h | 14 --------------
21
qapi/qom.json | 13 ++++++++
15
blockjob.c | 27 ---------------------------
22
meson.build | 3 +-
16
2 files changed, 41 deletions(-)
23
include/qemu/main-loop.h | 10 ++++++
17
24
include/sysemu/event-loop-base.h | 1 +
18
diff --git a/include/block/blockjob_int.h b/include/block/blockjob_int.h
25
event-loop-base.c | 13 ++++++++
19
index XXXXXXX..XXXXXXX 100644
26
util/main-loop.c | 56 ++++++++++++++++++++++++++++++++
20
--- a/include/block/blockjob_int.h
27
6 files changed, 95 insertions(+), 1 deletion(-)
21
+++ b/include/block/blockjob_int.h
28
22
@@ -XXX,XX +XXX,XX @@ void block_job_sleep_ns(BlockJob *job, int64_t ns);
29
diff --git a/qapi/qom.json b/qapi/qom.json
23
*/
30
index XXXXXXX..XXXXXXX 100644
24
void block_job_yield(BlockJob *job);
31
--- a/qapi/qom.json
25
32
+++ b/qapi/qom.json
26
-/**
33
@@ -XXX,XX +XXX,XX @@
27
- * block_job_pause_all:
34
'*poll-grow': 'int',
28
- *
35
'*poll-shrink': 'int' } }
29
- * Asynchronously pause all jobs.
36
30
- */
37
+##
31
-void block_job_pause_all(void);
38
+# @MainLoopProperties:
32
-
39
+#
33
-/**
40
+# Properties for the main-loop object.
34
- * block_job_resume_all:
41
+#
35
- *
42
+# Since: 7.1
36
- * Resume all block jobs. Must be paired with a preceding block_job_pause_all.
43
+##
37
- */
44
+{ 'struct': 'MainLoopProperties',
38
-void block_job_resume_all(void);
45
+ 'base': 'EventLoopBaseProperties',
39
-
46
+ 'data': {} }
47
+
48
##
49
# @MemoryBackendProperties:
50
#
51
@@ -XXX,XX +XXX,XX @@
52
{ 'name': 'input-linux',
53
'if': 'CONFIG_LINUX' },
54
'iothread',
55
+ 'main-loop',
56
{ 'name': 'memory-backend-epc',
57
'if': 'CONFIG_LINUX' },
58
'memory-backend-file',
59
@@ -XXX,XX +XXX,XX @@
60
'input-linux': { 'type': 'InputLinuxProperties',
61
'if': 'CONFIG_LINUX' },
62
'iothread': 'IothreadProperties',
63
+ 'main-loop': 'MainLoopProperties',
64
'memory-backend-epc': { 'type': 'MemoryBackendEpcProperties',
65
'if': 'CONFIG_LINUX' },
66
'memory-backend-file': 'MemoryBackendFileProperties',
67
diff --git a/meson.build b/meson.build
68
index XXXXXXX..XXXXXXX 100644
69
--- a/meson.build
70
+++ b/meson.build
71
@@ -XXX,XX +XXX,XX @@ libqemuutil = static_library('qemuutil',
72
sources: util_ss.sources() + stub_ss.sources() + genh,
73
dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc, pixman])
74
qemuutil = declare_dependency(link_with: libqemuutil,
75
- sources: genh + version_res)
76
+ sources: genh + version_res,
77
+ dependencies: [event_loop_base])
78
79
if have_system or have_user
80
decodetree = generator(find_program('scripts/decodetree.py'),
81
diff --git a/include/qemu/main-loop.h b/include/qemu/main-loop.h
82
index XXXXXXX..XXXXXXX 100644
83
--- a/include/qemu/main-loop.h
84
+++ b/include/qemu/main-loop.h
85
@@ -XXX,XX +XXX,XX @@
86
#define QEMU_MAIN_LOOP_H
87
88
#include "block/aio.h"
89
+#include "qom/object.h"
90
+#include "sysemu/event-loop-base.h"
91
92
#define SIG_IPI SIGUSR1
93
94
+#define TYPE_MAIN_LOOP "main-loop"
95
+OBJECT_DECLARE_TYPE(MainLoop, MainLoopClass, MAIN_LOOP)
96
+
97
+struct MainLoop {
98
+ EventLoopBase parent_obj;
99
+};
100
+typedef struct MainLoop MainLoop;
101
+
40
/**
102
/**
41
* block_job_early_fail:
103
* qemu_init_main_loop: Set up the process so that it can run the main loop.
42
* @bs: The block device.
104
*
43
diff --git a/blockjob.c b/blockjob.c
105
diff --git a/include/sysemu/event-loop-base.h b/include/sysemu/event-loop-base.h
44
index XXXXXXX..XXXXXXX 100644
106
index XXXXXXX..XXXXXXX 100644
45
--- a/blockjob.c
107
--- a/include/sysemu/event-loop-base.h
46
+++ b/blockjob.c
108
+++ b/include/sysemu/event-loop-base.h
47
@@ -XXX,XX +XXX,XX @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
109
@@ -XXX,XX +XXX,XX @@ struct EventLoopBaseClass {
48
return job;
110
49
}
111
void (*init)(EventLoopBase *base, Error **errp);
50
112
void (*update_params)(EventLoopBase *base, Error **errp);
51
-void block_job_pause_all(void)
113
+ bool (*can_be_deleted)(EventLoopBase *base);
52
-{
114
};
53
- BlockJob *job = NULL;
115
54
- while ((job = block_job_next(job))) {
116
struct EventLoopBase {
55
- AioContext *aio_context = blk_get_aio_context(job->blk);
117
diff --git a/event-loop-base.c b/event-loop-base.c
56
-
118
index XXXXXXX..XXXXXXX 100644
57
- aio_context_acquire(aio_context);
119
--- a/event-loop-base.c
58
- block_job_ref(job);
120
+++ b/event-loop-base.c
59
- block_job_pause(job);
121
@@ -XXX,XX +XXX,XX @@ static void event_loop_base_complete(UserCreatable *uc, Error **errp)
60
- aio_context_release(aio_context);
61
- }
62
-}
63
-
64
void block_job_early_fail(BlockJob *job)
65
{
66
assert(job->status == BLOCK_JOB_STATUS_CREATED);
67
@@ -XXX,XX +XXX,XX @@ void coroutine_fn block_job_pause_point(BlockJob *job)
68
}
122
}
69
}
123
}
70
124
71
-void block_job_resume_all(void)
125
+static bool event_loop_base_can_be_deleted(UserCreatable *uc)
72
-{
126
+{
73
- BlockJob *job, *next;
127
+ EventLoopBaseClass *bc = EVENT_LOOP_BASE_GET_CLASS(uc);
74
-
128
+ EventLoopBase *backend = EVENT_LOOP_BASE(uc);
75
- QLIST_FOREACH_SAFE(job, &block_jobs, job_list, next) {
129
+
76
- AioContext *aio_context = blk_get_aio_context(job->blk);
130
+ if (bc->can_be_deleted) {
77
-
131
+ return bc->can_be_deleted(backend);
78
- aio_context_acquire(aio_context);
132
+ }
79
- block_job_resume(job);
133
+
80
- block_job_unref(job);
134
+ return true;
81
- aio_context_release(aio_context);
135
+}
82
- }
136
+
83
-}
137
static void event_loop_base_class_init(ObjectClass *klass, void *class_data)
84
-
138
{
85
/*
139
UserCreatableClass *ucc = USER_CREATABLE_CLASS(klass);
86
* Conditionally enter a block_job pending a call to fn() while
140
ucc->complete = event_loop_base_complete;
87
* under the block_job_lock critical section.
141
+ ucc->can_be_deleted = event_loop_base_can_be_deleted;
142
143
object_class_property_add(klass, "aio-max-batch", "int",
144
event_loop_base_get_param,
145
diff --git a/util/main-loop.c b/util/main-loop.c
146
index XXXXXXX..XXXXXXX 100644
147
--- a/util/main-loop.c
148
+++ b/util/main-loop.c
149
@@ -XXX,XX +XXX,XX @@
150
#include "qemu/error-report.h"
151
#include "qemu/queue.h"
152
#include "qemu/compiler.h"
153
+#include "qom/object.h"
154
155
#ifndef _WIN32
156
#include <sys/wait.h>
157
@@ -XXX,XX +XXX,XX @@ int qemu_init_main_loop(Error **errp)
158
return 0;
159
}
160
161
+static void main_loop_update_params(EventLoopBase *base, Error **errp)
162
+{
163
+ if (!qemu_aio_context) {
164
+ error_setg(errp, "qemu aio context not ready");
165
+ return;
166
+ }
167
+
168
+ aio_context_set_aio_params(qemu_aio_context, base->aio_max_batch, errp);
169
+}
170
+
171
+MainLoop *mloop;
172
+
173
+static void main_loop_init(EventLoopBase *base, Error **errp)
174
+{
175
+ MainLoop *m = MAIN_LOOP(base);
176
+
177
+ if (mloop) {
178
+ error_setg(errp, "only one main-loop instance allowed");
179
+ return;
180
+ }
181
+
182
+ main_loop_update_params(base, errp);
183
+
184
+ mloop = m;
185
+ return;
186
+}
187
+
188
+static bool main_loop_can_be_deleted(EventLoopBase *base)
189
+{
190
+ return false;
191
+}
192
+
193
+static void main_loop_class_init(ObjectClass *oc, void *class_data)
194
+{
195
+ EventLoopBaseClass *bc = EVENT_LOOP_BASE_CLASS(oc);
196
+
197
+ bc->init = main_loop_init;
198
+ bc->update_params = main_loop_update_params;
199
+ bc->can_be_deleted = main_loop_can_be_deleted;
200
+}
201
+
202
+static const TypeInfo main_loop_info = {
203
+ .name = TYPE_MAIN_LOOP,
204
+ .parent = TYPE_EVENT_LOOP_BASE,
205
+ .class_init = main_loop_class_init,
206
+ .instance_size = sizeof(MainLoop),
207
+};
208
+
209
+static void main_loop_register_types(void)
210
+{
211
+ type_register_static(&main_loop_info);
212
+}
213
+
214
+type_init(main_loop_register_types)
215
+
216
static int max_priority;
217
218
#ifndef _WIN32
88
--
219
--
89
2.17.0
220
2.35.1
90
91
diff view generated by jsdifflib
Deleted patch
1
From: Joe Perches <joe@perches.com>
2
1
3
Some find using utf-8 in commit logs inappropriate.
4
5
Some patch commit logs contain unintended utf-8 characters when doing
6
things like copy/pasting compilation output.
7
8
Look for the start of any commit log by skipping initial lines that look
9
like email headers and "From: " lines.
10
11
Stop looking for utf-8 at the first signature line.
12
13
Signed-off-by: Joe Perches <joe@perches.com>
14
Reviewed-by: Markus Armbruster <armbru@redhat.com>
15
Reviewed-by: Thomas Huth <thuth@redhat.com>
16
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
17
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
18
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
19
Message-id: 20180430124651.10340-2-stefanha@redhat.com
20
Suggested-by: Andrew Morton <akpm@linux-foundation.org>
21
Cc: Andy Whitcroft <apw@shadowen.org>
22
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
23
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
24
(cherry picked from commit 15662b3e8644905032c2e26808401a487d4e90c1)
25
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
26
27
Conflicts:
28
QEMU does not have CHK(), use WARN() instead.
29
30
QEMU WARN() only takes one argument, drop the 'type' value in the
31
first argument.
32
33
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
34
---
35
scripts/checkpatch.pl | 30 ++++++++++++++++++++++++++----
36
1 file changed, 26 insertions(+), 4 deletions(-)
37
38
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
39
index XXXXXXX..XXXXXXX 100755
40
--- a/scripts/checkpatch.pl
41
+++ b/scripts/checkpatch.pl
42
@@ -XXX,XX +XXX,XX @@ our $NonptrType;
43
our $Type;
44
our $Declare;
45
46
-our $UTF8    = qr {
47
-    [\x09\x0A\x0D\x20-\x7E] # ASCII
48
-    | [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
49
+our $NON_ASCII_UTF8    = qr{
50
+    [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
51
    | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs
52
    | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
53
    | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
54
@@ -XXX,XX +XXX,XX @@ our $UTF8    = qr {
55
    | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
56
}x;
57
58
+our $UTF8    = qr{
59
+    [\x09\x0A\x0D\x20-\x7E] # ASCII
60
+    | $NON_ASCII_UTF8
61
+}x;
62
+
63
# There are still some false positives, but this catches most
64
# common cases.
65
our $typeTypedefs = qr{(?x:
66
@@ -XXX,XX +XXX,XX @@ sub process {
67
    my $signoff = 0;
68
    my $is_patch = 0;
69
70
+    my $in_header_lines = 1;
71
+    my $in_commit_log = 0;        #Scanning lines before patch
72
+
73
    our @report = ();
74
    our $cnt_lines = 0;
75
    our $cnt_error = 0;
76
@@ -XXX,XX +XXX,XX @@ sub process {
77
        if ($line =~ /^diff --git.*?(\S+)$/) {
78
            $realfile = $1;
79
            $realfile =~ s@^([^/]*)/@@;
80
-
81
        } elsif ($line =~ /^\+\+\+\s+(\S+)/) {
82
            $realfile = $1;
83
            $realfile =~ s@^([^/]*)/@@;
84
@@ -XXX,XX +XXX,XX @@ sub process {
85
        if ($line =~ /^\s*signed-off-by:/i) {
86
            # This is a signoff, if ugly, so do not double report.
87
            $signoff++;
88
+            $in_commit_log = 0;
89
+
90
            if (!($line =~ /^\s*Signed-off-by:/)) {
91
                ERROR("The correct form is \"Signed-off-by\"\n" .
92
                    $herecurr);
93
@@ -XXX,XX +XXX,XX @@ sub process {
94
            ERROR("Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr);
95
        }
96
97
+# Check if it's the start of a commit log
98
+# (not a header line and we haven't seen the patch filename)
99
+        if ($in_header_lines && $realfile =~ /^$/ &&
100
+         $rawline !~ /^(commit\b|from\b|\w+:).+$/i) {
101
+            $in_header_lines = 0;
102
+            $in_commit_log = 1;
103
+        }
104
+
105
+# Still not yet in a patch, check for any UTF-8
106
+        if ($in_commit_log && $realfile =~ /^$/ &&
107
+         $rawline =~ /$NON_ASCII_UTF8/) {
108
+            WARN("8-bit UTF-8 used in possible commit log\n" . $herecurr);
109
+        }
110
+
111
# ignore non-hunk lines and lines being removed
112
        next if (!$hunk_line || $line =~ /^-/);
113
114
--
115
2.17.0
116
117
diff view generated by jsdifflib
Deleted patch
1
From: Pasi Savanainen <pasi.savanainen@nixu.com>
2
1
3
Check that a commit log doesn't contain UTF-8 when a mail header
4
explicitly defines a different charset, like
5
6
'Content-Type: text/plain; charset="us-ascii"'
7
8
Signed-off-by: Pasi Savanainen <pasi.savanainen@nixu.com>
9
Reviewed-by: Markus Armbruster <armbru@redhat.com>
10
Reviewed-by: Thomas Huth <thuth@redhat.com>
11
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
12
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
13
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
14
Message-id: 20180430124651.10340-3-stefanha@redhat.com
15
Cc: Joe Perches <joe@perches.com>
16
Cc: Andy Whitcroft <apw@canonical.com>
17
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
18
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
19
(cherry picked from commit fa64205df9dfd7b7662cc64a7e82115c00e428e5)
20
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
21
Reviewed-by: Thomas Huth <thuth@redhat.com>
22
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
23
---
24
scripts/checkpatch.pl | 13 +++++++++++--
25
1 file changed, 11 insertions(+), 2 deletions(-)
26
27
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
28
index XXXXXXX..XXXXXXX 100755
29
--- a/scripts/checkpatch.pl
30
+++ b/scripts/checkpatch.pl
31
@@ -XXX,XX +XXX,XX @@ sub process {
32
    my $in_header_lines = 1;
33
    my $in_commit_log = 0;        #Scanning lines before patch
34
35
+    my $non_utf8_charset = 0;
36
+
37
    our @report = ();
38
    our $cnt_lines = 0;
39
    our $cnt_error = 0;
40
@@ -XXX,XX +XXX,XX @@ sub process {
41
            $in_commit_log = 1;
42
        }
43
44
-# Still not yet in a patch, check for any UTF-8
45
-        if ($in_commit_log && $realfile =~ /^$/ &&
46
+# Check if there is UTF-8 in a commit log when a mail header has explicitly
47
+# declined it, i.e defined some charset where it is missing.
48
+        if ($in_header_lines &&
49
+         $rawline =~ /^Content-Type:.+charset="(.+)".*$/ &&
50
+         $1 !~ /utf-8/i) {
51
+            $non_utf8_charset = 1;
52
+        }
53
+
54
+        if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ &&
55
         $rawline =~ /$NON_ASCII_UTF8/) {
56
            WARN("8-bit UTF-8 used in possible commit log\n" . $herecurr);
57
        }
58
--
59
2.17.0
60
61
diff view generated by jsdifflib
Deleted patch
1
From: Joe Perches <joe@perches.com>
2
1
3
There are some patches created by git format-patch that when scanned by
4
checkpatch report errors on lines like
5
6
To:    address.tld
7
8
This is a checkpatch false positive.
9
10
Improve the logic a bit to ignore folded email headers to avoid emitting
11
these messages.
12
13
Signed-off-by: Joe Perches <joe@perches.com>
14
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
15
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
16
Reviewed-by: Markus Armbruster <armbru@redhat.com>
17
Reviewed-by: Thomas Huth <thuth@redhat.com>
18
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
19
Message-id: 20180430124651.10340-4-stefanha@redhat.com
20
(cherry picked from commit 29ee1b0c67e0dd7dea8dd718e8326076bce5b6fe)
21
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
22
Reviewed-by: Thomas Huth <thuth@redhat.com>
23
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
24
---
25
scripts/checkpatch.pl | 5 +++--
26
1 file changed, 3 insertions(+), 2 deletions(-)
27
28
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
29
index XXXXXXX..XXXXXXX 100755
30
--- a/scripts/checkpatch.pl
31
+++ b/scripts/checkpatch.pl
32
@@ -XXX,XX +XXX,XX @@ sub process {
33
    my $signoff = 0;
34
    my $is_patch = 0;
35
36
-    my $in_header_lines = 1;
37
+    my $in_header_lines = $file ? 0 : 1;
38
    my $in_commit_log = 0;        #Scanning lines before patch
39
40
    my $non_utf8_charset = 0;
41
@@ -XXX,XX +XXX,XX @@ sub process {
42
# Check if it's the start of a commit log
43
# (not a header line and we haven't seen the patch filename)
44
        if ($in_header_lines && $realfile =~ /^$/ &&
45
-         $rawline !~ /^(commit\b|from\b|\w+:).+$/i) {
46
+         !($rawline =~ /^\s+\S/ ||
47
+         $rawline =~ /^(commit\b|from\b|[\w-]+:).*$/i)) {
48
            $in_header_lines = 0;
49
            $in_commit_log = 1;
50
        }
51
--
52
2.17.0
53
54
diff view generated by jsdifflib
Deleted patch
1
From: Joe Perches <joe@perches.com>
2
1
3
Whenever files are added, moved, or deleted, the MAINTAINERS file
4
patterns can be out of sync or outdated.
5
6
To try to keep MAINTAINERS more up-to-date, add a one-time warning
7
whenever a patch does any of those.
8
9
Signed-off-by: Joe Perches <joe@perches.com>
10
Acked-by: Andy Whitcroft <apw@canonical.com>
11
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
12
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
13
Reviewed-by: Markus Armbruster <armbru@redhat.com>
14
Reviewed-by: Thomas Huth <thuth@redhat.com>
15
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
16
Message-id: 20180430124651.10340-5-stefanha@redhat.com
17
(cherry picked from commit 13f1937ef33950b1112049972249e6191b82e6c9)
18
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
19
Reviewed-by: Thomas Huth <thuth@redhat.com>
20
21
Conflicts:
22
QEMU WARN() only takes one argument, drop the 'type' value in the
23
first argument.
24
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
25
---
26
scripts/checkpatch.pl | 12 +++++++++++-
27
1 file changed, 11 insertions(+), 1 deletion(-)
28
29
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
30
index XXXXXXX..XXXXXXX 100755
31
--- a/scripts/checkpatch.pl
32
+++ b/scripts/checkpatch.pl
33
@@ -XXX,XX +XXX,XX @@ sub process {
34
35
    my $in_header_lines = $file ? 0 : 1;
36
    my $in_commit_log = 0;        #Scanning lines before patch
37
-
38
+    my $reported_maintainer_file = 0;
39
    my $non_utf8_charset = 0;
40
41
    our @report = ();
42
@@ -XXX,XX +XXX,XX @@ sub process {
43
            }
44
        }
45
46
+# Check for added, moved or deleted files
47
+        if (!$reported_maintainer_file && !$in_commit_log &&
48
+         ($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ ||
49
+         $line =~ /^rename (?:from|to) [\w\/\.\-]+\s*$/ ||
50
+         ($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ &&
51
+         (defined($1) || defined($2))))) {
52
+            $reported_maintainer_file = 1;
53
+            WARN("added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr);
54
+        }
55
+
56
# Check for wrappage within a valid hunk of the file
57
        if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) {
58
            ERROR("patch seems to be corrupt (line wrapped?)\n" .
59
--
60
2.17.0
61
62
diff view generated by jsdifflib
Deleted patch
1
From: Joe Perches <joe@perches.com>
2
1
3
When files are being added/moved/deleted and a patch contains an update to
4
the MAINTAINERS file, assume it's to update the MAINTAINERS file correctly
5
and do not emit the "does MAINTAINERS need updating?" message.
6
7
Reported by many people.
8
9
Signed-off-by: Joe Perches <joe@perches.com>
10
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
11
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
12
Reviewed-by: Markus Armbruster <armbru@redhat.com>
13
Reviewed-by: Thomas Huth <thuth@redhat.com>
14
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
15
Message-id: 20180430124651.10340-6-stefanha@redhat.com
16
(cherry picked from e0d975b1b439c4fef58fbc306c542c94f48bb849)
17
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
18
Reviewed-by: Thomas Huth <thuth@redhat.com>
19
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
20
---
21
scripts/checkpatch.pl | 6 ++++++
22
1 file changed, 6 insertions(+)
23
24
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
25
index XXXXXXX..XXXXXXX 100755
26
--- a/scripts/checkpatch.pl
27
+++ b/scripts/checkpatch.pl
28
@@ -XXX,XX +XXX,XX @@ sub process {
29
            }
30
        }
31
32
+# Check if MAINTAINERS is being updated. If so, there's probably no need to
33
+# emit the "does MAINTAINERS need updating?" message on file add/move/delete
34
+        if ($line =~ /^\s*MAINTAINERS\s*\|/) {
35
+            $reported_maintainer_file = 1;
36
+        }
37
+
38
# Check for added, moved or deleted files
39
        if (!$reported_maintainer_file && !$in_commit_log &&
40
         ($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ ||
41
--
42
2.17.0
43
44
diff view generated by jsdifflib
1
On Linux posix_fadvise(POSIX_FADV_DONTNEED) invalidates pages*. Use
1
From: Nicolas Saenz Julienne <nsaenzju@redhat.com>
2
this to drop page cache on the destination host during shared storage
3
migration. This way the destination host will read the latest copy of
4
the data and will not use stale data from the page cache.
5
2
6
The flow is as follows:
3
The thread pool regulates itself: when idle, it kills threads until
4
empty, when in demand, it creates new threads until full. This behaviour
5
doesn't play well with latency sensitive workloads where the price of
6
creating a new thread is too high. For example, when paired with qemu's
7
'-mlock', or using safety features like SafeStack, creating a new thread
8
has been measured take multiple milliseconds.
7
9
8
1. Source host writes out all dirty pages and inactivates drives.
10
In order to mitigate this let's introduce a new 'EventLoopBase'
9
2. QEMU_VM_EOF is sent on migration stream.
11
property to set the thread pool size. The threads will be created during
10
3. Destination host invalidates caches before accessing drives.
12
the pool's initialization or upon updating the property's value, remain
13
available during its lifetime regardless of demand, and destroyed upon
14
freeing it. A properly characterized workload will then be able to
15
configure the pool to avoid any latency spikes.
11
16
12
This patch enables live migration even with -drive cache.direct=off.
17
Signed-off-by: Nicolas Saenz Julienne <nsaenzju@redhat.com>
13
18
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
14
* Terms and conditions may apply, please see patch for details.
19
Acked-by: Markus Armbruster <armbru@redhat.com>
15
20
Message-id: 20220425075723.20019-4-nsaenzju@redhat.com
16
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
17
Reviewed-by: Fam Zheng <famz@redhat.com>
18
Message-id: 20180427162312.18583-2-stefanha@redhat.com
19
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
21
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
20
---
22
---
21
block/file-posix.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
23
qapi/qom.json | 10 +++++-
22
1 file changed, 46 insertions(+)
24
include/block/aio.h | 10 ++++++
25
include/block/thread-pool.h | 3 ++
26
include/sysemu/event-loop-base.h | 4 +++
27
event-loop-base.c | 23 +++++++++++++
28
iothread.c | 3 ++
29
util/aio-posix.c | 1 +
30
util/async.c | 20 ++++++++++++
31
util/main-loop.c | 9 ++++++
32
util/thread-pool.c | 55 +++++++++++++++++++++++++++++---
33
10 files changed, 133 insertions(+), 5 deletions(-)
23
34
24
diff --git a/block/file-posix.c b/block/file-posix.c
35
diff --git a/qapi/qom.json b/qapi/qom.json
25
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
26
--- a/block/file-posix.c
37
--- a/qapi/qom.json
27
+++ b/block/file-posix.c
38
+++ b/qapi/qom.json
28
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_block_status(BlockDriverState *bs,
39
@@ -XXX,XX +XXX,XX @@
29
return ret | BDRV_BLOCK_OFFSET_VALID;
40
# 0 means that the engine will use its default.
30
}
41
# (default: 0)
31
42
#
32
+static void coroutine_fn raw_co_invalidate_cache(BlockDriverState *bs,
43
+# @thread-pool-min: minimum number of threads reserved in the thread pool
33
+ Error **errp)
44
+# (default:0)
45
+#
46
+# @thread-pool-max: maximum number of threads the thread pool can contain
47
+# (default:64)
48
+#
49
# Since: 7.1
50
##
51
{ 'struct': 'EventLoopBaseProperties',
52
- 'data': { '*aio-max-batch': 'int' } }
53
+ 'data': { '*aio-max-batch': 'int',
54
+ '*thread-pool-min': 'int',
55
+ '*thread-pool-max': 'int' } }
56
57
##
58
# @IothreadProperties:
59
diff --git a/include/block/aio.h b/include/block/aio.h
60
index XXXXXXX..XXXXXXX 100644
61
--- a/include/block/aio.h
62
+++ b/include/block/aio.h
63
@@ -XXX,XX +XXX,XX @@ struct AioContext {
64
QSLIST_HEAD(, Coroutine) scheduled_coroutines;
65
QEMUBH *co_schedule_bh;
66
67
+ int thread_pool_min;
68
+ int thread_pool_max;
69
/* Thread pool for performing work and receiving completion callbacks.
70
* Has its own locking.
71
*/
72
@@ -XXX,XX +XXX,XX @@ void aio_context_set_poll_params(AioContext *ctx, int64_t max_ns,
73
void aio_context_set_aio_params(AioContext *ctx, int64_t max_batch,
74
Error **errp);
75
76
+/**
77
+ * aio_context_set_thread_pool_params:
78
+ * @ctx: the aio context
79
+ * @min: min number of threads to have readily available in the thread pool
80
+ * @min: max number of threads the thread pool can contain
81
+ */
82
+void aio_context_set_thread_pool_params(AioContext *ctx, int64_t min,
83
+ int64_t max, Error **errp);
84
#endif
85
diff --git a/include/block/thread-pool.h b/include/block/thread-pool.h
86
index XXXXXXX..XXXXXXX 100644
87
--- a/include/block/thread-pool.h
88
+++ b/include/block/thread-pool.h
89
@@ -XXX,XX +XXX,XX @@
90
91
#include "block/block.h"
92
93
+#define THREAD_POOL_MAX_THREADS_DEFAULT 64
94
+
95
typedef int ThreadPoolFunc(void *opaque);
96
97
typedef struct ThreadPool ThreadPool;
98
@@ -XXX,XX +XXX,XX @@ BlockAIOCB *thread_pool_submit_aio(ThreadPool *pool,
99
int coroutine_fn thread_pool_submit_co(ThreadPool *pool,
100
ThreadPoolFunc *func, void *arg);
101
void thread_pool_submit(ThreadPool *pool, ThreadPoolFunc *func, void *arg);
102
+void thread_pool_update_params(ThreadPool *pool, struct AioContext *ctx);
103
104
#endif
105
diff --git a/include/sysemu/event-loop-base.h b/include/sysemu/event-loop-base.h
106
index XXXXXXX..XXXXXXX 100644
107
--- a/include/sysemu/event-loop-base.h
108
+++ b/include/sysemu/event-loop-base.h
109
@@ -XXX,XX +XXX,XX @@ struct EventLoopBase {
110
111
/* AioContext AIO engine parameters */
112
int64_t aio_max_batch;
113
+
114
+ /* AioContext thread pool parameters */
115
+ int64_t thread_pool_min;
116
+ int64_t thread_pool_max;
117
};
118
#endif
119
diff --git a/event-loop-base.c b/event-loop-base.c
120
index XXXXXXX..XXXXXXX 100644
121
--- a/event-loop-base.c
122
+++ b/event-loop-base.c
123
@@ -XXX,XX +XXX,XX @@
124
#include "qemu/osdep.h"
125
#include "qom/object_interfaces.h"
126
#include "qapi/error.h"
127
+#include "block/thread-pool.h"
128
#include "sysemu/event-loop-base.h"
129
130
typedef struct {
131
@@ -XXX,XX +XXX,XX @@ typedef struct {
132
ptrdiff_t offset; /* field's byte offset in EventLoopBase struct */
133
} EventLoopBaseParamInfo;
134
135
+static void event_loop_base_instance_init(Object *obj)
34
+{
136
+{
35
+ BDRVRawState *s = bs->opaque;
137
+ EventLoopBase *base = EVENT_LOOP_BASE(obj);
36
+ int ret;
138
+
37
+
139
+ base->thread_pool_max = THREAD_POOL_MAX_THREADS_DEFAULT;
38
+ ret = fd_open(bs);
140
+}
39
+ if (ret < 0) {
141
+
40
+ error_setg_errno(errp, -ret, "The file descriptor is not open");
142
static EventLoopBaseParamInfo aio_max_batch_info = {
143
"aio-max-batch", offsetof(EventLoopBase, aio_max_batch),
144
};
145
+static EventLoopBaseParamInfo thread_pool_min_info = {
146
+ "thread-pool-min", offsetof(EventLoopBase, thread_pool_min),
147
+};
148
+static EventLoopBaseParamInfo thread_pool_max_info = {
149
+ "thread-pool-max", offsetof(EventLoopBase, thread_pool_max),
150
+};
151
152
static void event_loop_base_get_param(Object *obj, Visitor *v,
153
const char *name, void *opaque, Error **errp)
154
@@ -XXX,XX +XXX,XX @@ static void event_loop_base_class_init(ObjectClass *klass, void *class_data)
155
event_loop_base_get_param,
156
event_loop_base_set_param,
157
NULL, &aio_max_batch_info);
158
+ object_class_property_add(klass, "thread-pool-min", "int",
159
+ event_loop_base_get_param,
160
+ event_loop_base_set_param,
161
+ NULL, &thread_pool_min_info);
162
+ object_class_property_add(klass, "thread-pool-max", "int",
163
+ event_loop_base_get_param,
164
+ event_loop_base_set_param,
165
+ NULL, &thread_pool_max_info);
166
}
167
168
static const TypeInfo event_loop_base_info = {
169
.name = TYPE_EVENT_LOOP_BASE,
170
.parent = TYPE_OBJECT,
171
.instance_size = sizeof(EventLoopBase),
172
+ .instance_init = event_loop_base_instance_init,
173
.class_size = sizeof(EventLoopBaseClass),
174
.class_init = event_loop_base_class_init,
175
.abstract = true,
176
diff --git a/iothread.c b/iothread.c
177
index XXXXXXX..XXXXXXX 100644
178
--- a/iothread.c
179
+++ b/iothread.c
180
@@ -XXX,XX +XXX,XX @@ static void iothread_set_aio_context_params(EventLoopBase *base, Error **errp)
181
aio_context_set_aio_params(iothread->ctx,
182
iothread->parent_obj.aio_max_batch,
183
errp);
184
+
185
+ aio_context_set_thread_pool_params(iothread->ctx, base->thread_pool_min,
186
+ base->thread_pool_max, errp);
187
}
188
189
190
diff --git a/util/aio-posix.c b/util/aio-posix.c
191
index XXXXXXX..XXXXXXX 100644
192
--- a/util/aio-posix.c
193
+++ b/util/aio-posix.c
194
@@ -XXX,XX +XXX,XX @@
195
196
#include "qemu/osdep.h"
197
#include "block/block.h"
198
+#include "block/thread-pool.h"
199
#include "qemu/main-loop.h"
200
#include "qemu/rcu.h"
201
#include "qemu/rcu_queue.h"
202
diff --git a/util/async.c b/util/async.c
203
index XXXXXXX..XXXXXXX 100644
204
--- a/util/async.c
205
+++ b/util/async.c
206
@@ -XXX,XX +XXX,XX @@ AioContext *aio_context_new(Error **errp)
207
208
ctx->aio_max_batch = 0;
209
210
+ ctx->thread_pool_min = 0;
211
+ ctx->thread_pool_max = THREAD_POOL_MAX_THREADS_DEFAULT;
212
+
213
return ctx;
214
fail:
215
g_source_destroy(&ctx->source);
216
@@ -XXX,XX +XXX,XX @@ void qemu_set_current_aio_context(AioContext *ctx)
217
assert(!get_my_aiocontext());
218
set_my_aiocontext(ctx);
219
}
220
+
221
+void aio_context_set_thread_pool_params(AioContext *ctx, int64_t min,
222
+ int64_t max, Error **errp)
223
+{
224
+
225
+ if (min > max || !max || min > INT_MAX || max > INT_MAX) {
226
+ error_setg(errp, "bad thread-pool-min/thread-pool-max values");
41
+ return;
227
+ return;
42
+ }
228
+ }
43
+
229
+
44
+ if (s->open_flags & O_DIRECT) {
230
+ ctx->thread_pool_min = min;
45
+ return; /* No host kernel page cache */
231
+ ctx->thread_pool_max = max;
46
+ }
232
+
47
+
233
+ if (ctx->thread_pool) {
48
+#if defined(__linux__)
234
+ thread_pool_update_params(ctx->thread_pool, ctx);
49
+ /* This sets the scene for the next syscall... */
235
+ }
50
+ ret = bdrv_co_flush(bs);
236
+}
51
+ if (ret < 0) {
237
diff --git a/util/main-loop.c b/util/main-loop.c
52
+ error_setg_errno(errp, -ret, "flush failed");
238
index XXXXXXX..XXXXXXX 100644
239
--- a/util/main-loop.c
240
+++ b/util/main-loop.c
241
@@ -XXX,XX +XXX,XX @@
242
#include "sysemu/replay.h"
243
#include "qemu/main-loop.h"
244
#include "block/aio.h"
245
+#include "block/thread-pool.h"
246
#include "qemu/error-report.h"
247
#include "qemu/queue.h"
248
#include "qemu/compiler.h"
249
@@ -XXX,XX +XXX,XX @@ int qemu_init_main_loop(Error **errp)
250
251
static void main_loop_update_params(EventLoopBase *base, Error **errp)
252
{
253
+ ERRP_GUARD();
254
+
255
if (!qemu_aio_context) {
256
error_setg(errp, "qemu aio context not ready");
257
return;
258
}
259
260
aio_context_set_aio_params(qemu_aio_context, base->aio_max_batch, errp);
261
+ if (*errp) {
53
+ return;
262
+ return;
54
+ }
263
+ }
55
+
264
+
56
+ /* Linux does not invalidate pages that are dirty, locked, or mmapped by a
265
+ aio_context_set_thread_pool_params(qemu_aio_context, base->thread_pool_min,
57
+ * process. These limitations are okay because we just fsynced the file,
266
+ base->thread_pool_max, errp);
58
+ * we don't use mmap, and the file should not be in use by other processes.
267
}
268
269
MainLoop *mloop;
270
diff --git a/util/thread-pool.c b/util/thread-pool.c
271
index XXXXXXX..XXXXXXX 100644
272
--- a/util/thread-pool.c
273
+++ b/util/thread-pool.c
274
@@ -XXX,XX +XXX,XX @@ struct ThreadPool {
275
QemuMutex lock;
276
QemuCond worker_stopped;
277
QemuSemaphore sem;
278
- int max_threads;
279
QEMUBH *new_thread_bh;
280
281
/* The following variables are only accessed from one AioContext. */
282
@@ -XXX,XX +XXX,XX @@ struct ThreadPool {
283
int new_threads; /* backlog of threads we need to create */
284
int pending_threads; /* threads created but not running yet */
285
bool stopping;
286
+ int min_threads;
287
+ int max_threads;
288
};
289
290
+static inline bool back_to_sleep(ThreadPool *pool, int ret)
291
+{
292
+ /*
293
+ * The semaphore timed out, we should exit the loop except when:
294
+ * - There is work to do, we raced with the signal.
295
+ * - The max threads threshold just changed, we raced with the signal.
296
+ * - The thread pool forces a minimum number of readily available threads.
59
+ */
297
+ */
60
+ ret = posix_fadvise(s->fd, 0, 0, POSIX_FADV_DONTNEED);
298
+ if (ret == -1 && (!QTAILQ_EMPTY(&pool->request_list) ||
61
+ if (ret != 0) { /* the return value is a positive errno */
299
+ pool->cur_threads > pool->max_threads ||
62
+ error_setg_errno(errp, ret, "fadvise failed");
300
+ pool->cur_threads <= pool->min_threads)) {
63
+ return;
301
+ return true;
64
+ }
302
+ }
65
+#else /* __linux__ */
303
+
66
+ /* Do nothing. Live migration to a remote host with cache.direct=off is
304
+ return false;
67
+ * unsupported on other host operating systems. Cache consistency issues
305
+}
68
+ * may occur but no error is reported here, partly because that's the
306
+
69
+ * historical behavior and partly because it's hard to differentiate valid
307
static void *worker_thread(void *opaque)
70
+ * configurations that should not cause errors.
308
{
309
ThreadPool *pool = opaque;
310
@@ -XXX,XX +XXX,XX @@ static void *worker_thread(void *opaque)
311
ret = qemu_sem_timedwait(&pool->sem, 10000);
312
qemu_mutex_lock(&pool->lock);
313
pool->idle_threads--;
314
- } while (ret == -1 && !QTAILQ_EMPTY(&pool->request_list));
315
- if (ret == -1 || pool->stopping) {
316
+ } while (back_to_sleep(pool, ret));
317
+ if (ret == -1 || pool->stopping ||
318
+ pool->cur_threads > pool->max_threads) {
319
break;
320
}
321
322
@@ -XXX,XX +XXX,XX @@ void thread_pool_submit(ThreadPool *pool, ThreadPoolFunc *func, void *arg)
323
thread_pool_submit_aio(pool, func, arg, NULL, NULL);
324
}
325
326
+void thread_pool_update_params(ThreadPool *pool, AioContext *ctx)
327
+{
328
+ qemu_mutex_lock(&pool->lock);
329
+
330
+ pool->min_threads = ctx->thread_pool_min;
331
+ pool->max_threads = ctx->thread_pool_max;
332
+
333
+ /*
334
+ * We either have to:
335
+ * - Increase the number available of threads until over the min_threads
336
+ * threshold.
337
+ * - Decrease the number of available threads until under the max_threads
338
+ * threshold.
339
+ * - Do nothing. The current number of threads fall in between the min and
340
+ * max thresholds. We'll let the pool manage itself.
71
+ */
341
+ */
72
+#endif /* !__linux__ */
342
+ for (int i = pool->cur_threads; i < pool->min_threads; i++) {
343
+ spawn_thread(pool);
344
+ }
345
+
346
+ for (int i = pool->cur_threads; i > pool->max_threads; i--) {
347
+ qemu_sem_post(&pool->sem);
348
+ }
349
+
350
+ qemu_mutex_unlock(&pool->lock);
73
+}
351
+}
74
+
352
+
75
static coroutine_fn BlockAIOCB *raw_aio_pdiscard(BlockDriverState *bs,
353
static void thread_pool_init_one(ThreadPool *pool, AioContext *ctx)
76
int64_t offset, int bytes,
354
{
77
BlockCompletionFunc *cb, void *opaque)
355
if (!ctx) {
78
@@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_file = {
356
@@ -XXX,XX +XXX,XX @@ static void thread_pool_init_one(ThreadPool *pool, AioContext *ctx)
79
.bdrv_co_create_opts = raw_co_create_opts,
357
qemu_mutex_init(&pool->lock);
80
.bdrv_has_zero_init = bdrv_has_zero_init_1,
358
qemu_cond_init(&pool->worker_stopped);
81
.bdrv_co_block_status = raw_co_block_status,
359
qemu_sem_init(&pool->sem, 0);
82
+ .bdrv_co_invalidate_cache = raw_co_invalidate_cache,
360
- pool->max_threads = 64;
83
.bdrv_co_pwrite_zeroes = raw_co_pwrite_zeroes,
361
pool->new_thread_bh = aio_bh_new(ctx, spawn_thread_bh_fn, pool);
84
362
85
.bdrv_co_preadv = raw_co_preadv,
363
QLIST_INIT(&pool->head);
86
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_host_device = {
364
QTAILQ_INIT(&pool->request_list);
87
.bdrv_reopen_abort = raw_reopen_abort,
365
+
88
.bdrv_co_create_opts = hdev_co_create_opts,
366
+ thread_pool_update_params(pool, ctx);
89
.create_opts = &raw_create_opts,
367
}
90
+ .bdrv_co_invalidate_cache = raw_co_invalidate_cache,
368
91
.bdrv_co_pwrite_zeroes = hdev_co_pwrite_zeroes,
369
ThreadPool *thread_pool_new(AioContext *ctx)
92
93
.bdrv_co_preadv = raw_co_preadv,
94
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_host_cdrom = {
95
.bdrv_reopen_abort = raw_reopen_abort,
96
.bdrv_co_create_opts = hdev_co_create_opts,
97
.create_opts = &raw_create_opts,
98
+ .bdrv_co_invalidate_cache = raw_co_invalidate_cache,
99
100
101
.bdrv_co_preadv = raw_co_preadv,
102
--
370
--
103
2.17.0
371
2.35.1
104
105
diff view generated by jsdifflib