diff options
author | Kent Overstreet <koverstreet@google.com> | 2013-05-07 19:18:39 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-07 21:38:28 -0400 |
commit | 11599ebac4a249ab3c8b9a535c21db7a51458c0a (patch) | |
tree | c5927106704034f4dbe6c10ae2c2c6bd60df42d8 /include/linux/aio.h | |
parent | 1d98ebfccc15aeea87a7c48d50d7343e1ce8daae (diff) |
aio: make aio_put_req() lockless
Freeing a kiocb needed to touch the kioctx for three things:
* Pull it off the reqs_active list
* Decrementing reqs_active
* Issuing a wakeup, if the kioctx was in the process of being freed.
This patch moves these to aio_complete(), for a couple reasons:
* aio_complete() already has to issue the wakeup, so if we drop the
kioctx refcount before aio_complete does its wakeup we don't have to
do it twice.
* aio_complete currently has to take the kioctx lock, so it makes sense
for it to pull the kiocb off the reqs_active list too.
* A later patch is going to change reqs_active to include unreaped
completions - this will mean allocating a kiocb doesn't have to look
at the ringbuffer. So taking the decrement of reqs_active out of
kiocb_free() is useful prep work for that patch.
This doesn't really affect cancellation, since existing (usb) code that
implements a cancel function still calls aio_complete() - we just have
to make sure that aio_complete does the necessary teardown for cancelled
kiocbs.
It does affect code paths where we free kiocbs that were never
submitted; they need to decrement reqs_active and pull the kiocb off the
reqs_active list. This occurs in two places: kiocb_batch_free(), which
is going away in a later patch, and the error path in io_submit_one.
[akpm@linux-foundation.org: coding-style fixes]
Signed-off-by: Kent Overstreet <koverstreet@google.com>
Cc: Zach Brown <zab@redhat.com>
Cc: Felipe Balbi <balbi@ti.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Mark Fasheh <mfasheh@suse.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: Asai Thambi S P <asamymuthupa@micron.com>
Cc: Selvan Mani <smani@micron.com>
Cc: Sam Bradshaw <sbradshaw@micron.com>
Acked-by: Jeff Moyer <jmoyer@redhat.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Benjamin LaHaise <bcrl@kvack.org>
Reviewed-by: "Theodore Ts'o" <tytso@mit.edu>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include/linux/aio.h')
-rw-r--r-- | include/linux/aio.h | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/include/linux/aio.h b/include/linux/aio.h index 7b1eb234e0ab..1e728f0086f8 100644 --- a/include/linux/aio.h +++ b/include/linux/aio.h | |||
@@ -49,7 +49,7 @@ struct kioctx; | |||
49 | */ | 49 | */ |
50 | struct kiocb { | 50 | struct kiocb { |
51 | unsigned long ki_flags; | 51 | unsigned long ki_flags; |
52 | int ki_users; | 52 | atomic_t ki_users; |
53 | unsigned ki_key; /* id of this request */ | 53 | unsigned ki_key; /* id of this request */ |
54 | 54 | ||
55 | struct file *ki_filp; | 55 | struct file *ki_filp; |
@@ -96,7 +96,7 @@ static inline bool is_sync_kiocb(struct kiocb *kiocb) | |||
96 | static inline void init_sync_kiocb(struct kiocb *kiocb, struct file *filp) | 96 | static inline void init_sync_kiocb(struct kiocb *kiocb, struct file *filp) |
97 | { | 97 | { |
98 | *kiocb = (struct kiocb) { | 98 | *kiocb = (struct kiocb) { |
99 | .ki_users = 1, | 99 | .ki_users = ATOMIC_INIT(1), |
100 | .ki_key = KIOCB_SYNC_KEY, | 100 | .ki_key = KIOCB_SYNC_KEY, |
101 | .ki_filp = filp, | 101 | .ki_filp = filp, |
102 | .ki_obj.tsk = current, | 102 | .ki_obj.tsk = current, |