Re: [PATCH] lockdep: Speed up lockdep_unregister_key() with expedited RCU synchronization

Waiman Long
2025-03-25T14:57:20Z

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