Thread (1 message) 1 message, 1 author, 2025-03-25

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
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help