lkml.org 
[lkml]   [2018]   [Jun]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Date
    Subject[PATCH 3.16 358/410] fs/aio: Use RCU accessors for kioctx_table->table[]
    3.16.57-rc1 review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Tejun Heo <tj@kernel.org>

    commit d0264c01e7587001a8c4608a5d1818dba9a4c11a upstream.

    While converting ioctx index from a list to a table, db446a08c23d
    ("aio: convert the ioctx list to table lookup v3") missed tagging
    kioctx_table->table[] as an array of RCU pointers and using the
    appropriate RCU accessors. This introduces a small window in the
    lookup path where init and access may race.

    Mark kioctx_table->table[] with __rcu and use the approriate RCU
    accessors when using the field.

    Signed-off-by: Tejun Heo <tj@kernel.org>
    Reported-by: Jann Horn <jannh@google.com>
    Fixes: db446a08c23d ("aio: convert the ioctx list to table lookup v3")
    Cc: Benjamin LaHaise <bcrl@kvack.org>
    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    [bwh: Backported to 3.16:
    - Drop changes to aio_ring_mremap()
    -
    Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
    ---
    fs/aio.c | 21 +++++++++++----------
    1 file changed, 11 insertions(+), 10 deletions(-)

    --- a/fs/aio.c
    +++ b/fs/aio.c
    @@ -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 {
    @@ -588,9 +588,9 @@ static int ioctx_add_table(struct kioctx
    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,
    @@ -765,8 +765,8 @@ static int kill_ioctx(struct mm_struct *

    spin_lock(&mm->ioctx_lock);
    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 */
    @@ -827,7 +827,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++;
    @@ -1022,7 +1023,7 @@ static struct kioctx *lookup_ioctx(unsig
    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;
    \
     
     \ /
      Last update: 2018-06-07 17:03    [W:4.056 / U:0.040 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site