aio: allow direct aio poll comletions for keyed wakeups
If we get a keyed wakeup for a aio poll waitqueue and wake can acquire the ctx_lock without spinning we can just complete the iocb straight from the wakeup callback to avoid a context switch. Signed-off-by: Christoph Hellwig <hch@lst.de> Tested-by: Avi Kivity <avi@scylladb.com>
This commit is contained in:
Родитель
bfe4037e72
Коммит
e8693bcfa0
15
fs/aio.c
15
fs/aio.c
|
@ -1672,14 +1672,27 @@ static int aio_poll_wake(struct wait_queue_entry *wait, unsigned mode, int sync,
|
||||||
void *key)
|
void *key)
|
||||||
{
|
{
|
||||||
struct poll_iocb *req = container_of(wait, struct poll_iocb, wait);
|
struct poll_iocb *req = container_of(wait, struct poll_iocb, wait);
|
||||||
|
struct aio_kiocb *iocb = container_of(req, struct aio_kiocb, poll);
|
||||||
__poll_t mask = key_to_poll(key);
|
__poll_t mask = key_to_poll(key);
|
||||||
|
|
||||||
req->woken = true;
|
req->woken = true;
|
||||||
|
|
||||||
/* for instances that support it check for an event match first: */
|
/* for instances that support it check for an event match first: */
|
||||||
if (mask && !(mask & req->events))
|
if (mask) {
|
||||||
|
if (!(mask & req->events))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
/* try to complete the iocb inline if we can: */
|
||||||
|
if (spin_trylock(&iocb->ki_ctx->ctx_lock)) {
|
||||||
|
list_del(&iocb->ki_list);
|
||||||
|
spin_unlock(&iocb->ki_ctx->ctx_lock);
|
||||||
|
|
||||||
|
list_del_init(&req->wait.entry);
|
||||||
|
aio_poll_complete(iocb, mask);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
list_del_init(&req->wait.entry);
|
list_del_init(&req->wait.entry);
|
||||||
schedule_work(&req->work);
|
schedule_work(&req->work);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче