162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * kernel/lockdep_internals.h
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Runtime locking correctness validator
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci * lockdep subsystem internal functions and variables.
862306a36Sopenharmony_ci */
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci/*
1162306a36Sopenharmony_ci * Lock-class usage-state bits:
1262306a36Sopenharmony_ci */
1362306a36Sopenharmony_cienum lock_usage_bit {
1462306a36Sopenharmony_ci#define LOCKDEP_STATE(__STATE)		\
1562306a36Sopenharmony_ci	LOCK_USED_IN_##__STATE,		\
1662306a36Sopenharmony_ci	LOCK_USED_IN_##__STATE##_READ,	\
1762306a36Sopenharmony_ci	LOCK_ENABLED_##__STATE,		\
1862306a36Sopenharmony_ci	LOCK_ENABLED_##__STATE##_READ,
1962306a36Sopenharmony_ci#include "lockdep_states.h"
2062306a36Sopenharmony_ci#undef LOCKDEP_STATE
2162306a36Sopenharmony_ci	LOCK_USED,
2262306a36Sopenharmony_ci	LOCK_USED_READ,
2362306a36Sopenharmony_ci	LOCK_USAGE_STATES,
2462306a36Sopenharmony_ci};
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci/* states after LOCK_USED_READ are not traced and printed */
2762306a36Sopenharmony_cistatic_assert(LOCK_TRACE_STATES == LOCK_USAGE_STATES);
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci#define LOCK_USAGE_READ_MASK 1
3062306a36Sopenharmony_ci#define LOCK_USAGE_DIR_MASK  2
3162306a36Sopenharmony_ci#define LOCK_USAGE_STATE_MASK (~(LOCK_USAGE_READ_MASK | LOCK_USAGE_DIR_MASK))
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci/*
3462306a36Sopenharmony_ci * Usage-state bitmasks:
3562306a36Sopenharmony_ci */
3662306a36Sopenharmony_ci#define __LOCKF(__STATE)	LOCKF_##__STATE = (1 << LOCK_##__STATE),
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_cienum {
3962306a36Sopenharmony_ci#define LOCKDEP_STATE(__STATE)						\
4062306a36Sopenharmony_ci	__LOCKF(USED_IN_##__STATE)					\
4162306a36Sopenharmony_ci	__LOCKF(USED_IN_##__STATE##_READ)				\
4262306a36Sopenharmony_ci	__LOCKF(ENABLED_##__STATE)					\
4362306a36Sopenharmony_ci	__LOCKF(ENABLED_##__STATE##_READ)
4462306a36Sopenharmony_ci#include "lockdep_states.h"
4562306a36Sopenharmony_ci#undef LOCKDEP_STATE
4662306a36Sopenharmony_ci	__LOCKF(USED)
4762306a36Sopenharmony_ci	__LOCKF(USED_READ)
4862306a36Sopenharmony_ci};
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci#define LOCKDEP_STATE(__STATE)	LOCKF_ENABLED_##__STATE |
5162306a36Sopenharmony_cistatic const unsigned long LOCKF_ENABLED_IRQ =
5262306a36Sopenharmony_ci#include "lockdep_states.h"
5362306a36Sopenharmony_ci	0;
5462306a36Sopenharmony_ci#undef LOCKDEP_STATE
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci#define LOCKDEP_STATE(__STATE)	LOCKF_USED_IN_##__STATE |
5762306a36Sopenharmony_cistatic const unsigned long LOCKF_USED_IN_IRQ =
5862306a36Sopenharmony_ci#include "lockdep_states.h"
5962306a36Sopenharmony_ci	0;
6062306a36Sopenharmony_ci#undef LOCKDEP_STATE
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci#define LOCKDEP_STATE(__STATE)	LOCKF_ENABLED_##__STATE##_READ |
6362306a36Sopenharmony_cistatic const unsigned long LOCKF_ENABLED_IRQ_READ =
6462306a36Sopenharmony_ci#include "lockdep_states.h"
6562306a36Sopenharmony_ci	0;
6662306a36Sopenharmony_ci#undef LOCKDEP_STATE
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci#define LOCKDEP_STATE(__STATE)	LOCKF_USED_IN_##__STATE##_READ |
6962306a36Sopenharmony_cistatic const unsigned long LOCKF_USED_IN_IRQ_READ =
7062306a36Sopenharmony_ci#include "lockdep_states.h"
7162306a36Sopenharmony_ci	0;
7262306a36Sopenharmony_ci#undef LOCKDEP_STATE
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci#define LOCKF_ENABLED_IRQ_ALL (LOCKF_ENABLED_IRQ | LOCKF_ENABLED_IRQ_READ)
7562306a36Sopenharmony_ci#define LOCKF_USED_IN_IRQ_ALL (LOCKF_USED_IN_IRQ | LOCKF_USED_IN_IRQ_READ)
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_ci#define LOCKF_IRQ (LOCKF_ENABLED_IRQ | LOCKF_USED_IN_IRQ)
7862306a36Sopenharmony_ci#define LOCKF_IRQ_READ (LOCKF_ENABLED_IRQ_READ | LOCKF_USED_IN_IRQ_READ)
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ci/*
8162306a36Sopenharmony_ci * CONFIG_LOCKDEP_SMALL is defined for sparc. Sparc requires .text,
8262306a36Sopenharmony_ci * .data and .bss to fit in required 32MB limit for the kernel. With
8362306a36Sopenharmony_ci * CONFIG_LOCKDEP we could go over this limit and cause system boot-up problems.
8462306a36Sopenharmony_ci * So, reduce the static allocations for lockdeps related structures so that
8562306a36Sopenharmony_ci * everything fits in current required size limit.
8662306a36Sopenharmony_ci */
8762306a36Sopenharmony_ci#ifdef CONFIG_LOCKDEP_SMALL
8862306a36Sopenharmony_ci/*
8962306a36Sopenharmony_ci * MAX_LOCKDEP_ENTRIES is the maximum number of lock dependencies
9062306a36Sopenharmony_ci * we track.
9162306a36Sopenharmony_ci *
9262306a36Sopenharmony_ci * We use the per-lock dependency maps in two ways: we grow it by adding
9362306a36Sopenharmony_ci * every to-be-taken lock to all currently held lock's own dependency
9462306a36Sopenharmony_ci * table (if it's not there yet), and we check it for lock order
9562306a36Sopenharmony_ci * conflicts and deadlocks.
9662306a36Sopenharmony_ci */
9762306a36Sopenharmony_ci#define MAX_LOCKDEP_ENTRIES	16384UL
9862306a36Sopenharmony_ci#define MAX_LOCKDEP_CHAINS_BITS	15
9962306a36Sopenharmony_ci#define MAX_STACK_TRACE_ENTRIES	262144UL
10062306a36Sopenharmony_ci#define STACK_TRACE_HASH_SIZE	8192
10162306a36Sopenharmony_ci#else
10262306a36Sopenharmony_ci#define MAX_LOCKDEP_ENTRIES	(1UL << CONFIG_LOCKDEP_BITS)
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci#define MAX_LOCKDEP_CHAINS_BITS	CONFIG_LOCKDEP_CHAINS_BITS
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_ci/*
10762306a36Sopenharmony_ci * Stack-trace: tightly packed array of stack backtrace
10862306a36Sopenharmony_ci * addresses. Protected by the hash_lock.
10962306a36Sopenharmony_ci */
11062306a36Sopenharmony_ci#define MAX_STACK_TRACE_ENTRIES	(1UL << CONFIG_LOCKDEP_STACK_TRACE_BITS)
11162306a36Sopenharmony_ci#define STACK_TRACE_HASH_SIZE	(1 << CONFIG_LOCKDEP_STACK_TRACE_HASH_BITS)
11262306a36Sopenharmony_ci#endif
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_ci/*
11562306a36Sopenharmony_ci * Bit definitions for lock_chain.irq_context
11662306a36Sopenharmony_ci */
11762306a36Sopenharmony_ci#define LOCK_CHAIN_SOFTIRQ_CONTEXT	(1 << 0)
11862306a36Sopenharmony_ci#define LOCK_CHAIN_HARDIRQ_CONTEXT	(1 << 1)
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_ci#define MAX_LOCKDEP_CHAINS	(1UL << MAX_LOCKDEP_CHAINS_BITS)
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ci#define MAX_LOCKDEP_CHAIN_HLOCKS (MAX_LOCKDEP_CHAINS*5)
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_ciextern struct lock_chain lock_chains[];
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_ci#define LOCK_USAGE_CHARS (2*XXX_LOCK_USAGE_STATES + 1)
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_ciextern void get_usage_chars(struct lock_class *class,
12962306a36Sopenharmony_ci			    char usage[LOCK_USAGE_CHARS]);
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_ciextern const char *__get_key_name(const struct lockdep_subclass_key *key,
13262306a36Sopenharmony_ci				  char *str);
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_cistruct lock_class *lock_chain_get_class(struct lock_chain *chain, int i);
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_ciextern unsigned long nr_lock_classes;
13762306a36Sopenharmony_ciextern unsigned long nr_zapped_classes;
13862306a36Sopenharmony_ciextern unsigned long nr_zapped_lock_chains;
13962306a36Sopenharmony_ciextern unsigned long nr_list_entries;
14062306a36Sopenharmony_cilong lockdep_next_lockchain(long i);
14162306a36Sopenharmony_ciunsigned long lock_chain_count(void);
14262306a36Sopenharmony_ciextern unsigned long nr_stack_trace_entries;
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ciextern unsigned int nr_hardirq_chains;
14562306a36Sopenharmony_ciextern unsigned int nr_softirq_chains;
14662306a36Sopenharmony_ciextern unsigned int nr_process_chains;
14762306a36Sopenharmony_ciextern unsigned int nr_free_chain_hlocks;
14862306a36Sopenharmony_ciextern unsigned int nr_lost_chain_hlocks;
14962306a36Sopenharmony_ciextern unsigned int nr_large_chain_blocks;
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_ciextern unsigned int max_lockdep_depth;
15262306a36Sopenharmony_ciextern unsigned int max_bfs_queue_depth;
15362306a36Sopenharmony_ciextern unsigned long max_lock_class_idx;
15462306a36Sopenharmony_ci
15562306a36Sopenharmony_ciextern struct lock_class lock_classes[MAX_LOCKDEP_KEYS];
15662306a36Sopenharmony_ciextern unsigned long lock_classes_in_use[];
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_ci#ifdef CONFIG_PROVE_LOCKING
15962306a36Sopenharmony_ciextern unsigned long lockdep_count_forward_deps(struct lock_class *);
16062306a36Sopenharmony_ciextern unsigned long lockdep_count_backward_deps(struct lock_class *);
16162306a36Sopenharmony_ci#ifdef CONFIG_TRACE_IRQFLAGS
16262306a36Sopenharmony_ciu64 lockdep_stack_trace_count(void);
16362306a36Sopenharmony_ciu64 lockdep_stack_hash_count(void);
16462306a36Sopenharmony_ci#endif
16562306a36Sopenharmony_ci#else
16662306a36Sopenharmony_cistatic inline unsigned long
16762306a36Sopenharmony_cilockdep_count_forward_deps(struct lock_class *class)
16862306a36Sopenharmony_ci{
16962306a36Sopenharmony_ci	return 0;
17062306a36Sopenharmony_ci}
17162306a36Sopenharmony_cistatic inline unsigned long
17262306a36Sopenharmony_cilockdep_count_backward_deps(struct lock_class *class)
17362306a36Sopenharmony_ci{
17462306a36Sopenharmony_ci	return 0;
17562306a36Sopenharmony_ci}
17662306a36Sopenharmony_ci#endif
17762306a36Sopenharmony_ci
17862306a36Sopenharmony_ci#ifdef CONFIG_DEBUG_LOCKDEP
17962306a36Sopenharmony_ci
18062306a36Sopenharmony_ci#include <asm/local.h>
18162306a36Sopenharmony_ci/*
18262306a36Sopenharmony_ci * Various lockdep statistics.
18362306a36Sopenharmony_ci * We want them per cpu as they are often accessed in fast path
18462306a36Sopenharmony_ci * and we want to avoid too much cache bouncing.
18562306a36Sopenharmony_ci */
18662306a36Sopenharmony_cistruct lockdep_stats {
18762306a36Sopenharmony_ci	unsigned long  chain_lookup_hits;
18862306a36Sopenharmony_ci	unsigned int   chain_lookup_misses;
18962306a36Sopenharmony_ci	unsigned long  hardirqs_on_events;
19062306a36Sopenharmony_ci	unsigned long  hardirqs_off_events;
19162306a36Sopenharmony_ci	unsigned long  redundant_hardirqs_on;
19262306a36Sopenharmony_ci	unsigned long  redundant_hardirqs_off;
19362306a36Sopenharmony_ci	unsigned long  softirqs_on_events;
19462306a36Sopenharmony_ci	unsigned long  softirqs_off_events;
19562306a36Sopenharmony_ci	unsigned long  redundant_softirqs_on;
19662306a36Sopenharmony_ci	unsigned long  redundant_softirqs_off;
19762306a36Sopenharmony_ci	int            nr_unused_locks;
19862306a36Sopenharmony_ci	unsigned int   nr_redundant_checks;
19962306a36Sopenharmony_ci	unsigned int   nr_redundant;
20062306a36Sopenharmony_ci	unsigned int   nr_cyclic_checks;
20162306a36Sopenharmony_ci	unsigned int   nr_find_usage_forwards_checks;
20262306a36Sopenharmony_ci	unsigned int   nr_find_usage_backwards_checks;
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_ci	/*
20562306a36Sopenharmony_ci	 * Per lock class locking operation stat counts
20662306a36Sopenharmony_ci	 */
20762306a36Sopenharmony_ci	unsigned long lock_class_ops[MAX_LOCKDEP_KEYS];
20862306a36Sopenharmony_ci};
20962306a36Sopenharmony_ci
21062306a36Sopenharmony_ciDECLARE_PER_CPU(struct lockdep_stats, lockdep_stats);
21162306a36Sopenharmony_ci
21262306a36Sopenharmony_ci#define __debug_atomic_inc(ptr)					\
21362306a36Sopenharmony_ci	this_cpu_inc(lockdep_stats.ptr);
21462306a36Sopenharmony_ci
21562306a36Sopenharmony_ci#define debug_atomic_inc(ptr)			{		\
21662306a36Sopenharmony_ci	WARN_ON_ONCE(!irqs_disabled());				\
21762306a36Sopenharmony_ci	__this_cpu_inc(lockdep_stats.ptr);			\
21862306a36Sopenharmony_ci}
21962306a36Sopenharmony_ci
22062306a36Sopenharmony_ci#define debug_atomic_dec(ptr)			{		\
22162306a36Sopenharmony_ci	WARN_ON_ONCE(!irqs_disabled());				\
22262306a36Sopenharmony_ci	__this_cpu_dec(lockdep_stats.ptr);			\
22362306a36Sopenharmony_ci}
22462306a36Sopenharmony_ci
22562306a36Sopenharmony_ci#define debug_atomic_read(ptr)		({				\
22662306a36Sopenharmony_ci	struct lockdep_stats *__cpu_lockdep_stats;			\
22762306a36Sopenharmony_ci	unsigned long long __total = 0;					\
22862306a36Sopenharmony_ci	int __cpu;							\
22962306a36Sopenharmony_ci	for_each_possible_cpu(__cpu) {					\
23062306a36Sopenharmony_ci		__cpu_lockdep_stats = &per_cpu(lockdep_stats, __cpu);	\
23162306a36Sopenharmony_ci		__total += __cpu_lockdep_stats->ptr;			\
23262306a36Sopenharmony_ci	}								\
23362306a36Sopenharmony_ci	__total;							\
23462306a36Sopenharmony_ci})
23562306a36Sopenharmony_ci
23662306a36Sopenharmony_cistatic inline void debug_class_ops_inc(struct lock_class *class)
23762306a36Sopenharmony_ci{
23862306a36Sopenharmony_ci	int idx;
23962306a36Sopenharmony_ci
24062306a36Sopenharmony_ci	idx = class - lock_classes;
24162306a36Sopenharmony_ci	__debug_atomic_inc(lock_class_ops[idx]);
24262306a36Sopenharmony_ci}
24362306a36Sopenharmony_ci
24462306a36Sopenharmony_cistatic inline unsigned long debug_class_ops_read(struct lock_class *class)
24562306a36Sopenharmony_ci{
24662306a36Sopenharmony_ci	int idx, cpu;
24762306a36Sopenharmony_ci	unsigned long ops = 0;
24862306a36Sopenharmony_ci
24962306a36Sopenharmony_ci	idx = class - lock_classes;
25062306a36Sopenharmony_ci	for_each_possible_cpu(cpu)
25162306a36Sopenharmony_ci		ops += per_cpu(lockdep_stats.lock_class_ops[idx], cpu);
25262306a36Sopenharmony_ci	return ops;
25362306a36Sopenharmony_ci}
25462306a36Sopenharmony_ci
25562306a36Sopenharmony_ci#else
25662306a36Sopenharmony_ci# define __debug_atomic_inc(ptr)	do { } while (0)
25762306a36Sopenharmony_ci# define debug_atomic_inc(ptr)		do { } while (0)
25862306a36Sopenharmony_ci# define debug_atomic_dec(ptr)		do { } while (0)
25962306a36Sopenharmony_ci# define debug_atomic_read(ptr)		0
26062306a36Sopenharmony_ci# define debug_class_ops_inc(ptr)	do { } while (0)
26162306a36Sopenharmony_ci#endif
262