XenevaOS
Loading...
Searching...
No Matches
lockdep.h
Go to the documentation of this file.
1#ifndef __LINUX_LOCKDEP_H__
2#define __LINUX_LOCKDEP_H__
3
4/*
5 * DCL <linux/lockdep.h> -- the lock-dependency API, as no-ops.
6 *
7 * lockdep's whole job is to notice at *runtime* that a program acquires locks
8 * in two different orders and might therefore deadlock -- it tracks a graph of
9 * held locks while running. DCL has no lock graph, and its locks are no-ops
10 * (see <linux/spinlock.h> and <linux/mutex.h>), so there is no acquisition
11 * order to record in the first place.
12 *
13 * The reason this header exists rather than being skipped is that ported code
14 * *names* lockdep: tty_buffer.c:618 calls
15 *
16 * lockdep_set_subclass(&port->buf.lock, TTY_LOCK_SLAVE);
17 *
18 * as its final line, and 8250_port.c includes this header outright. A call
19 * with no declaration is an implicit-function-declaration error, so the call
20 * has to parse. What the call means upstream -- "this lock is being taken
21 * nested, tell lockdep it is a different instance so it does not report a
22 * recursion" -- has no referent when locks do not recurse, so the arguments
23 * are evaluated for side effects and dropped.
24 *
25 * lockdep_init_map_type() and friends take variadic arguments including
26 * format strings, hence the `...` form rather than a fixed parameter list:
27 * mainline's call sites pass different numbers of them.
28 */
29
30#include <linux/kernel.h>
31
32#define lockdep_set_class(lock, key) do { (void)(lock); (void)(key); } while (0)
33#define lockdep_set_class_and_name(lock, key, name) \
34 do { (void)(lock); (void)(key); (void)(name); } while (0)
35#define lockdep_set_subclass(lock, sub) do { (void)(lock); (void)(sub); } while (0)
36#define lockdep_set_novalidate_class(lock) do { (void)(lock); } while (0)
37
38/*
39 * The `lock` argument is dropped rather than evaluated, which is what
40 * mainline's own !CONFIG_LOCKDEP arm does (lockdep.h:349, `do { (void)(name);
41 * (void)(key); } while (0)`). The difference matters because mainline's
42 * seqlock.h is a byte-port here and its __seqcount_init() (:48) and
43 * do_write_seqcount_begin_nested() (:478) both address `&s->dep_map` -- a
44 * member seqcount_t only has when CONFIG_DEBUG_LOCK_ALLOC is on, which it is
45 * not. Evaluating the first parameter type-checked that member access and
46 * turned every dma-resv.c inclusion into "no member named 'dep_map' in
47 * 'struct seqcount'". A macro parameter that never appears in its
48 * replacement list is not expanded at all, so the expression never reaches C.
49 *
50 * mainline evaluates name and key and so does this: both are live parameters
51 * of __seqcount_init(), so the (void) casts also keep them from warning.
52 *
53 * seqcount_acquire/seqcount_release are mainline's own two-step names
54 * (lockdep.h:528/:530), spelled the same way as the rwsem quartet below for
55 * the same reason -- the lockdep_map they would take does not exist here.
56 */
57#define lockdep_init_map(lock, name, key, sub) \
58 do { (void)(name); (void)(key); } while (0)
59#define lockdep_init_map_type(lock, name, key, sub, ...) \
60 do { (void)(name); (void)(key); } while (0)
61
62#define seqcount_acquire(l, s, t, i) do {} while (0)
63#define seqcount_release(l, i) do {} while (0)
64
65#define lockdep_match_class(lock, key) (1)
66#define lockdep_match_name(lock, name) (1)
67
68#define lockdep_rcu_suspicious(file, line, s) \
69 do { (void)(file); (void)(line); (void)(s); } while (0)
70
71#define lockdep_assert_held(l) do { (void)(l); } while (0)
72#define lockdep_assert_held_write(l) do { (void)(l); } while (0)
73#define lockdep_assert_not_held(l) do { (void)(l); } while (0)
74#define lockdep_assert_irqs_disabled() do {} while (0)
75#define lockdep_assert_irqs_enabled() do {} while (0)
76#define lockdep_assert_in_rcu() do {} while (0)
77#define lockdep_assert_preemption_disabled() do {} while (0)
78
79/*
80 * The three names the drm core adds to that family. drm_auth.c:66 is the
81 * interesting one:
82 *
83 * lockdep_assert_once(lockdep_is_held(&fpriv->master_lookup_lock) ||
84 * lockdep_is_held(&dev->master_mutex));
85 *
86 * and drm_syncobj.c:385/:1020 hand lockdep_is_held() to
87 * rcu_dereference_protected()'s condition slot. mainline answers "does this
88 * task hold this lock" out of the held-lock graph it maintains while running
89 * (lockdep.h:252); DCL has no graph and its locks are no-ops, so nothing is
90 * ever held and no order can be violated -- `1` is the answer that makes
91 * every one of these assertions pass, which is what an assertion that can
92 * only fail with lockdep is supposed to do. The RCU condition is a hint
93 * DCL's rcu_dereference_protected() drops anyway (rcupdate.h).
94 *
95 * lockdep_assert_once() *does* evaluate its argument, unlike its neighbours
96 * above that take no value and unlike mainline's !CONFIG_LOCKDEP form
97 * (`do { } while (0)`, lockdep.h:390): the argument is the expression under
98 * assertion, and evaluating it is what keeps the lock it names used -- the
99 * same reason lockdep_set_subclass() above evaluates its arguments. The
100 * compiler then folds it away, since lockdep_is_held() is the constant 1.
101 * A macro rather than an extern declaration (which is what upstream's
102 * !CONFIG_LOCKDEP build uses) follows lockdep_match_class() above, and both
103 * files that reference it reach this header, so no definition is needed.
104 */
105#define lockdep_is_held(lock) (1)
106#define lockdep_assert_once(cond) do { (void)(cond); } while (0)
107#define lockdep_assert_none_held_once() do {} while (0)
108
109/*
110 * The rwsem acquire/release quartet -- tty_ldsem.c:300-310, which brackets
111 * every ldsem_up/_down with them:
112 *
113 * rwsem_acquire_read(&sem->dep_map, subclass, 0, _RET_IP_);
114 * count = atomic_long_add_return(LDSEM_READ_BIAS, &sem->count);
115 * ...
116 * rwsem_release(&sem->dep_map, _RET_IP_);
117 *
118 * mainline's versions are real when CONFIG_LOCKDEP and CONFIG_PROVE_LOCKING
119 * are on and no-ops otherwise, so this is the arm every non-debug build
120 * already takes. What is *not* borrowed is mainline's `(void)(l)` argument
121 * handling: these four take a `struct lockdep_map *` that struct ld_semaphore
122 * does not carry (tty_ldisc.h), and evaluating it would mean adding a member
123 * whose only purpose is to be addressed and forgotten. Dropping the
124 * parameter instead means the expression never reaches C at all -- a macro
125 * parameter that does not appear in the replacement list is not expanded --
126 * which also leaves _RET_IP_ (a lockdep return-address macro) as a bare
127 * identifier that never has to be defined.
128 *
129 * Argument order is mainline's: lockdep_map, subclass[, read], ip.
130 */
131#define rwsem_acquire(l, s, t, i) do {} while (0)
132#define rwsem_acquire_read(l, s, t, i) do {} while (0)
133#define rwsem_release(l, i) do {} while (0)
134#define lock_contended(l, i) do {} while (0)
135#define lock_acquired(l, i) do {} while (0)
136
137/*
138 * lock_acquire_shared_recursive() / lock_release() -- the two lockdep calls
139 * drm_connector.c makes around the connector list iterator, at :1054 and
140 * :1135. Same spelling as the five above, same argument-dropping reason, but
141 * here it is load-bearing rather than tidy.
142 *
143 * The second argument of the first call and the first of the second is
144 * `&connector_list_iter_dep_map`, and mainline only *defines* that object
145 * inside `#ifdef CONFIG_LOCKDEP` (drm_connector.c:1032-1036). The two call
146 * sites are not under that ifdef. They still compile in mainline because
147 * mainline's no-op spelling of these macros discards its arguments before
148 * they reach C, so the address of an object that was never declared is
149 * parsed and then thrown away.
150 *
151 * That is exactly what dropping the parameter does here, and it is why the
152 * macros must not be written `(void)(l)`: evaluating the argument would
153 * require a declaration, the declaration lives behind an ifdef that is off,
154 * and the only ways out would be editing the vendored .c or unguarding a
155 * lockdep object this kernel does not run.
156 */
157#define lock_acquire_shared_recursive(l, s, r, n, i) do {} while (0)
158#define lock_release(l, i) do {} while (0)
159
160struct lock_class_key { };
161struct lockdep_map { };
162
163
164/*
165 * lockdep_assert_held_once -- the one assertion the tty/serial headers use
166 * that this header did not have (8250.h:200, 8250_port.c:555, and every
167 * uart_port_lock* wrapper in serial_core.h reach for it).
168 *
169 * mainline's is a real test that fires once per site when the lock is not
170 * held; DCL runs no lockdep, so it is the same no-op as
171 * lockdep_assert_held() directly above. The distinction that survives is
172 * arity: these are macros taking an lvalue, and the `(void)(l)` evaluates the
173 * argument so `-Wunused-but-set-variable` does not fire on a lock that is
174 * only ever asserted about.
175 */
176#define lockdep_assert_held_once(l) do { (void)(l); } while (0)
177#endif /* __LINUX_LOCKDEP_H__ */
Definition lockdep.h:160
Definition lockdep.h:161