lkml.org 
[lkml]   [2022]   [Oct]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    Subject[RFC PATCH 02/11] locking/mutex: Rework task_struct::blocked_on
    From
    From: Peter Zijlstra <peterz@infradead.org>

    Track the blocked-on relation for mutexes, this allows following this
    relation at schedule time.

    task
    | blocked-on
    v
    mutex
    | owner
    v
    task

    Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
    [minor changes while rebasing]
    Signed-off-by: Juri Lelli <juri.lelli@redhat.com>
    Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
    Signed-off-by: Connor O'Brien <connoro@google.com>
    Link: https://lkml.kernel.org/r/20181009092434.26221-4-juri.lelli@redhat.com
    ---
    include/linux/sched.h | 6 ++----
    kernel/fork.c | 4 ++--
    kernel/locking/mutex-debug.c | 9 +++++----
    kernel/locking/mutex.c | 6 ++++++
    4 files changed, 15 insertions(+), 10 deletions(-)

    diff --git a/include/linux/sched.h b/include/linux/sched.h
    index e7b2f8a5c711..bd995e66d7d6 100644
    --- a/include/linux/sched.h
    +++ b/include/linux/sched.h
    @@ -1130,10 +1130,8 @@ struct task_struct {
    struct rt_mutex_waiter *pi_blocked_on;
    #endif

    -#ifdef CONFIG_DEBUG_MUTEXES
    - /* Mutex deadlock detection: */
    - struct mutex_waiter *blocked_on;
    -#endif
    + struct task_struct *blocked_proxy; /* task that is boosting us */
    + struct mutex *blocked_on; /* lock we're blocked on */

    #ifdef CONFIG_DEBUG_ATOMIC_SLEEP
    int non_block_count;
    diff --git a/kernel/fork.c b/kernel/fork.c
    index 2b6bd511c6ed..81e809c343fd 100644
    --- a/kernel/fork.c
    +++ b/kernel/fork.c
    @@ -2208,9 +2208,9 @@ static __latent_entropy struct task_struct *copy_process(
    lockdep_init_task(p);
    #endif

    -#ifdef CONFIG_DEBUG_MUTEXES
    + p->blocked_proxy = NULL; /* nobody is boosting us yet */
    p->blocked_on = NULL; /* not blocked yet */
    -#endif
    +
    #ifdef CONFIG_BCACHE
    p->sequential_io = 0;
    p->sequential_io_avg = 0;
    diff --git a/kernel/locking/mutex-debug.c b/kernel/locking/mutex-debug.c
    index bc8abb8549d2..7228909c3e62 100644
    --- a/kernel/locking/mutex-debug.c
    +++ b/kernel/locking/mutex-debug.c
    @@ -52,17 +52,18 @@ void debug_mutex_add_waiter(struct mutex *lock, struct mutex_waiter *waiter,
    {
    lockdep_assert_held(&lock->wait_lock);

    - /* Mark the current thread as blocked on the lock: */
    - task->blocked_on = waiter;
    + /* Current thread can't be already blocked (since it's executing!) */
    + DEBUG_LOCKS_WARN_ON(task->blocked_on);
    }

    void debug_mutex_remove_waiter(struct mutex *lock, struct mutex_waiter *waiter,
    struct task_struct *task)
    {
    + struct mutex *blocked_on = READ_ONCE(task->blocked_on);
    +
    DEBUG_LOCKS_WARN_ON(list_empty(&waiter->list));
    DEBUG_LOCKS_WARN_ON(waiter->task != task);
    - DEBUG_LOCKS_WARN_ON(task->blocked_on != waiter);
    - task->blocked_on = NULL;
    + DEBUG_LOCKS_WARN_ON(blocked_on && blocked_on != lock);

    INIT_LIST_HEAD(&waiter->list);
    waiter->task = NULL;
    diff --git a/kernel/locking/mutex.c b/kernel/locking/mutex.c
    index 1582756914df..f05cd2d216c7 100644
    --- a/kernel/locking/mutex.c
    +++ b/kernel/locking/mutex.c
    @@ -645,6 +645,7 @@ __mutex_lock_common(struct mutex *lock, unsigned int state, unsigned int subclas
    goto err_early_kill;
    }

    + current->blocked_on = lock;
    set_current_state(state);
    trace_contention_begin(lock, LCB_F_MUTEX);
    for (;;) {
    @@ -682,6 +683,10 @@ __mutex_lock_common(struct mutex *lock, unsigned int state, unsigned int subclas

    first = __mutex_waiter_is_first(lock, &waiter);

    + /*
    + * Gets reset by ttwu_runnable().
    + */
    + current->blocked_on = lock;
    set_current_state(state);
    /*
    * Here we order against unlock; we must either see it change
    @@ -715,6 +720,7 @@ __mutex_lock_common(struct mutex *lock, unsigned int state, unsigned int subclas
    }

    __mutex_remove_waiter(lock, &waiter);
    + current->blocked_on = NULL;

    debug_mutex_free_waiter(&waiter);

    --
    2.38.0.rc1.362.ged0d419d3c-goog
    \
     
     \ /
      Last update: 2022-10-03 23:46    [W:2.637 / U:0.012 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site