Re: [PATCH v2 1/6] locking/lockdep: Track number of zapped classes

From: Bart Van Assche
Date: Mon Jan 13 2020 - 11:02:17 EST


On 1/13/20 6:58 AM, Waiman Long wrote:
On 1/13/20 9:55 AM, Peter Zijlstra wrote:
On Mon, Dec 16, 2019 at 10:15:12AM -0500, Waiman Long wrote:
The whole point of the lockdep dynamic key patch is to allow unused
locks to be removed from the lockdep data buffers so that existing
buffer space can be reused. However, there is no way to find out how
many unused locks are zapped and so we don't know if the zapping process
is working properly.

Add a new nr_zapped_classes variable to track that and show it in
/proc/lockdep_stats if it is non-zero.

diff --git a/kernel/locking/lockdep_proc.c b/kernel/locking/lockdep_proc.c
index dadb7b7fba37..d98d349bb648 100644
--- a/kernel/locking/lockdep_proc.c
+++ b/kernel/locking/lockdep_proc.c
@@ -336,6 +336,15 @@ static int lockdep_stats_show(struct seq_file *m, void *v)
seq_printf(m, " debug_locks: %11u\n",
debug_locks);
+ /*
+ * Zappped classes and lockdep data buffers reuse statistics.
+ */
+ if (!nr_zapped_classes)
+ return 0;
+
+ seq_puts(m, "\n");
+ seq_printf(m, " zapped classes: %11lu\n",
+ nr_zapped_classes);
return 0;
}
Why is that conditional?

Because I thought zapping class doesn't occur that often. Apparently,
class zapping happens when the system first boots up. I guess that
conditional check isn't needed. I can remove it in the next version.

Zapping a lock class happens every time a lock key is unregistered. That can happen any time as one can see in the following grep output:

$ git grep -lw 'lockdep_unregister_key'
drivers/net/bonding/bond_main.c:4446: lockdep_unregister_key(&bond->stats_lock_key);
drivers/net/team/team.c:1676: lockdep_unregister_key(&team->team_lock_key);
drivers/net/team/team.c:1984: lockdep_unregister_key(&team->team_lock_key);
include/linux/lockdep.h:294:extern void lockdep_unregister_key(struct lock_class_key *key);
include/linux/lockdep.h:464:static inline void lockdep_unregister_key(struct lock_class_key *key)
kernel/locking/lockdep.c:5166:void lockdep_unregister_key(struct lock_class_key *key)
kernel/locking/lockdep.c:5201:EXPORT_SYMBOL_GPL(lockdep_unregister_key);
kernel/workqueue.c:3456: lockdep_unregister_key(&wq->key);
net/core/dev.c:9172: lockdep_unregister_key(&dev->qdisc_tx_busylock_key);
net/core/dev.c:9173: lockdep_unregister_key(&dev->qdisc_running_key);
net/core/dev.c:9174: lockdep_unregister_key(&dev->qdisc_xmit_lock_key);
net/core/dev.c:9175: lockdep_unregister_key(&dev->addr_list_lock_key);
net/core/dev.c:9183: lockdep_unregister_key(&dev->qdisc_xmit_lock_key);
net/core/dev.c:9184: lockdep_unregister_key(&dev->addr_list_lock_key);
tools/lib/lockdep/include/liblockdep/common.h:48:void lockdep_unregister_key(struct lock_class_key *key);
tools/lib/lockdep/include/liblockdep/mutex.h:58: lockdep_unregister_key(&lock->key);

Bart.