Re: [PATCH 20/27] locking/lockdep: Free lock classes that are no longer in use

From: Peter Zijlstra
Date: Thu Nov 29 2018 - 05:37:46 EST


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.