lkml.org 
[lkml]   [2019]   [Jul]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 5.1 053/219] locking/lockdep: Fix merging of hlocks with non-zero references
    Date
    From: Imre Deak <imre.deak@intel.com>

    [ Upstream commit d9349850e188b8b59e5322fda17ff389a1c0cd7d ]

    The sequence

    static DEFINE_WW_CLASS(test_ww_class);

    struct ww_acquire_ctx ww_ctx;
    struct ww_mutex ww_lock_a;
    struct ww_mutex ww_lock_b;
    struct ww_mutex ww_lock_c;
    struct mutex lock_c;

    ww_acquire_init(&ww_ctx, &test_ww_class);

    ww_mutex_init(&ww_lock_a, &test_ww_class);
    ww_mutex_init(&ww_lock_b, &test_ww_class);
    ww_mutex_init(&ww_lock_c, &test_ww_class);

    mutex_init(&lock_c);

    ww_mutex_lock(&ww_lock_a, &ww_ctx);

    mutex_lock(&lock_c);

    ww_mutex_lock(&ww_lock_b, &ww_ctx);
    ww_mutex_lock(&ww_lock_c, &ww_ctx);

    mutex_unlock(&lock_c); (*)

    ww_mutex_unlock(&ww_lock_c);
    ww_mutex_unlock(&ww_lock_b);
    ww_mutex_unlock(&ww_lock_a);

    ww_acquire_fini(&ww_ctx); (**)

    will trigger the following error in __lock_release() when calling
    mutex_release() at **:

    DEBUG_LOCKS_WARN_ON(depth <= 0)

    The problem is that the hlock merging happening at * updates the
    references for test_ww_class incorrectly to 3 whereas it should've
    updated it to 4 (representing all the instances for ww_ctx and
    ww_lock_[abc]).

    Fix this by updating the references during merging correctly taking into
    account that we can have non-zero references (both for the hlock that we
    merge into another hlock or for the hlock we are merging into).

    Signed-off-by: Imre Deak <imre.deak@intel.com>
    Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
    Cc: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@linux.intel.com>
    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Cc: Will Deacon <will.deacon@arm.com>
    Link: https://lkml.kernel.org/r/20190524201509.9199-2-imre.deak@intel.com
    Signed-off-by: Ingo Molnar <mingo@kernel.org>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    kernel/locking/lockdep.c | 18 +++++++++---------
    1 file changed, 9 insertions(+), 9 deletions(-)

    diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
    index 2ecc12cd11d0..89b3f38a57f3 100644
    --- a/kernel/locking/lockdep.c
    +++ b/kernel/locking/lockdep.c
    @@ -3611,17 +3611,17 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass,
    if (depth) {
    hlock = curr->held_locks + depth - 1;
    if (hlock->class_idx == class_idx && nest_lock) {
    - if (hlock->references) {
    - /*
    - * Check: unsigned int references:12, overflow.
    - */
    - if (DEBUG_LOCKS_WARN_ON(hlock->references == (1 << 12)-1))
    - return 0;
    + if (!references)
    + references++;

    + if (!hlock->references)
    hlock->references++;
    - } else {
    - hlock->references = 2;
    - }
    +
    + hlock->references += references;
    +
    + /* Overflow */
    + if (DEBUG_LOCKS_WARN_ON(hlock->references < references))
    + return 0;

    return 2;
    }
    --
    2.20.1
    \
     
     \ /
      Last update: 2019-07-15 17:15    [W:3.255 / U:0.896 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site