1 | The following changes since commit d0ed6a69d399ae193959225cdeaa9382746c91cc: | 1 | The following changes since commit ca61fa4b803e5d0abaf6f1ceb690f23bb78a4def: |
---|---|---|---|
2 | 2 | ||
3 | Update version for v5.1.0 release (2020-08-11 17:07:03 +0100) | 3 | Merge remote-tracking branch 'remotes/quic/tags/pull-hex-20211006' into staging (2021-10-06 12:11:14 -0700) |
4 | 4 | ||
5 | are available in the Git repository at: | 5 | are available in the Git repository at: |
6 | 6 | ||
7 | https://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 44277bf914471962c9e88e09c859aae65ae109c4: | 9 | for you to fetch changes up to 1cc7eada97914f090125e588497986f6f7900514: |
10 | 10 | ||
11 | aio-posix: keep aio_notify_me disabled during polling (2020-08-13 13:34:14 = | 11 | iothread: use IOThreadParamInfo in iothread_[set|get]_param() (2021-10-07 15:29:50 +0100) |
12 | +0100) | ||
13 | 12 | ||
14 | ---------------------------------------------------------------- | 13 | ---------------------------------------------------------------- |
15 | Pull request | 14 | Pull request |
16 | 15 | ||
17 | ---------------------------------------------------------------- | 16 | ---------------------------------------------------------------- |
18 | 17 | ||
19 | Stefan Hajnoczi (3): | 18 | Stefano Garzarella (2): |
20 | async: rename event_notifier_dummy_cb/poll() | 19 | iothread: rename PollParamInfo to IOThreadParamInfo |
21 | async: always set ctx->notified in aio_notify() | 20 | iothread: use IOThreadParamInfo in iothread_[set|get]_param() |
22 | aio-posix: keep aio_notify_me disabled during polling | ||
23 | 21 | ||
24 | util/aio-posix.c | 47 +++++++++++++++++++++++++---------------------- | 22 | iothread.c | 28 +++++++++++++++------------- |
25 | util/async.c | 36 +++++++++++++++++++++++------------- | 23 | 1 file changed, 15 insertions(+), 13 deletions(-) |
26 | 2 files changed, 48 insertions(+), 35 deletions(-) | ||
27 | 24 | ||
28 | --=20 | 25 | -- |
29 | 2.26.2 | 26 | 2.31.1 |
30 | 27 | ||
28 | |||
29 | diff view generated by jsdifflib |
1 | Polling only monitors the ctx->notified field and does not need the | 1 | From: Stefano Garzarella <sgarzare@redhat.com> |
---|---|---|---|
2 | ctx->notifier EventNotifier to be signalled. Keep ctx->aio_notify_me | ||
3 | disabled while polling to avoid unnecessary EventNotifier syscalls. | ||
4 | 2 | ||
5 | This optimization improves virtio-blk 4KB random read performance by | 3 | Commit 1793ad0247 ("iothread: add aio-max-batch parameter") added |
6 | 18%. The following results are with an IOThread and the null-co block | 4 | a new parameter (aio-max-batch) to IOThread and used PollParamInfo |
7 | driver: | 5 | structure to handle it. |
8 | 6 | ||
9 | Test IOPS Error | 7 | Since it is not a parameter of the polling mechanism, we rename the |
10 | Before 244518.62 ± 1.20% | 8 | structure to a more generic IOThreadParamInfo. |
11 | After 290706.11 ± 0.44% | ||
12 | 9 | ||
13 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | 10 | Suggested-by: Kevin Wolf <kwolf@redhat.com> |
14 | Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> | 11 | Signed-off-by: Stefano Garzarella <sgarzare@redhat.com> |
15 | Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> | 12 | Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> |
16 | Message-id: 20200806131802.569478-4-stefanha@redhat.com | 13 | Message-id: 20210727145936.147032-2-sgarzare@redhat.com |
17 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | 14 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> |
18 | --- | 15 | --- |
19 | util/aio-posix.c | 47 +++++++++++++++++++++++++---------------------- | 16 | iothread.c | 14 +++++++------- |
20 | 1 file changed, 25 insertions(+), 22 deletions(-) | 17 | 1 file changed, 7 insertions(+), 7 deletions(-) |
21 | 18 | ||
22 | diff --git a/util/aio-posix.c b/util/aio-posix.c | 19 | diff --git a/iothread.c b/iothread.c |
23 | index XXXXXXX..XXXXXXX 100644 | 20 | index XXXXXXX..XXXXXXX 100644 |
24 | --- a/util/aio-posix.c | 21 | --- a/iothread.c |
25 | +++ b/util/aio-posix.c | 22 | +++ b/iothread.c |
26 | @@ -XXX,XX +XXX,XX @@ static bool remove_idle_poll_handlers(AioContext *ctx, int64_t now) | 23 | @@ -XXX,XX +XXX,XX @@ static void iothread_complete(UserCreatable *obj, Error **errp) |
27 | * | 24 | typedef struct { |
28 | * Polls for a given time. | 25 | const char *name; |
29 | * | 26 | ptrdiff_t offset; /* field's byte offset in IOThread struct */ |
30 | - * Note that ctx->notify_me must be non-zero so this function can detect | 27 | -} PollParamInfo; |
31 | - * aio_notify(). | 28 | +} IOThreadParamInfo; |
32 | - * | 29 | |
33 | * Note that the caller must have incremented ctx->list_lock. | 30 | -static PollParamInfo poll_max_ns_info = { |
34 | * | 31 | +static IOThreadParamInfo poll_max_ns_info = { |
35 | * Returns: true if progress was made, false otherwise | 32 | "poll-max-ns", offsetof(IOThread, poll_max_ns), |
36 | @@ -XXX,XX +XXX,XX @@ static bool run_poll_handlers(AioContext *ctx, int64_t max_ns, int64_t *timeout) | 33 | }; |
37 | bool progress; | 34 | -static PollParamInfo poll_grow_info = { |
38 | int64_t start_time, elapsed_time; | 35 | +static IOThreadParamInfo poll_grow_info = { |
39 | 36 | "poll-grow", offsetof(IOThread, poll_grow), | |
40 | - assert(ctx->notify_me); | 37 | }; |
41 | assert(qemu_lockcnt_count(&ctx->list_lock) > 0); | 38 | -static PollParamInfo poll_shrink_info = { |
42 | 39 | +static IOThreadParamInfo poll_shrink_info = { | |
43 | trace_run_poll_handlers_begin(ctx, max_ns, *timeout); | 40 | "poll-shrink", offsetof(IOThread, poll_shrink), |
44 | @@ -XXX,XX +XXX,XX @@ static bool run_poll_handlers(AioContext *ctx, int64_t max_ns, int64_t *timeout) | 41 | }; |
45 | * @timeout: timeout for blocking wait, computed by the caller and updated if | 42 | -static PollParamInfo aio_max_batch_info = { |
46 | * polling succeeds. | 43 | +static IOThreadParamInfo aio_max_batch_info = { |
47 | * | 44 | "aio-max-batch", offsetof(IOThread, aio_max_batch), |
48 | - * ctx->notify_me must be non-zero so this function can detect aio_notify(). | 45 | }; |
49 | - * | 46 | |
50 | * Note that the caller must have incremented ctx->list_lock. | 47 | @@ -XXX,XX +XXX,XX @@ static void iothread_get_param(Object *obj, Visitor *v, |
51 | * | 48 | const char *name, void *opaque, Error **errp) |
52 | * Returns: true if progress was made, false otherwise | 49 | { |
53 | @@ -XXX,XX +XXX,XX @@ bool aio_poll(AioContext *ctx, bool blocking) | 50 | IOThread *iothread = IOTHREAD(obj); |
54 | AioHandlerList ready_list = QLIST_HEAD_INITIALIZER(ready_list); | 51 | - PollParamInfo *info = opaque; |
55 | int ret = 0; | 52 | + IOThreadParamInfo *info = opaque; |
56 | bool progress; | 53 | int64_t *field = (void *)iothread + info->offset; |
57 | + bool use_notify_me; | 54 | |
58 | int64_t timeout; | 55 | visit_type_int64(v, name, field, errp); |
59 | int64_t start = 0; | 56 | @@ -XXX,XX +XXX,XX @@ static bool iothread_set_param(Object *obj, Visitor *v, |
60 | 57 | const char *name, void *opaque, Error **errp) | |
61 | @@ -XXX,XX +XXX,XX @@ bool aio_poll(AioContext *ctx, bool blocking) | 58 | { |
62 | */ | 59 | IOThread *iothread = IOTHREAD(obj); |
63 | assert(in_aio_context_home_thread(ctx)); | 60 | - PollParamInfo *info = opaque; |
64 | 61 | + IOThreadParamInfo *info = opaque; | |
65 | - /* aio_notify can avoid the expensive event_notifier_set if | 62 | int64_t *field = (void *)iothread + info->offset; |
66 | + qemu_lockcnt_inc(&ctx->list_lock); | 63 | int64_t value; |
67 | + | 64 | |
68 | + if (ctx->poll_max_ns) { | ||
69 | + start = qemu_clock_get_ns(QEMU_CLOCK_REALTIME); | ||
70 | + } | ||
71 | + | ||
72 | + timeout = blocking ? aio_compute_timeout(ctx) : 0; | ||
73 | + progress = try_poll_mode(ctx, &timeout); | ||
74 | + assert(!(timeout && progress)); | ||
75 | + | ||
76 | + /* | ||
77 | + * aio_notify can avoid the expensive event_notifier_set if | ||
78 | * everything (file descriptors, bottom halves, timers) will | ||
79 | * be re-evaluated before the next blocking poll(). This is | ||
80 | * already true when aio_poll is called with blocking == false; | ||
81 | * if blocking == true, it is only true after poll() returns, | ||
82 | * so disable the optimization now. | ||
83 | */ | ||
84 | - if (blocking) { | ||
85 | + use_notify_me = timeout != 0; | ||
86 | + if (use_notify_me) { | ||
87 | atomic_set(&ctx->notify_me, atomic_read(&ctx->notify_me) + 2); | ||
88 | /* | ||
89 | - * Write ctx->notify_me before computing the timeout | ||
90 | - * (reading bottom half flags, etc.). Pairs with | ||
91 | + * Write ctx->notify_me before reading ctx->notified. Pairs with | ||
92 | * smp_mb in aio_notify(). | ||
93 | */ | ||
94 | smp_mb(); | ||
95 | - } | ||
96 | - | ||
97 | - qemu_lockcnt_inc(&ctx->list_lock); | ||
98 | |||
99 | - if (ctx->poll_max_ns) { | ||
100 | - start = qemu_clock_get_ns(QEMU_CLOCK_REALTIME); | ||
101 | + /* Don't block if aio_notify() was called */ | ||
102 | + if (atomic_read(&ctx->notified)) { | ||
103 | + timeout = 0; | ||
104 | + } | ||
105 | } | ||
106 | |||
107 | - timeout = blocking ? aio_compute_timeout(ctx) : 0; | ||
108 | - progress = try_poll_mode(ctx, &timeout); | ||
109 | - assert(!(timeout && progress)); | ||
110 | - | ||
111 | /* If polling is allowed, non-blocking aio_poll does not need the | ||
112 | * system call---a single round of run_poll_handlers_once suffices. | ||
113 | */ | ||
114 | @@ -XXX,XX +XXX,XX @@ bool aio_poll(AioContext *ctx, bool blocking) | ||
115 | ret = ctx->fdmon_ops->wait(ctx, &ready_list, timeout); | ||
116 | } | ||
117 | |||
118 | - if (blocking) { | ||
119 | + if (use_notify_me) { | ||
120 | /* Finish the poll before clearing the flag. */ | ||
121 | - atomic_store_release(&ctx->notify_me, atomic_read(&ctx->notify_me) - 2); | ||
122 | - aio_notify_accept(ctx); | ||
123 | + atomic_store_release(&ctx->notify_me, | ||
124 | + atomic_read(&ctx->notify_me) - 2); | ||
125 | } | ||
126 | |||
127 | + aio_notify_accept(ctx); | ||
128 | + | ||
129 | /* Adjust polling time */ | ||
130 | if (ctx->poll_max_ns) { | ||
131 | int64_t block_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME) - start; | ||
132 | -- | 65 | -- |
133 | 2.26.2 | 66 | 2.31.1 |
134 | 67 | ||
68 | diff view generated by jsdifflib |
1 | The event_notifier_*() prefix can be confused with the EventNotifier | 1 | From: Stefano Garzarella <sgarzare@redhat.com> |
---|---|---|---|
2 | APIs that are also called event_notifier_*(). | ||
3 | 2 | ||
4 | Rename the functions to aio_context_notifier_*() to make it clear that | 3 | Commit 0445409d74 ("iothread: generalize |
5 | they relate to the AioContext::notifier field. | 4 | iothread_set_param/iothread_get_param") moved common code to set and |
5 | get IOThread parameters in two new functions. | ||
6 | 6 | ||
7 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | 7 | These functions are called inside callbacks, so we don't need to use an |
8 | opaque pointer. Let's replace `void *opaque` parameter with | ||
9 | `IOThreadParamInfo *info`. | ||
10 | |||
11 | Suggested-by: Kevin Wolf <kwolf@redhat.com> | ||
12 | Signed-off-by: Stefano Garzarella <sgarzare@redhat.com> | ||
8 | Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> | 13 | Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> |
9 | Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> | 14 | Message-id: 20210727145936.147032-3-sgarzare@redhat.com |
10 | Message-id: 20200806131802.569478-2-stefanha@redhat.com | ||
11 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | 15 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> |
12 | --- | 16 | --- |
13 | util/async.c | 8 ++++---- | 17 | iothread.c | 18 ++++++++++-------- |
14 | 1 file changed, 4 insertions(+), 4 deletions(-) | 18 | 1 file changed, 10 insertions(+), 8 deletions(-) |
15 | 19 | ||
16 | diff --git a/util/async.c b/util/async.c | 20 | diff --git a/iothread.c b/iothread.c |
17 | index XXXXXXX..XXXXXXX 100644 | 21 | index XXXXXXX..XXXXXXX 100644 |
18 | --- a/util/async.c | 22 | --- a/iothread.c |
19 | +++ b/util/async.c | 23 | +++ b/iothread.c |
20 | @@ -XXX,XX +XXX,XX @@ static void aio_timerlist_notify(void *opaque, QEMUClockType type) | 24 | @@ -XXX,XX +XXX,XX @@ static IOThreadParamInfo aio_max_batch_info = { |
21 | aio_notify(opaque); | 25 | }; |
26 | |||
27 | static void iothread_get_param(Object *obj, Visitor *v, | ||
28 | - const char *name, void *opaque, Error **errp) | ||
29 | + const char *name, IOThreadParamInfo *info, Error **errp) | ||
30 | { | ||
31 | IOThread *iothread = IOTHREAD(obj); | ||
32 | - IOThreadParamInfo *info = opaque; | ||
33 | int64_t *field = (void *)iothread + info->offset; | ||
34 | |||
35 | visit_type_int64(v, name, field, errp); | ||
22 | } | 36 | } |
23 | 37 | ||
24 | -static void event_notifier_dummy_cb(EventNotifier *e) | 38 | static bool iothread_set_param(Object *obj, Visitor *v, |
25 | +static void aio_context_notifier_dummy_cb(EventNotifier *e) | 39 | - const char *name, void *opaque, Error **errp) |
40 | + const char *name, IOThreadParamInfo *info, Error **errp) | ||
26 | { | 41 | { |
42 | IOThread *iothread = IOTHREAD(obj); | ||
43 | - IOThreadParamInfo *info = opaque; | ||
44 | int64_t *field = (void *)iothread + info->offset; | ||
45 | int64_t value; | ||
46 | |||
47 | @@ -XXX,XX +XXX,XX @@ static bool iothread_set_param(Object *obj, Visitor *v, | ||
48 | static void iothread_get_poll_param(Object *obj, Visitor *v, | ||
49 | const char *name, void *opaque, Error **errp) | ||
50 | { | ||
51 | + IOThreadParamInfo *info = opaque; | ||
52 | |||
53 | - iothread_get_param(obj, v, name, opaque, errp); | ||
54 | + iothread_get_param(obj, v, name, info, errp); | ||
27 | } | 55 | } |
28 | 56 | ||
29 | /* Returns true if aio_notify() was called (e.g. a BH was scheduled) */ | 57 | static void iothread_set_poll_param(Object *obj, Visitor *v, |
30 | -static bool event_notifier_poll(void *opaque) | 58 | const char *name, void *opaque, Error **errp) |
31 | +static bool aio_context_notifier_poll(void *opaque) | ||
32 | { | 59 | { |
33 | EventNotifier *e = opaque; | 60 | IOThread *iothread = IOTHREAD(obj); |
34 | AioContext *ctx = container_of(e, AioContext, notifier); | 61 | + IOThreadParamInfo *info = opaque; |
35 | @@ -XXX,XX +XXX,XX @@ AioContext *aio_context_new(Error **errp) | 62 | |
36 | 63 | - if (!iothread_set_param(obj, v, name, opaque, errp)) { | |
37 | aio_set_event_notifier(ctx, &ctx->notifier, | 64 | + if (!iothread_set_param(obj, v, name, info, errp)) { |
38 | false, | 65 | return; |
39 | - event_notifier_dummy_cb, | 66 | } |
40 | - event_notifier_poll); | 67 | |
41 | + aio_context_notifier_dummy_cb, | 68 | @@ -XXX,XX +XXX,XX @@ static void iothread_set_poll_param(Object *obj, Visitor *v, |
42 | + aio_context_notifier_poll); | 69 | static void iothread_get_aio_param(Object *obj, Visitor *v, |
43 | #ifdef CONFIG_LINUX_AIO | 70 | const char *name, void *opaque, Error **errp) |
44 | ctx->linux_aio = NULL; | 71 | { |
45 | #endif | 72 | + IOThreadParamInfo *info = opaque; |
73 | |||
74 | - iothread_get_param(obj, v, name, opaque, errp); | ||
75 | + iothread_get_param(obj, v, name, info, errp); | ||
76 | } | ||
77 | |||
78 | static void iothread_set_aio_param(Object *obj, Visitor *v, | ||
79 | const char *name, void *opaque, Error **errp) | ||
80 | { | ||
81 | IOThread *iothread = IOTHREAD(obj); | ||
82 | + IOThreadParamInfo *info = opaque; | ||
83 | |||
84 | - if (!iothread_set_param(obj, v, name, opaque, errp)) { | ||
85 | + if (!iothread_set_param(obj, v, name, info, errp)) { | ||
86 | return; | ||
87 | } | ||
88 | |||
46 | -- | 89 | -- |
47 | 2.26.2 | 90 | 2.31.1 |
48 | 91 | ||
92 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | aio_notify() does not set ctx->notified when called with | ||
2 | ctx->aio_notify_me disabled. Therefore aio_notify_me needs to be enabled | ||
3 | during polling. | ||
4 | 1 | ||
5 | This is suboptimal since expensive event_notifier_set(&ctx->notifier) | ||
6 | and event_notifier_test_and_clear(&ctx->notifier) calls are required | ||
7 | when ctx->aio_notify_me is enabled. | ||
8 | |||
9 | Change aio_notify() so that aio->notified is always set, regardless of | ||
10 | ctx->aio_notify_me. This will make polling cheaper since | ||
11 | ctx->aio_notify_me can remain disabled. Move the | ||
12 | event_notifier_test_and_clear() to the fd handler function (which is now | ||
13 | no longer an empty function so "dummy" has been dropped from its name). | ||
14 | |||
15 | The next patch takes advantage of this by optimizing polling in | ||
16 | util/aio-posix.c. | ||
17 | |||
18 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
19 | Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> | ||
20 | Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
21 | Message-id: 20200806131802.569478-3-stefanha@redhat.com | ||
22 | |||
23 | [Paolo Bonzini pointed out that the smp_wmb() in aio_notify_accept() | ||
24 | should be smp_wb() but the comment should be smp_wmb() instead of | ||
25 | smp_wb(). Fixed. | ||
26 | --Stefan] | ||
27 | |||
28 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
29 | --- | ||
30 | util/async.c | 32 +++++++++++++++++++++----------- | ||
31 | 1 file changed, 21 insertions(+), 11 deletions(-) | ||
32 | |||
33 | diff --git a/util/async.c b/util/async.c | ||
34 | index XXXXXXX..XXXXXXX 100644 | ||
35 | --- a/util/async.c | ||
36 | +++ b/util/async.c | ||
37 | @@ -XXX,XX +XXX,XX @@ LuringState *aio_get_linux_io_uring(AioContext *ctx) | ||
38 | |||
39 | void aio_notify(AioContext *ctx) | ||
40 | { | ||
41 | - /* Write e.g. bh->scheduled before reading ctx->notify_me. Pairs | ||
42 | + /* | ||
43 | + * Write e.g. bh->flags before writing ctx->notified. Pairs with smp_mb in | ||
44 | + * aio_notify_accept. | ||
45 | + */ | ||
46 | + smp_wmb(); | ||
47 | + atomic_set(&ctx->notified, true); | ||
48 | + | ||
49 | + /* | ||
50 | + * Write ctx->notified before reading ctx->notify_me. Pairs | ||
51 | * with smp_mb in aio_ctx_prepare or aio_poll. | ||
52 | */ | ||
53 | smp_mb(); | ||
54 | if (atomic_read(&ctx->notify_me)) { | ||
55 | event_notifier_set(&ctx->notifier); | ||
56 | - atomic_mb_set(&ctx->notified, true); | ||
57 | } | ||
58 | } | ||
59 | |||
60 | void aio_notify_accept(AioContext *ctx) | ||
61 | { | ||
62 | - if (atomic_xchg(&ctx->notified, false) | ||
63 | -#ifdef WIN32 | ||
64 | - || true | ||
65 | -#endif | ||
66 | - ) { | ||
67 | - event_notifier_test_and_clear(&ctx->notifier); | ||
68 | - } | ||
69 | + atomic_set(&ctx->notified, false); | ||
70 | + | ||
71 | + /* | ||
72 | + * Write ctx->notified before reading e.g. bh->flags. Pairs with smp_wmb | ||
73 | + * in aio_notify. | ||
74 | + */ | ||
75 | + smp_mb(); | ||
76 | } | ||
77 | |||
78 | static void aio_timerlist_notify(void *opaque, QEMUClockType type) | ||
79 | @@ -XXX,XX +XXX,XX @@ static void aio_timerlist_notify(void *opaque, QEMUClockType type) | ||
80 | aio_notify(opaque); | ||
81 | } | ||
82 | |||
83 | -static void aio_context_notifier_dummy_cb(EventNotifier *e) | ||
84 | +static void aio_context_notifier_cb(EventNotifier *e) | ||
85 | { | ||
86 | + AioContext *ctx = container_of(e, AioContext, notifier); | ||
87 | + | ||
88 | + event_notifier_test_and_clear(&ctx->notifier); | ||
89 | } | ||
90 | |||
91 | /* Returns true if aio_notify() was called (e.g. a BH was scheduled) */ | ||
92 | @@ -XXX,XX +XXX,XX @@ AioContext *aio_context_new(Error **errp) | ||
93 | |||
94 | aio_set_event_notifier(ctx, &ctx->notifier, | ||
95 | false, | ||
96 | - aio_context_notifier_dummy_cb, | ||
97 | + aio_context_notifier_cb, | ||
98 | aio_context_notifier_poll); | ||
99 | #ifdef CONFIG_LINUX_AIO | ||
100 | ctx->linux_aio = NULL; | ||
101 | -- | ||
102 | 2.26.2 | ||
103 | diff view generated by jsdifflib |