3.16.57-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Oleg Nesterov oleg@redhat.com
commit 855ef0dec7271ff7be7381feaaf3f4aed80bd503 upstream.
ioctx_add_table() is the writer, it does not need rcu_read_lock() to protect ->ioctx_table. It relies on mm->ioctx_lock and rcu locks just add the confusion.
And it doesn't need rcu_dereference() by the same reason, it must see any updates previously done under the same ->ioctx_lock. We could use rcu_dereference_protected() but the patch uses rcu_dereference_raw(), the function is simple enough.
The same for kill_ioctx(), although it does not update the pointer.
Signed-off-by: Oleg Nesterov oleg@redhat.com Signed-off-by: Benjamin LaHaise bcrl@kvack.org Signed-off-by: Ben Hutchings ben@decadent.org.uk --- fs/aio.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-)
--- a/fs/aio.c +++ b/fs/aio.c @@ -563,8 +563,7 @@ static int ioctx_add_table(struct kioctx struct aio_ring *ring;
spin_lock(&mm->ioctx_lock); - rcu_read_lock(); - table = rcu_dereference(mm->ioctx_table); + table = rcu_dereference_raw(mm->ioctx_table);
while (1) { if (table) @@ -572,7 +571,6 @@ static int ioctx_add_table(struct kioctx if (!table->table[i]) { ctx->id = i; table->table[i] = ctx; - rcu_read_unlock(); spin_unlock(&mm->ioctx_lock);
/* While kioctx setup is in progress, @@ -586,8 +584,6 @@ static int ioctx_add_table(struct kioctx }
new_nr = (table ? table->nr : 1) * 4; - - rcu_read_unlock(); spin_unlock(&mm->ioctx_lock);
table = kzalloc(sizeof(*table) + sizeof(struct kioctx *) * @@ -598,8 +594,7 @@ static int ioctx_add_table(struct kioctx table->nr = new_nr;
spin_lock(&mm->ioctx_lock); - rcu_read_lock(); - old = rcu_dereference(mm->ioctx_table); + old = rcu_dereference_raw(mm->ioctx_table);
if (!old) { rcu_assign_pointer(mm->ioctx_table, table); @@ -749,12 +744,9 @@ static int kill_ioctx(struct mm_struct *
spin_lock(&mm->ioctx_lock); - rcu_read_lock(); - table = rcu_dereference(mm->ioctx_table); - + table = rcu_dereference_raw(mm->ioctx_table); WARN_ON(ctx != table->table[ctx->id]); table->table[ctx->id] = NULL; - rcu_read_unlock(); spin_unlock(&mm->ioctx_lock);
/* percpu_ref_kill() will do the necessary call_rcu() */