xref: /linux/Documentation/dev-tools/context-analysis.rst (revision 37a93dd5c49b5fda807fd204edf2547c3493319c)
1.. SPDX-License-Identifier: GPL-2.0
2.. Copyright (C) 2025, Google LLC.
3
4.. _context-analysis:
5
6Compiler-Based Context Analysis
7===============================
8
9Context Analysis is a language extension, which enables statically checking
10that required contexts are active (or inactive) by acquiring and releasing
11user-definable "context locks". An obvious application is lock-safety checking
12for the kernel's various synchronization primitives (each of which represents a
13"context lock"), and checking that locking rules are not violated.
14
15The Clang compiler currently supports the full set of context analysis
16features. To enable for Clang, configure the kernel with::
17
18    CONFIG_WARN_CONTEXT_ANALYSIS=y
19
20The feature requires Clang 22 or later.
21
22The analysis is *opt-in by default*, and requires declaring which modules and
23subsystems should be analyzed in the respective `Makefile`::
24
25    CONTEXT_ANALYSIS_mymodule.o := y
26
27Or for all translation units in the directory::
28
29    CONTEXT_ANALYSIS := y
30
31It is possible to enable the analysis tree-wide, however, which will result in
32numerous false positive warnings currently and is *not* generally recommended::
33
34    CONFIG_WARN_CONTEXT_ANALYSIS_ALL=y
35
36Programming Model
37-----------------
38
39The below describes the programming model around using context lock types.
40
41.. note::
42   Enabling context analysis can be seen as enabling a dialect of Linux C with
43   a Context System. Some valid patterns involving complex control-flow are
44   constrained (such as conditional acquisition and later conditional release
45   in the same function).
46
47Context analysis is a way to specify permissibility of operations to depend on
48context locks being held (or not held). Typically we are interested in
49protecting data and code in a critical section by requiring a specific context
50to be active, for example by holding a specific lock. The analysis ensures that
51callers cannot perform an operation without the required context being active.
52
53Context locks are associated with named structs, along with functions that
54operate on struct instances to acquire and release the associated context lock.
55
56Context locks can be held either exclusively or shared. This mechanism allows
57assigning more precise privileges when a context is active, typically to
58distinguish where a thread may only read (shared) or also write (exclusive) to
59data guarded within a context.
60
61The set of contexts that are actually active in a given thread at a given point
62in program execution is a run-time concept. The static analysis works by
63calculating an approximation of that set, called the context environment. The
64context environment is calculated for every program point, and describes the
65set of contexts that are statically known to be active, or inactive, at that
66particular point. This environment is a conservative approximation of the full
67set of contexts that will actually be active in a thread at run-time.
68
69More details are also documented `here
70<https://clang.llvm.org/docs/ThreadSafetyAnalysis.html>`_.
71
72.. note::
73   Clang's analysis explicitly does not infer context locks acquired or
74   released by inline functions. It requires explicit annotations to (a) assert
75   that it's not a bug if a context lock is released or acquired, and (b) to
76   retain consistency between inline and non-inline function declarations.
77
78Supported Kernel Primitives
79~~~~~~~~~~~~~~~~~~~~~~~~~~~
80
81Currently the following synchronization primitives are supported:
82`raw_spinlock_t`, `spinlock_t`, `rwlock_t`, `mutex`, `seqlock_t`,
83`bit_spinlock`, RCU, SRCU (`srcu_struct`), `rw_semaphore`, `local_lock_t`,
84`ww_mutex`.
85
86To initialize variables guarded by a context lock with an initialization
87function (``type_init(&lock)``), prefer using ``guard(type_init)(&lock)`` or
88``scoped_guard(type_init, &lock) { ... }`` to initialize such guarded members
89or globals in the enclosing scope. This initializes the context lock and treats
90the context as active within the initialization scope (initialization implies
91exclusive access to the underlying object).
92
93For example::
94
95    struct my_data {
96            spinlock_t lock;
97            int counter __guarded_by(&lock);
98    };
99
100    void init_my_data(struct my_data *d)
101    {
102            ...
103            guard(spinlock_init)(&d->lock);
104            d->counter = 0;
105            ...
106    }
107
108Alternatively, initializing guarded variables can be done with context analysis
109disabled, preferably in the smallest possible scope (due to lack of any other
110checking): either with a ``context_unsafe(var = init)`` expression, or by
111marking small initialization functions with the ``__context_unsafe(init)``
112attribute.
113
114Lockdep assertions, such as `lockdep_assert_held()`, inform the compiler's
115context analysis that the associated synchronization primitive is held after
116the assertion. This avoids false positives in complex control-flow scenarios
117and encourages the use of Lockdep where static analysis is limited. For
118example, this is useful when a function doesn't *always* require a lock, making
119`__must_hold()` inappropriate.
120
121Keywords
122~~~~~~~~
123
124.. kernel-doc:: include/linux/compiler-context-analysis.h
125   :identifiers: context_lock_struct
126                 token_context_lock token_context_lock_instance
127                 __guarded_by __pt_guarded_by
128                 __must_hold
129                 __must_not_hold
130                 __acquires
131                 __cond_acquires
132                 __releases
133                 __must_hold_shared
134                 __acquires_shared
135                 __cond_acquires_shared
136                 __releases_shared
137                 __acquire
138                 __release
139                 __acquire_shared
140                 __release_shared
141                 __acquire_ret
142                 __acquire_shared_ret
143                 context_unsafe
144                 __context_unsafe
145                 disable_context_analysis enable_context_analysis
146
147.. note::
148   The function attribute `__no_context_analysis` is reserved for internal
149   implementation of context lock types, and should be avoided in normal code.
150
151Background
152----------
153
154Clang originally called the feature `Thread Safety Analysis
155<https://clang.llvm.org/docs/ThreadSafetyAnalysis.html>`_, with some keywords
156and documentation still using the thread-safety-analysis-only terminology. This
157was later changed and the feature became more flexible, gaining the ability to
158define custom "capabilities". Its foundations can be found in `Capability
159Systems <https://www.cs.cornell.edu/talc/papers/capabilities.pdf>`_, used to
160specify the permissibility of operations to depend on some "capability" being
161held (or not held).
162
163Because the feature is not just able to express capabilities related to
164synchronization primitives, and "capability" is already overloaded in the
165kernel, the naming chosen for the kernel departs from Clang's initial "Thread
166Safety" and "capability" nomenclature; we refer to the feature as "Context
167Analysis" to avoid confusion. The internal implementation still makes
168references to Clang's terminology in a few places, such as `-Wthread-safety`
169being the warning option that also still appears in diagnostic messages.
170