• Imre Deak's avatar
    locking/lockdep: Fix OOO unlock when hlocks need merging · 8c8889d8
    Imre Deak authored
    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 mutex lock_c;
    	struct mutex lock_d;
    
    	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);
    
    	mutex_init(&lock_c);
    
    	ww_mutex_lock(&ww_lock_a, &ww_ctx);
    
    	mutex_lock(&lock_c);
    
    	ww_mutex_lock(&ww_lock_b, &ww_ctx);
    
    	mutex_unlock(&lock_c);		(*)
    
    	ww_mutex_unlock(&ww_lock_b);
    	ww_mutex_unlock(&ww_lock_a);
    
    	ww_acquire_fini(&ww_ctx);
    
    triggers the following WARN in __lock_release() when doing the unlock at *:
    
    	DEBUG_LOCKS_WARN_ON(curr->lockdep_depth != depth - 1);
    
    The problem is that the WARN check doesn't take into account the merging
    of ww_lock_a and ww_lock_b which results in decreasing curr->lockdep_depth
    by 2 not only 1.
    
    Note that the following sequence doesn't trigger the WARN, since there
    won't be any hlock merging.
    
    	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);
    
    	mutex_init(&lock_c);
    	mutex_init(&lock_d);
    
    	ww_mutex_lock(&ww_lock_a, &ww_ctx);
    
    	mutex_lock(&lock_c);
    	mutex_lock(&lock_d);
    
    	ww_mutex_lock(&ww_lock_b, &ww_ctx);
    
    	mutex_unlock(&lock_d);
    
    	ww_mutex_unlock(&ww_lock_b);
    	ww_mutex_unlock(&ww_lock_a);
    
    	mutex_unlock(&lock_c);
    
    	ww_acquire_fini(&ww_ctx);
    
    In general both of the above two sequences are valid and shouldn't
    trigger any lockdep warning.
    
    Fix this by taking the decrement due to the hlock merging into account
    during lock release and hlock class re-setting. Merging can't happen
    during lock downgrading since there won't be a new possibility to merge
    hlocks in that case, so add a WARN if merging still happens then.
    Signed-off-by: default avatarImre Deak <imre.deak@intel.com>
    Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
    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>
    Cc: ville.syrjala@linux.intel.com
    Link: https://lkml.kernel.org/r/20190524201509.9199-1-imre.deak@intel.comSigned-off-by: default avatarIngo Molnar <mingo@kernel.org>
    8c8889d8
lockdep.c 132 KB