aboutsummaryrefslogtreecommitdiffstats
path: root/fs/aio.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2018-05-20 13:19:30 -0400
committerChristoph Hellwig <hch@lst.de>2018-05-26 03:16:44 -0400
commit1962da0d2198a00a056a2915fbc6ec684c3bef0a (patch)
treeaec374beb42fb7e8d6dc95a602a1cd257df3ba82 /fs/aio.c
parent2c14fa838cbefc23cf1c73ca167ed85b274b2913 (diff)
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>
Diffstat (limited to 'fs/aio.c')
-rw-r--r--fs/aio.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/fs/aio.c b/fs/aio.c
index bd711cfa4a1f..8274d09d44a2 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -1633,6 +1633,7 @@ static int aio_poll_wake(struct wait_queue_entry *wait, unsigned mode, int sync,
1633 void *key) 1633 void *key)
1634{ 1634{
1635 struct poll_iocb *req = container_of(wait, struct poll_iocb, wait); 1635 struct poll_iocb *req = container_of(wait, struct poll_iocb, wait);
1636 struct aio_kiocb *iocb = container_of(req, struct aio_kiocb, poll);
1636 struct file *file = req->file; 1637 struct file *file = req->file;
1637 __poll_t mask = key_to_poll(key); 1638 __poll_t mask = key_to_poll(key);
1638 1639
@@ -1648,9 +1649,22 @@ static int aio_poll_wake(struct wait_queue_entry *wait, unsigned mode, int sync,
1648 1649
1649 __aio_poll_remove(req); 1650 __aio_poll_remove(req);
1650 1651
1651 req->events = mask; 1652 /*
1652 INIT_WORK(&req->work, aio_poll_work); 1653 * Try completing without a context switch if we can acquire ctx_lock
1653 schedule_work(&req->work); 1654 * without spinning. Otherwise we need to defer to a workqueue to
1655 * avoid a deadlock due to the lock order.
1656 */
1657 if (spin_trylock(&iocb->ki_ctx->ctx_lock)) {
1658 list_del_init(&iocb->ki_list);
1659 spin_unlock(&iocb->ki_ctx->ctx_lock);
1660
1661 __aio_poll_complete(req, mask);
1662 } else {
1663 req->events = mask;
1664 INIT_WORK(&req->work, aio_poll_work);
1665 schedule_work(&req->work);
1666 }
1667
1654 return 1; 1668 return 1;
1655} 1669}
1656 1670