diff options
author | Christoph Hellwig <hch@lst.de> | 2018-05-20 13:19:30 -0400 |
---|---|---|
committer | Christoph Hellwig <hch@lst.de> | 2018-05-26 03:16:44 -0400 |
commit | 1962da0d2198a00a056a2915fbc6ec684c3bef0a (patch) | |
tree | aec374beb42fb7e8d6dc95a602a1cd257df3ba82 /fs/aio.c | |
parent | 2c14fa838cbefc23cf1c73ca167ed85b274b2913 (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.c | 20 |
1 files changed, 17 insertions, 3 deletions
@@ -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 | ||