mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2026-05-05 09:57:21 +02:00
Documentation: Add documentation for Compiler-Based Context Analysis
Adds documentation in Documentation/dev-tools/context-analysis.rst, and adds it to the index. Signed-off-by: Marco Elver <elver@google.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://patch.msgid.link/20251219154418.3592607-5-elver@google.com
This commit is contained in:
committed by
Peter Zijlstra
parent
9b00c1609d
commit
8f32441d7a
@@ -0,0 +1,144 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
.. Copyright (C) 2025, Google LLC.
|
||||
|
||||
.. _context-analysis:
|
||||
|
||||
Compiler-Based Context Analysis
|
||||
===============================
|
||||
|
||||
Context Analysis is a language extension, which enables statically checking
|
||||
that required contexts are active (or inactive) by acquiring and releasing
|
||||
user-definable "context locks". An obvious application is lock-safety checking
|
||||
for the kernel's various synchronization primitives (each of which represents a
|
||||
"context lock"), and checking that locking rules are not violated.
|
||||
|
||||
The Clang compiler currently supports the full set of context analysis
|
||||
features. To enable for Clang, configure the kernel with::
|
||||
|
||||
CONFIG_WARN_CONTEXT_ANALYSIS=y
|
||||
|
||||
The feature requires Clang 22 or later.
|
||||
|
||||
The analysis is *opt-in by default*, and requires declaring which modules and
|
||||
subsystems should be analyzed in the respective `Makefile`::
|
||||
|
||||
CONTEXT_ANALYSIS_mymodule.o := y
|
||||
|
||||
Or for all translation units in the directory::
|
||||
|
||||
CONTEXT_ANALYSIS := y
|
||||
|
||||
It is possible to enable the analysis tree-wide, however, which will result in
|
||||
numerous false positive warnings currently and is *not* generally recommended::
|
||||
|
||||
CONFIG_WARN_CONTEXT_ANALYSIS_ALL=y
|
||||
|
||||
Programming Model
|
||||
-----------------
|
||||
|
||||
The below describes the programming model around using context lock types.
|
||||
|
||||
.. note::
|
||||
Enabling context analysis can be seen as enabling a dialect of Linux C with
|
||||
a Context System. Some valid patterns involving complex control-flow are
|
||||
constrained (such as conditional acquisition and later conditional release
|
||||
in the same function).
|
||||
|
||||
Context analysis is a way to specify permissibility of operations to depend on
|
||||
context locks being held (or not held). Typically we are interested in
|
||||
protecting data and code in a critical section by requiring a specific context
|
||||
to be active, for example by holding a specific lock. The analysis ensures that
|
||||
callers cannot perform an operation without the required context being active.
|
||||
|
||||
Context locks are associated with named structs, along with functions that
|
||||
operate on struct instances to acquire and release the associated context lock.
|
||||
|
||||
Context locks can be held either exclusively or shared. This mechanism allows
|
||||
assigning more precise privileges when a context is active, typically to
|
||||
distinguish where a thread may only read (shared) or also write (exclusive) to
|
||||
data guarded within a context.
|
||||
|
||||
The set of contexts that are actually active in a given thread at a given point
|
||||
in program execution is a run-time concept. The static analysis works by
|
||||
calculating an approximation of that set, called the context environment. The
|
||||
context environment is calculated for every program point, and describes the
|
||||
set of contexts that are statically known to be active, or inactive, at that
|
||||
particular point. This environment is a conservative approximation of the full
|
||||
set of contexts that will actually be active in a thread at run-time.
|
||||
|
||||
More details are also documented `here
|
||||
<https://clang.llvm.org/docs/ThreadSafetyAnalysis.html>`_.
|
||||
|
||||
.. note::
|
||||
Clang's analysis explicitly does not infer context locks acquired or
|
||||
released by inline functions. It requires explicit annotations to (a) assert
|
||||
that it's not a bug if a context lock is released or acquired, and (b) to
|
||||
retain consistency between inline and non-inline function declarations.
|
||||
|
||||
Supported Kernel Primitives
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. Currently the following synchronization primitives are supported:
|
||||
|
||||
For context locks with an initialization function (e.g., `spin_lock_init()`),
|
||||
calling this function before initializing any guarded members or globals
|
||||
prevents the compiler from issuing warnings about unguarded initialization.
|
||||
|
||||
Lockdep assertions, such as `lockdep_assert_held()`, inform the compiler's
|
||||
context analysis that the associated synchronization primitive is held after
|
||||
the assertion. This avoids false positives in complex control-flow scenarios
|
||||
and encourages the use of Lockdep where static analysis is limited. For
|
||||
example, this is useful when a function doesn't *always* require a lock, making
|
||||
`__must_hold()` inappropriate.
|
||||
|
||||
Keywords
|
||||
~~~~~~~~
|
||||
|
||||
.. kernel-doc:: include/linux/compiler-context-analysis.h
|
||||
:identifiers: context_lock_struct
|
||||
token_context_lock token_context_lock_instance
|
||||
__guarded_by __pt_guarded_by
|
||||
__must_hold
|
||||
__must_not_hold
|
||||
__acquires
|
||||
__cond_acquires
|
||||
__releases
|
||||
__must_hold_shared
|
||||
__acquires_shared
|
||||
__cond_acquires_shared
|
||||
__releases_shared
|
||||
__acquire
|
||||
__release
|
||||
__cond_lock
|
||||
__acquire_shared
|
||||
__release_shared
|
||||
__cond_lock_shared
|
||||
__acquire_ret
|
||||
__acquire_shared_ret
|
||||
context_unsafe
|
||||
__context_unsafe
|
||||
disable_context_analysis enable_context_analysis
|
||||
|
||||
.. note::
|
||||
The function attribute `__no_context_analysis` is reserved for internal
|
||||
implementation of context lock types, and should be avoided in normal code.
|
||||
|
||||
Background
|
||||
----------
|
||||
|
||||
Clang originally called the feature `Thread Safety Analysis
|
||||
<https://clang.llvm.org/docs/ThreadSafetyAnalysis.html>`_, with some keywords
|
||||
and documentation still using the thread-safety-analysis-only terminology. This
|
||||
was later changed and the feature became more flexible, gaining the ability to
|
||||
define custom "capabilities". Its foundations can be found in `Capability
|
||||
Systems <https://www.cs.cornell.edu/talc/papers/capabilities.pdf>`_, used to
|
||||
specify the permissibility of operations to depend on some "capability" being
|
||||
held (or not held).
|
||||
|
||||
Because the feature is not just able to express capabilities related to
|
||||
synchronization primitives, and "capability" is already overloaded in the
|
||||
kernel, the naming chosen for the kernel departs from Clang's initial "Thread
|
||||
Safety" and "capability" nomenclature; we refer to the feature as "Context
|
||||
Analysis" to avoid confusion. The internal implementation still makes
|
||||
references to Clang's terminology in a few places, such as `-Wthread-safety`
|
||||
being the warning option that also still appears in diagnostic messages.
|
||||
@@ -21,6 +21,7 @@ Documentation/process/debugging/index.rst
|
||||
checkpatch
|
||||
clang-format
|
||||
coccinelle
|
||||
context-analysis
|
||||
sparse
|
||||
kcov
|
||||
gcov
|
||||
|
||||
Reference in New Issue
Block a user