[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH v2 3/3] aio-posix: keep aio_notify_me disabled during polling
From: |
Paolo Bonzini |
Subject: |
Re: [PATCH v2 3/3] aio-posix: keep aio_notify_me disabled during polling |
Date: |
Wed, 5 Aug 2020 18:37:45 +0200 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.9.0 |
On 05/08/20 12:00, Stefan Hajnoczi wrote:
> +
> + /*
> + * aio_notify can avoid the expensive event_notifier_set if
> + * everything (file descriptors, bottom halves, timers) will
> + * be re-evaluated before the next blocking poll(). This is
> + * already true when aio_poll is called with blocking == false;
> + * if blocking == true, it is only true after poll() returns,
> + * so disable the optimization now.
> + */
> + if (use_notify_me) {
> + atomic_set(&ctx->notify_me, atomic_read(&ctx->notify_me) + 2);
> + /*
> + * Write ctx->notify_me before reading ctx->notified. Pairs with
> + * smp_mb in aio_notify().
> + */
> + smp_mb();
> +
> + /* Don't block if aio_notify() was called */
> + if (atomic_read(&ctx->notified)) {
> + timeout = 0;
> + }
Aha, this is the trick: "timeout = 0" also applies if a timer was moved
early. In this case you uselessly keep notify_me set for a bit, but
it's okay. Nice!
The code can be simplified a bit more, since the use_notify_me variable
is just "timeout":
use_notify_me = (timeout != 0);
if (use_notify_me) {
/*
* aio_notify can avoid the expensive event_notifier_set if
* everything (file descriptors, bottom halves, timers) will
* be re-evaluated before the next blocking poll(). This is
* already true when aio_poll is called with blocking == false;
* if blocking == true, it is only true after poll() returns,
* so disable the optimization now.
*/
atomic_set(&ctx->notify_me, atomic_read(&ctx->notify_me) + 2);
/*
* Write ctx->notify_me before reading ctx->notified. Pairs with
* smp_mb in aio_notify().
*/
smp_mb();
/* Don't block if aio_notify() was called */
if (atomic_read(&ctx->notified)) {
timeout = 0;
}
}
if (timeout || ctx->fdmon_ops->need_wait(ctx)) {
ret = ctx->fdmon_ops->wait(ctx, &ready_list, timeout);
}
if (use_notify_me) {
/* Finish the poll before clearing the flag. */
atomic_store_release(&ctx->notify_me,
atomic_read(&ctx->notify_me) - 2);
}
Paolo