|
@@ -68,9 +68,9 @@ struct aio_ring {
|
|
|
#define AIO_RING_PAGES 8
|
|
|
|
|
|
struct kioctx_table {
|
|
|
- struct rcu_head rcu;
|
|
|
- unsigned nr;
|
|
|
- struct kioctx *table[];
|
|
|
+ struct rcu_head rcu;
|
|
|
+ unsigned nr;
|
|
|
+ struct kioctx __rcu *table[];
|
|
|
};
|
|
|
|
|
|
struct kioctx_cpu {
|
|
@@ -330,7 +330,7 @@ static int aio_ring_mremap(struct vm_area_struct *vma)
|
|
|
for (i = 0; i < table->nr; i++) {
|
|
|
struct kioctx *ctx;
|
|
|
|
|
|
- ctx = table->table[i];
|
|
|
+ ctx = rcu_dereference(table->table[i]);
|
|
|
if (ctx && ctx->aio_ring_file == file) {
|
|
|
if (!atomic_read(&ctx->dead)) {
|
|
|
ctx->user_id = ctx->mmap_base = vma->vm_start;
|
|
@@ -666,9 +666,9 @@ static int ioctx_add_table(struct kioctx *ctx, struct mm_struct *mm)
|
|
|
while (1) {
|
|
|
if (table)
|
|
|
for (i = 0; i < table->nr; i++)
|
|
|
- if (!table->table[i]) {
|
|
|
+ if (!rcu_access_pointer(table->table[i])) {
|
|
|
ctx->id = i;
|
|
|
- table->table[i] = ctx;
|
|
|
+ rcu_assign_pointer(table->table[i], ctx);
|
|
|
spin_unlock(&mm->ioctx_lock);
|
|
|
|
|
|
/* While kioctx setup is in progress,
|
|
@@ -849,8 +849,8 @@ static int kill_ioctx(struct mm_struct *mm, struct kioctx *ctx,
|
|
|
}
|
|
|
|
|
|
table = rcu_dereference_raw(mm->ioctx_table);
|
|
|
- WARN_ON(ctx != table->table[ctx->id]);
|
|
|
- table->table[ctx->id] = NULL;
|
|
|
+ WARN_ON(ctx != rcu_access_pointer(table->table[ctx->id]));
|
|
|
+ RCU_INIT_POINTER(table->table[ctx->id], NULL);
|
|
|
spin_unlock(&mm->ioctx_lock);
|
|
|
|
|
|
/* free_ioctx_reqs() will do the necessary RCU synchronization */
|
|
@@ -895,7 +895,8 @@ void exit_aio(struct mm_struct *mm)
|
|
|
|
|
|
skipped = 0;
|
|
|
for (i = 0; i < table->nr; ++i) {
|
|
|
- struct kioctx *ctx = table->table[i];
|
|
|
+ struct kioctx *ctx =
|
|
|
+ rcu_dereference_protected(table->table[i], true);
|
|
|
|
|
|
if (!ctx) {
|
|
|
skipped++;
|
|
@@ -1084,7 +1085,7 @@ static struct kioctx *lookup_ioctx(unsigned long ctx_id)
|
|
|
if (!table || id >= table->nr)
|
|
|
goto out;
|
|
|
|
|
|
- ctx = table->table[id];
|
|
|
+ ctx = rcu_dereference(table->table[id]);
|
|
|
if (ctx && ctx->user_id == ctx_id) {
|
|
|
percpu_ref_get(&ctx->users);
|
|
|
ret = ctx;
|