Skip to content

Commit 259c2fb

Browse files
committed
Merge tag 'locking-urgent-2020-11-15' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull locking fixes from Thomas Gleixner: "Two fixes for the locking subsystem: - Prevent an unconditional interrupt enable in a futex helper function which can be called from contexts which expect interrupts to stay disabled across the call - Don't modify lockdep chain keys in the validation process as that causes chain inconsistency" * tag 'locking-urgent-2020-11-15' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: lockdep: Avoid to modify chain keys in validate_chain() futex: Don't enable IRQs unconditionally in put_pi_state()
2 parents a50cf15 + d61fc96 commit 259c2fb

2 files changed

Lines changed: 12 additions & 12 deletions

File tree

kernel/futex.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -788,16 +788,17 @@ static void put_pi_state(struct futex_pi_state *pi_state)
788788
*/
789789
if (pi_state->owner) {
790790
struct task_struct *owner;
791+
unsigned long flags;
791792

792-
raw_spin_lock_irq(&pi_state->pi_mutex.wait_lock);
793+
raw_spin_lock_irqsave(&pi_state->pi_mutex.wait_lock, flags);
793794
owner = pi_state->owner;
794795
if (owner) {
795796
raw_spin_lock(&owner->pi_lock);
796797
list_del_init(&pi_state->list);
797798
raw_spin_unlock(&owner->pi_lock);
798799
}
799800
rt_mutex_proxy_unlock(&pi_state->pi_mutex, owner);
800-
raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock);
801+
raw_spin_unlock_irqrestore(&pi_state->pi_mutex.wait_lock, flags);
801802
}
802803

803804
if (current->pi_state_cache) {

kernel/locking/lockdep.c

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2765,7 +2765,9 @@ print_deadlock_bug(struct task_struct *curr, struct held_lock *prev,
27652765
* (Note that this has to be done separately, because the graph cannot
27662766
* detect such classes of deadlocks.)
27672767
*
2768-
* Returns: 0 on deadlock detected, 1 on OK, 2 on recursive read
2768+
* Returns: 0 on deadlock detected, 1 on OK, 2 if another lock with the same
2769+
* lock class is held but nest_lock is also held, i.e. we rely on the
2770+
* nest_lock to avoid the deadlock.
27692771
*/
27702772
static int
27712773
check_deadlock(struct task_struct *curr, struct held_lock *next)
@@ -2788,7 +2790,7 @@ check_deadlock(struct task_struct *curr, struct held_lock *next)
27882790
* lock class (i.e. read_lock(lock)+read_lock(lock)):
27892791
*/
27902792
if ((next->read == 2) && prev->read)
2791-
return 2;
2793+
continue;
27922794

27932795
/*
27942796
* We're holding the nest_lock, which serializes this lock's
@@ -3592,16 +3594,13 @@ static int validate_chain(struct task_struct *curr,
35923594

35933595
if (!ret)
35943596
return 0;
3595-
/*
3596-
* Mark recursive read, as we jump over it when
3597-
* building dependencies (just like we jump over
3598-
* trylock entries):
3599-
*/
3600-
if (ret == 2)
3601-
hlock->read = 2;
36023597
/*
36033598
* Add dependency only if this lock is not the head
3604-
* of the chain, and if it's not a secondary read-lock:
3599+
* of the chain, and if the new lock introduces no more
3600+
* lock dependency (because we already hold a lock with the
3601+
* same lock class) nor deadlock (because the nest_lock
3602+
* serializes nesting locks), see the comments for
3603+
* check_deadlock().
36053604
*/
36063605
if (!chain_head && ret != 2) {
36073606
if (!check_prevs_add(curr, hlock))

0 commit comments

Comments
 (0)