Re: [PATCH] lockdep: Speed up lockdep_unregister_key() with expedited RCU synchronization
From: Waiman Long <hidden>
Date: 2025-03-25 14:57:20
Also in:
lkml
On 3/25/25 10:52 AM, Waiman Long wrote:
I agree that the commit that I mentioned is not relevant to the
current case. You are right that is_dynamic_key() is the only function
that is problematic, the other two are protected by the lockdep_lock.
So they are safe. Anyway, I believe that the actual race happens in
the iteration of the hashed list in is_dynamic_key(). The key that you
save in the lockdep_key_hazptr in your proposed patch should never be
the key (dead_key) that is passed to lockdep_unregister_key(). In
is_dynamic_key():
hlist_for_each_entry_rcu(k, hash_head, hash_entry) {
if (k == key) {
found = true;
break;
}
}
key != k (dead_key), but before accessing its content to get to
hash_entry, an interrupt/NMI can happen. In the mean time, the
structure holding the key is freed and its content can be overwritten
with some garbage. When interrupt/NMI returns, hash_entry can point to
anything leading to crash or an infinite loop. Perhaps we can use
some kind of synchronization mechanism between is_dynamic_key() and
lockdep_unregister_key() to prevent this kind of racing. For example,
we can have an atomic counter associated with each head of the hashed
table. is_dynamic_key() can increment the counter if it is not zero to
proceed and lockdep_unregister_key() have to make sure it can safely
decrement the counter to 0 before going ahead. Just a thought!Well, that is essentially an arch_rwlock_t for each list head. Cheers, Longman