lkml.org 
[lkml]   [2016]   [May]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4/4] locking/rwsem: Rework zeroing reader waiter->task
    Date
    Readers that are awoken will expect a nil ->task indicating
    that a wakeup has occurred. There is a mismatch between the
    smp_mb() and its documentation, in that the serialization is
    done between reading the task and the nil store. Furthermore,
    in addition to having the overlapping of loads and stores to
    waiter->task guaranteed to be ordered within that CPU, both
    wake_up_process() originally and now wake_q_add() already
    imply barriers upon successful calls, which serves the comment.

    Just atomically do a xchg() and simplify the whole thing. We can
    use relaxed semantics as before mentioned in addition to the
    barrier provided by wake_q_add(), delaying there is no risk in
    reordering with the actual wakeup.

    Signed-off-by: Davidlohr Bueso <dbueso@suse.de>
    ---
    kernel/locking/rwsem-xadd.c | 17 +++++------------
    1 file changed, 5 insertions(+), 12 deletions(-)

    diff --git a/kernel/locking/rwsem-xadd.c b/kernel/locking/rwsem-xadd.c
    index 1b8c1285a2aa..96e53cb4a4db 100644
    --- a/kernel/locking/rwsem-xadd.c
    +++ b/kernel/locking/rwsem-xadd.c
    @@ -126,7 +126,6 @@ __rwsem_mark_wake(struct rw_semaphore *sem,
    enum rwsem_wake_type wake_type, struct wake_q_head *wake_q)
    {
    struct rwsem_waiter *waiter;
    - struct task_struct *tsk;
    struct list_head *next;
    long oldcount, woken, loop, adjustment;

    @@ -190,24 +189,18 @@ __rwsem_mark_wake(struct rw_semaphore *sem,
    next = sem->wait_list.next;
    loop = woken;
    do {
    + struct task_struct *tsk;
    +
    waiter = list_entry(next, struct rwsem_waiter, list);
    next = waiter->list.next;
    - tsk = waiter->task;
    - /*
    - * Make sure we do not wakeup the next reader before
    - * setting the nil condition to grant the next reader;
    - * otherwise we could miss the wakeup on the other
    - * side and end up sleeping again. See the pairing
    - * in rwsem_down_read_failed().
    - */
    - smp_mb();
    - waiter->task = NULL;
    +
    + tsk = xchg_relaxed(&waiter->task, NULL);
    wake_q_add(wake_q, tsk);
    } while (--loop);

    sem->wait_list.next = next;
    next->prev = &sem->wait_list;
    - out:
    +out:
    return sem;
    }

    --
    2.8.1
    \
     
     \ /
      Last update: 2016-05-09 07:21    [W:2.113 / U:0.348 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site