|
|
357786 |
From 451a04350505ac3078620cacc1c89389c848e6c5 Mon Sep 17 00:00:00 2001
|
|
|
357786 |
From: Fam Zheng <famz@redhat.com>
|
|
|
357786 |
Date: Tue, 18 Sep 2018 09:07:13 +0200
|
|
|
357786 |
Subject: [PATCH 2/3] aio-posix: compute timeout before polling
|
|
|
357786 |
|
|
|
357786 |
RH-Author: Fam Zheng <famz@redhat.com>
|
|
|
357786 |
Message-id: <20180918090714.18069-3-famz@redhat.com>
|
|
|
357786 |
Patchwork-id: 82213
|
|
|
357786 |
O-Subject: [RHEL-7.6 qemu-kvm-rhev PATCH 2/3] aio-posix: compute timeout before polling
|
|
|
357786 |
Bugzilla: 1628191
|
|
|
357786 |
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
357786 |
RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
|
|
|
357786 |
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
|
|
357786 |
|
|
|
357786 |
From: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
357786 |
|
|
|
357786 |
This is a preparation for the next patch, and also a very small
|
|
|
357786 |
optimization. Compute the timeout only once, before invoking
|
|
|
357786 |
try_poll_mode, and adjust it in run_poll_handlers. The adjustment
|
|
|
357786 |
is the polling time when polling fails, or zero (non-blocking) if
|
|
|
357786 |
polling succeeds.
|
|
|
357786 |
|
|
|
357786 |
Fixes: 70232b5253a3c4e03ed1ac47ef9246a8ac66c6fa
|
|
|
357786 |
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
357786 |
Message-Id: <20180912171040.1732-3-pbonzini@redhat.com>
|
|
|
357786 |
Reviewed-by: Fam Zheng <famz@redhat.com>
|
|
|
357786 |
Signed-off-by: Fam Zheng <famz@redhat.com>
|
|
|
357786 |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
357786 |
---
|
|
|
357786 |
util/aio-posix.c | 59 ++++++++++++++++++++++++++++++++-----------------------
|
|
|
357786 |
util/trace-events | 4 ++--
|
|
|
357786 |
2 files changed, 36 insertions(+), 27 deletions(-)
|
|
|
357786 |
|
|
|
357786 |
diff --git a/util/aio-posix.c b/util/aio-posix.c
|
|
|
357786 |
index 1d7cc53..1b17597 100644
|
|
|
357786 |
--- a/util/aio-posix.c
|
|
|
357786 |
+++ b/util/aio-posix.c
|
|
|
357786 |
@@ -490,7 +490,7 @@ static void add_pollfd(AioHandler *node)
|
|
|
357786 |
npfd++;
|
|
|
357786 |
}
|
|
|
357786 |
|
|
|
357786 |
-static bool run_poll_handlers_once(AioContext *ctx)
|
|
|
357786 |
+static bool run_poll_handlers_once(AioContext *ctx, int64_t *timeout)
|
|
|
357786 |
{
|
|
|
357786 |
bool progress = false;
|
|
|
357786 |
AioHandler *node;
|
|
|
357786 |
@@ -500,6 +500,7 @@ static bool run_poll_handlers_once(AioContext *ctx)
|
|
|
357786 |
aio_node_check(ctx, node->is_external) &&
|
|
|
357786 |
node->io_poll(node->opaque) &&
|
|
|
357786 |
node->opaque != &ctx->notifier) {
|
|
|
357786 |
+ *timeout = 0;
|
|
|
357786 |
progress = true;
|
|
|
357786 |
}
|
|
|
357786 |
|
|
|
357786 |
@@ -522,31 +523,38 @@ static bool run_poll_handlers_once(AioContext *ctx)
|
|
|
357786 |
*
|
|
|
357786 |
* Returns: true if progress was made, false otherwise
|
|
|
357786 |
*/
|
|
|
357786 |
-static bool run_poll_handlers(AioContext *ctx, int64_t max_ns)
|
|
|
357786 |
+static bool run_poll_handlers(AioContext *ctx, int64_t max_ns, int64_t *timeout)
|
|
|
357786 |
{
|
|
|
357786 |
bool progress;
|
|
|
357786 |
- int64_t end_time;
|
|
|
357786 |
+ int64_t start_time, elapsed_time;
|
|
|
357786 |
|
|
|
357786 |
assert(ctx->notify_me);
|
|
|
357786 |
assert(qemu_lockcnt_count(&ctx->list_lock) > 0);
|
|
|
357786 |
|
|
|
357786 |
- trace_run_poll_handlers_begin(ctx, max_ns);
|
|
|
357786 |
-
|
|
|
357786 |
- end_time = qemu_clock_get_ns(QEMU_CLOCK_REALTIME) + max_ns;
|
|
|
357786 |
+ trace_run_poll_handlers_begin(ctx, max_ns, *timeout);
|
|
|
357786 |
|
|
|
357786 |
+ start_time = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
|
|
|
357786 |
do {
|
|
|
357786 |
- progress = run_poll_handlers_once(ctx);
|
|
|
357786 |
- } while (!progress && qemu_clock_get_ns(QEMU_CLOCK_REALTIME) < end_time
|
|
|
357786 |
+ progress = run_poll_handlers_once(ctx, timeout);
|
|
|
357786 |
+ elapsed_time = qemu_clock_get_ns(QEMU_CLOCK_REALTIME) - start_time;
|
|
|
357786 |
+ } while (!progress && elapsed_time < max_ns
|
|
|
357786 |
&& !atomic_read(&ctx->poll_disable_cnt));
|
|
|
357786 |
|
|
|
357786 |
- trace_run_poll_handlers_end(ctx, progress);
|
|
|
357786 |
+ /* If time has passed with no successful polling, adjust *timeout to
|
|
|
357786 |
+ * keep the same ending time.
|
|
|
357786 |
+ */
|
|
|
357786 |
+ if (*timeout != -1) {
|
|
|
357786 |
+ *timeout -= MIN(*timeout, elapsed_time);
|
|
|
357786 |
+ }
|
|
|
357786 |
|
|
|
357786 |
+ trace_run_poll_handlers_end(ctx, progress, *timeout);
|
|
|
357786 |
return progress;
|
|
|
357786 |
}
|
|
|
357786 |
|
|
|
357786 |
/* try_poll_mode:
|
|
|
357786 |
* @ctx: the AioContext
|
|
|
357786 |
- * @blocking: busy polling is only attempted when blocking is true
|
|
|
357786 |
+ * @timeout: timeout for blocking wait, computed by the caller and updated if
|
|
|
357786 |
+ * polling succeeds.
|
|
|
357786 |
*
|
|
|
357786 |
* ctx->notify_me must be non-zero so this function can detect aio_notify().
|
|
|
357786 |
*
|
|
|
357786 |
@@ -554,19 +562,16 @@ static bool run_poll_handlers(AioContext *ctx, int64_t max_ns)
|
|
|
357786 |
*
|
|
|
357786 |
* Returns: true if progress was made, false otherwise
|
|
|
357786 |
*/
|
|
|
357786 |
-static bool try_poll_mode(AioContext *ctx, bool blocking)
|
|
|
357786 |
+static bool try_poll_mode(AioContext *ctx, int64_t *timeout)
|
|
|
357786 |
{
|
|
|
357786 |
- if (blocking && ctx->poll_max_ns && !atomic_read(&ctx->poll_disable_cnt)) {
|
|
|
357786 |
- /* See qemu_soonest_timeout() uint64_t hack */
|
|
|
357786 |
- int64_t max_ns = MIN((uint64_t)aio_compute_timeout(ctx),
|
|
|
357786 |
- (uint64_t)ctx->poll_ns);
|
|
|
357786 |
+ /* See qemu_soonest_timeout() uint64_t hack */
|
|
|
357786 |
+ int64_t max_ns = MIN((uint64_t)*timeout, (uint64_t)ctx->poll_ns);
|
|
|
357786 |
|
|
|
357786 |
- if (max_ns) {
|
|
|
357786 |
- poll_set_started(ctx, true);
|
|
|
357786 |
+ if (max_ns && !atomic_read(&ctx->poll_disable_cnt)) {
|
|
|
357786 |
+ poll_set_started(ctx, true);
|
|
|
357786 |
|
|
|
357786 |
- if (run_poll_handlers(ctx, max_ns)) {
|
|
|
357786 |
- return true;
|
|
|
357786 |
- }
|
|
|
357786 |
+ if (run_poll_handlers(ctx, max_ns, timeout)) {
|
|
|
357786 |
+ return true;
|
|
|
357786 |
}
|
|
|
357786 |
}
|
|
|
357786 |
|
|
|
357786 |
@@ -575,7 +580,7 @@ static bool try_poll_mode(AioContext *ctx, bool blocking)
|
|
|
357786 |
/* Even if we don't run busy polling, try polling once in case it can make
|
|
|
357786 |
* progress and the caller will be able to avoid ppoll(2)/epoll_wait(2).
|
|
|
357786 |
*/
|
|
|
357786 |
- return run_poll_handlers_once(ctx);
|
|
|
357786 |
+ return run_poll_handlers_once(ctx, timeout);
|
|
|
357786 |
}
|
|
|
357786 |
|
|
|
357786 |
bool aio_poll(AioContext *ctx, bool blocking)
|
|
|
357786 |
@@ -605,8 +610,14 @@ bool aio_poll(AioContext *ctx, bool blocking)
|
|
|
357786 |
start = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
|
|
|
357786 |
}
|
|
|
357786 |
|
|
|
357786 |
- progress = try_poll_mode(ctx, blocking);
|
|
|
357786 |
- if (!progress) {
|
|
|
357786 |
+ timeout = blocking ? aio_compute_timeout(ctx) : 0;
|
|
|
357786 |
+ progress = try_poll_mode(ctx, &timeout);
|
|
|
357786 |
+ assert(!(timeout && progress));
|
|
|
357786 |
+
|
|
|
357786 |
+ /* If polling is allowed, non-blocking aio_poll does not need the
|
|
|
357786 |
+ * system call---a single round of run_poll_handlers_once suffices.
|
|
|
357786 |
+ */
|
|
|
357786 |
+ if (timeout || atomic_read(&ctx->poll_disable_cnt)) {
|
|
|
357786 |
assert(npfd == 0);
|
|
|
357786 |
|
|
|
357786 |
/* fill pollfds */
|
|
|
357786 |
@@ -620,8 +631,6 @@ bool aio_poll(AioContext *ctx, bool blocking)
|
|
|
357786 |
}
|
|
|
357786 |
}
|
|
|
357786 |
|
|
|
357786 |
- timeout = blocking ? aio_compute_timeout(ctx) : 0;
|
|
|
357786 |
-
|
|
|
357786 |
/* wait until next event */
|
|
|
357786 |
if (aio_epoll_check_poll(ctx, pollfds, npfd, timeout)) {
|
|
|
357786 |
AioHandler epoll_handler;
|
|
|
357786 |
diff --git a/util/trace-events b/util/trace-events
|
|
|
357786 |
index 4822434..79569b7 100644
|
|
|
357786 |
--- a/util/trace-events
|
|
|
357786 |
+++ b/util/trace-events
|
|
|
357786 |
@@ -1,8 +1,8 @@
|
|
|
357786 |
# See docs/devel/tracing.txt for syntax documentation.
|
|
|
357786 |
|
|
|
357786 |
# util/aio-posix.c
|
|
|
357786 |
-run_poll_handlers_begin(void *ctx, int64_t max_ns) "ctx %p max_ns %"PRId64
|
|
|
357786 |
-run_poll_handlers_end(void *ctx, bool progress) "ctx %p progress %d"
|
|
|
357786 |
+run_poll_handlers_begin(void *ctx, int64_t max_ns, int64_t timeout) "ctx %p max_ns %"PRId64 " timeout %"PRId64
|
|
|
357786 |
+run_poll_handlers_end(void *ctx, bool progress, int64_t timeout) "ctx %p progress %d new timeout %"PRId64
|
|
|
357786 |
poll_shrink(void *ctx, int64_t old, int64_t new) "ctx %p old %"PRId64" new %"PRId64
|
|
|
357786 |
poll_grow(void *ctx, int64_t old, int64_t new) "ctx %p old %"PRId64" new %"PRId64
|
|
|
357786 |
|
|
|
357786 |
--
|
|
|
357786 |
1.8.3.1
|
|
|
357786 |
|