aio: try to complete poll iocbs without context switch
If we can acquire ctx_lock without spinning we can just remove our iocb from the active_reqs list, and thus complete the iocbs from the wakeup context. Signed-off-by: Christoph Hellwig <hch@lst.de>
This commit is contained in:
parent
2c14fa838c
commit
1962da0d21
20
fs/aio.c
20
fs/aio.c
|
@ -1633,6 +1633,7 @@ 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);
|
||||||
struct file *file = req->file;
|
struct file *file = req->file;
|
||||||
__poll_t mask = key_to_poll(key);
|
__poll_t mask = key_to_poll(key);
|
||||||
|
|
||||||
|
@ -1648,9 +1649,22 @@ static int aio_poll_wake(struct wait_queue_entry *wait, unsigned mode, int sync,
|
||||||
|
|
||||||
__aio_poll_remove(req);
|
__aio_poll_remove(req);
|
||||||
|
|
||||||
req->events = mask;
|
/*
|
||||||
INIT_WORK(&req->work, aio_poll_work);
|
* Try completing without a context switch if we can acquire ctx_lock
|
||||||
schedule_work(&req->work);
|
* without spinning. Otherwise we need to defer to a workqueue to
|
||||||
|
* avoid a deadlock due to the lock order.
|
||||||
|
*/
|
||||||
|
if (spin_trylock(&iocb->ki_ctx->ctx_lock)) {
|
||||||
|
list_del_init(&iocb->ki_list);
|
||||||
|
spin_unlock(&iocb->ki_ctx->ctx_lock);
|
||||||
|
|
||||||
|
__aio_poll_complete(req, mask);
|
||||||
|
} else {
|
||||||
|
req->events = mask;
|
||||||
|
INIT_WORK(&req->work, aio_poll_work);
|
||||||
|
schedule_work(&req->work);
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue