On Wed, Nov 28, 2018 at 03:43:18PM -0800, Bart Van Assche wrote: > +/* Must be called with the graph lock held. */ > +static void remove_class_from_lock_chain(struct lock_chain *chain, > + struct lock_class *class) > +{ > + u64 chain_key; > + int i; > + > + for (i = chain->base; i < chain->base + chain->depth; i++) { > + if (chain_hlocks[i] != class - lock_classes) > + continue; > + if (--chain->depth == 0) > + break; > + memmove(&chain_hlocks[i], &chain_hlocks[i + 1], > + (chain->base + chain->depth - i) * > + sizeof(chain_hlocks[0])); > + /* > + * Each lock class occurs at most once in a > + * lock chain so once we found a match we can > + * break out of this loop. > + */ > + break; > + } > + /* > + * Note: calling hlist_del_rcu() from inside a > + * hlist_for_each_entry_rcu() loop is safe. > + */ > + if (chain->depth == 0) { > + /* To do: decrease chain count. See also inc_chains(). */ > + hlist_del_rcu(&chain->entry); > + return; > + } > + chain_key = 0; > + for (i = chain->base; i < chain->base + chain->depth; i++) > + chain_key = iterate_chain_key(chain_key, chain_hlocks[i] + 1); > + if (chain->chain_key == chain_key) > + return; > + hlist_del_rcu(&chain->entry); > + chain->chain_key = chain_key; > + hlist_add_head_rcu(&chain->entry, chainhashentry(chain_key)); > +} > + > +/* Must be called with the graph lock held. */ > +static void remove_class_from_lock_chains(struct lock_class *class) > +{ > + struct lock_chain *chain; > + struct hlist_head *head; > + int i; > + > + for (i = 0; i < ARRAY_SIZE(chainhash_table); i++) { > + head = chainhash_table + i; > + hlist_for_each_entry_rcu(chain, head, entry) { > + remove_class_from_lock_chain(chain, class); > + } > + } > +}
*shudder*, I suppose that is the reason I never went there. I suoppose that if you don't do this too often it doesn't matter it is horribly epxneisve.