When adding a dependency, if the dependency exists the dependency's read-write type will be "upgraded" if the new dependency has more exclusive lock types. The order toward more exclusiveness: recursive read -> read -> write.
Signed-off-by: Yuyang Du <[email protected]> --- kernel/locking/lockdep.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c index 9fa38fb..2329add 100644 --- a/kernel/locking/lockdep.c +++ b/kernel/locking/lockdep.c @@ -1516,6 +1516,21 @@ static inline int get_lock_type2(struct lock_list *lock) return lock->lock_type2; } +static inline int hlock_type(struct held_lock *hlock) +{ + return hlock->read; +} + +static inline void set_lock_type1(struct lock_list *lock, int read) +{ + lock->lock_type1 = read; +} + +static inline void set_lock_type2(struct lock_list *lock, int read) +{ + lock->lock_type2 = read; +} + /* * Forward- or backward-dependency search, used for both circular dependency * checking and hardirq-unsafe/softirq-unsafe checking. @@ -2511,6 +2526,17 @@ static inline void inc_chains(void) list_add_tail_rcu(&chain->chain_entry, &entry->chains); __set_bit(chain - lock_chains, lock_chains_in_dep); + /* + * For a direct dependency, smaller type value + * generally means more lock exlusiveness; we + * keep the more exlusive one, in other words, + * we "upgrade" the dependency if we can. + */ + if (prev->read < get_lock_type1(entry)) + set_lock_type1(entry, prev->read); + if (next->read < get_lock_type2(entry)) + set_lock_type2(entry, next->read); + if (distance == 1) entry->distance = 1; -- 1.8.3.1

