[PATCH 3.16 355/410] aio: kill the misleading rcu read locks in ioctx_add_table() and kill_ioctx()
From: Ben Hutchings
Date: Thu Jun 07 2018 - 11:22:25 EST
3.16.57-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Oleg Nesterov <oleg@xxxxxxxxxx>
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@xxxxxxxxxx>
Signed-off-by: Benjamin LaHaise <bcrl@xxxxxxxxx>
Signed-off-by: Ben Hutchings <ben@xxxxxxxxxxxxxxx>
---
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() */