aboutsummaryrefslogtreecommitdiffstats
path: root/fs/aio.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2018-05-23 08:11:02 -0400
committerChristoph Hellwig <hch@lst.de>2018-05-26 03:16:44 -0400
commit888933f8fdf06ecbd5a476b312a37176ab29fb5e (patch)
treebd9a86d1a1740e9be765bde585a6212ad1802990 /fs/aio.c
parentf3a2752a43de18eb2eafa869d06f6e423ff0ce61 (diff)
aio: simplify cancellation
With the current aio code there is no need for the magic KIOCB_CANCELLED value, as a cancelation just kicks the driver to queue the completion ASAP, with all actual completion handling done in another thread. Given that both the completion path and cancelation take the context lock there is no need for magic cmpxchg loops either. If we remove iocbs from the active list after calling ->ki_cancel (but with ctx_lock still held), we can also rely on the invariant thay anything found on the list has a ->ki_cancel callback and can be cancelled, further simplifing the code. Signed-off-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'fs/aio.c')
-rw-r--r--fs/aio.c48
1 files changed, 6 insertions, 42 deletions
diff --git a/fs/aio.c b/fs/aio.c
index 50a90e5581ed..0633cf3b325c 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -164,19 +164,6 @@ struct fsync_iocb {
164 bool datasync; 164 bool datasync;
165}; 165};
166 166
167/*
168 * We use ki_cancel == KIOCB_CANCELLED to indicate that a kiocb has been either
169 * cancelled or completed (this makes a certain amount of sense because
170 * successful cancellation - io_cancel() - does deliver the completion to
171 * userspace).
172 *
173 * And since most things don't implement kiocb cancellation and we'd really like
174 * kiocb completion to be lockless when possible, we use ki_cancel to
175 * synchronize cancellation and completion - we only set it to KIOCB_CANCELLED
176 * with xchg() or cmpxchg(), see batch_complete_aio() and kiocb_cancel().
177 */
178#define KIOCB_CANCELLED ((void *) (~0ULL))
179
180struct aio_kiocb { 167struct aio_kiocb {
181 union { 168 union {
182 struct kiocb rw; 169 struct kiocb rw;
@@ -574,27 +561,6 @@ void kiocb_set_cancel_fn(struct kiocb *iocb, kiocb_cancel_fn *cancel)
574} 561}
575EXPORT_SYMBOL(kiocb_set_cancel_fn); 562EXPORT_SYMBOL(kiocb_set_cancel_fn);
576 563
577static int kiocb_cancel(struct aio_kiocb *kiocb)
578{
579 kiocb_cancel_fn *old, *cancel;
580
581 /*
582 * Don't want to set kiocb->ki_cancel = KIOCB_CANCELLED unless it
583 * actually has a cancel function, hence the cmpxchg()
584 */
585
586 cancel = READ_ONCE(kiocb->ki_cancel);
587 do {
588 if (!cancel || cancel == KIOCB_CANCELLED)
589 return -EINVAL;
590
591 old = cancel;
592 cancel = cmpxchg(&kiocb->ki_cancel, old, KIOCB_CANCELLED);
593 } while (cancel != old);
594
595 return cancel(&kiocb->rw);
596}
597
598/* 564/*
599 * free_ioctx() should be RCU delayed to synchronize against the RCU 565 * free_ioctx() should be RCU delayed to synchronize against the RCU
600 * protected lookup_ioctx() and also needs process context to call 566 * protected lookup_ioctx() and also needs process context to call
@@ -641,7 +607,7 @@ static void free_ioctx_users(struct percpu_ref *ref)
641 while (!list_empty(&ctx->active_reqs)) { 607 while (!list_empty(&ctx->active_reqs)) {
642 req = list_first_entry(&ctx->active_reqs, 608 req = list_first_entry(&ctx->active_reqs,
643 struct aio_kiocb, ki_list); 609 struct aio_kiocb, ki_list);
644 kiocb_cancel(req); 610 req->ki_cancel(&req->rw);
645 list_del_init(&req->ki_list); 611 list_del_init(&req->ki_list);
646 } 612 }
647 613
@@ -1842,8 +1808,8 @@ SYSCALL_DEFINE3(io_cancel, aio_context_t, ctx_id, struct iocb __user *, iocb,
1842{ 1808{
1843 struct kioctx *ctx; 1809 struct kioctx *ctx;
1844 struct aio_kiocb *kiocb; 1810 struct aio_kiocb *kiocb;
1811 int ret = -EINVAL;
1845 u32 key; 1812 u32 key;
1846 int ret;
1847 1813
1848 if (unlikely(get_user(key, &iocb->aio_key))) 1814 if (unlikely(get_user(key, &iocb->aio_key)))
1849 return -EFAULT; 1815 return -EFAULT;
@@ -1855,13 +1821,11 @@ SYSCALL_DEFINE3(io_cancel, aio_context_t, ctx_id, struct iocb __user *, iocb,
1855 return -EINVAL; 1821 return -EINVAL;
1856 1822
1857 spin_lock_irq(&ctx->ctx_lock); 1823 spin_lock_irq(&ctx->ctx_lock);
1858
1859 kiocb = lookup_kiocb(ctx, iocb); 1824 kiocb = lookup_kiocb(ctx, iocb);
1860 if (kiocb) 1825 if (kiocb) {
1861 ret = kiocb_cancel(kiocb); 1826 ret = kiocb->ki_cancel(&kiocb->rw);
1862 else 1827 list_del_init(&kiocb->ki_list);
1863 ret = -EINVAL; 1828 }
1864
1865 spin_unlock_irq(&ctx->ctx_lock); 1829 spin_unlock_irq(&ctx->ctx_lock);
1866 1830
1867 if (!ret) { 1831 if (!ret) {