18f32441dSMarco Elver.. SPDX-License-Identifier: GPL-2.0 28f32441dSMarco Elver.. Copyright (C) 2025, Google LLC. 38f32441dSMarco Elver 48f32441dSMarco Elver.. _context-analysis: 58f32441dSMarco Elver 68f32441dSMarco ElverCompiler-Based Context Analysis 78f32441dSMarco Elver=============================== 88f32441dSMarco Elver 98f32441dSMarco ElverContext Analysis is a language extension, which enables statically checking 108f32441dSMarco Elverthat required contexts are active (or inactive) by acquiring and releasing 118f32441dSMarco Elveruser-definable "context locks". An obvious application is lock-safety checking 128f32441dSMarco Elverfor the kernel's various synchronization primitives (each of which represents a 138f32441dSMarco Elver"context lock"), and checking that locking rules are not violated. 148f32441dSMarco Elver 158f32441dSMarco ElverThe Clang compiler currently supports the full set of context analysis 168f32441dSMarco Elverfeatures. To enable for Clang, configure the kernel with:: 178f32441dSMarco Elver 188f32441dSMarco Elver CONFIG_WARN_CONTEXT_ANALYSIS=y 198f32441dSMarco Elver 208f32441dSMarco ElverThe feature requires Clang 22 or later. 218f32441dSMarco Elver 228f32441dSMarco ElverThe analysis is *opt-in by default*, and requires declaring which modules and 238f32441dSMarco Elversubsystems should be analyzed in the respective `Makefile`:: 248f32441dSMarco Elver 258f32441dSMarco Elver CONTEXT_ANALYSIS_mymodule.o := y 268f32441dSMarco Elver 278f32441dSMarco ElverOr for all translation units in the directory:: 288f32441dSMarco Elver 298f32441dSMarco Elver CONTEXT_ANALYSIS := y 308f32441dSMarco Elver 318f32441dSMarco ElverIt is possible to enable the analysis tree-wide, however, which will result in 328f32441dSMarco Elvernumerous false positive warnings currently and is *not* generally recommended:: 338f32441dSMarco Elver 348f32441dSMarco Elver CONFIG_WARN_CONTEXT_ANALYSIS_ALL=y 358f32441dSMarco Elver 368f32441dSMarco ElverProgramming Model 378f32441dSMarco Elver----------------- 388f32441dSMarco Elver 398f32441dSMarco ElverThe below describes the programming model around using context lock types. 408f32441dSMarco Elver 418f32441dSMarco Elver.. note:: 428f32441dSMarco Elver Enabling context analysis can be seen as enabling a dialect of Linux C with 438f32441dSMarco Elver a Context System. Some valid patterns involving complex control-flow are 448f32441dSMarco Elver constrained (such as conditional acquisition and later conditional release 458f32441dSMarco Elver in the same function). 468f32441dSMarco Elver 478f32441dSMarco ElverContext analysis is a way to specify permissibility of operations to depend on 488f32441dSMarco Elvercontext locks being held (or not held). Typically we are interested in 498f32441dSMarco Elverprotecting data and code in a critical section by requiring a specific context 508f32441dSMarco Elverto be active, for example by holding a specific lock. The analysis ensures that 518f32441dSMarco Elvercallers cannot perform an operation without the required context being active. 528f32441dSMarco Elver 538f32441dSMarco ElverContext locks are associated with named structs, along with functions that 548f32441dSMarco Elveroperate on struct instances to acquire and release the associated context lock. 558f32441dSMarco Elver 568f32441dSMarco ElverContext locks can be held either exclusively or shared. This mechanism allows 578f32441dSMarco Elverassigning more precise privileges when a context is active, typically to 588f32441dSMarco Elverdistinguish where a thread may only read (shared) or also write (exclusive) to 598f32441dSMarco Elverdata guarded within a context. 608f32441dSMarco Elver 618f32441dSMarco ElverThe set of contexts that are actually active in a given thread at a given point 628f32441dSMarco Elverin program execution is a run-time concept. The static analysis works by 638f32441dSMarco Elvercalculating an approximation of that set, called the context environment. The 648f32441dSMarco Elvercontext environment is calculated for every program point, and describes the 658f32441dSMarco Elverset of contexts that are statically known to be active, or inactive, at that 668f32441dSMarco Elverparticular point. This environment is a conservative approximation of the full 678f32441dSMarco Elverset of contexts that will actually be active in a thread at run-time. 688f32441dSMarco Elver 698f32441dSMarco ElverMore details are also documented `here 708f32441dSMarco Elver<https://clang.llvm.org/docs/ThreadSafetyAnalysis.html>`_. 718f32441dSMarco Elver 728f32441dSMarco Elver.. note:: 738f32441dSMarco Elver Clang's analysis explicitly does not infer context locks acquired or 748f32441dSMarco Elver released by inline functions. It requires explicit annotations to (a) assert 758f32441dSMarco Elver that it's not a bug if a context lock is released or acquired, and (b) to 768f32441dSMarco Elver retain consistency between inline and non-inline function declarations. 778f32441dSMarco Elver 788f32441dSMarco ElverSupported Kernel Primitives 798f32441dSMarco Elver~~~~~~~~~~~~~~~~~~~~~~~~~~~ 808f32441dSMarco Elver 81f16a802dSMarco ElverCurrently the following synchronization primitives are supported: 82eb7d96a1SMarco Elver`raw_spinlock_t`, `spinlock_t`, `rwlock_t`, `mutex`, `seqlock_t`, 8347907461SMarco Elver`bit_spinlock`, RCU, SRCU (`srcu_struct`), `rw_semaphore`, `local_lock_t`, 8447907461SMarco Elver`ww_mutex`. 858f32441dSMarco Elver 86*d084a737SMarco ElverTo initialize variables guarded by a context lock with an initialization 87*d084a737SMarco Elverfunction (``type_init(&lock)``), prefer using ``guard(type_init)(&lock)`` or 88*d084a737SMarco Elver``scoped_guard(type_init, &lock) { ... }`` to initialize such guarded members 89*d084a737SMarco Elveror globals in the enclosing scope. This initializes the context lock and treats 90*d084a737SMarco Elverthe context as active within the initialization scope (initialization implies 91*d084a737SMarco Elverexclusive access to the underlying object). 92*d084a737SMarco Elver 93*d084a737SMarco ElverFor example:: 94*d084a737SMarco Elver 95*d084a737SMarco Elver struct my_data { 96*d084a737SMarco Elver spinlock_t lock; 97*d084a737SMarco Elver int counter __guarded_by(&lock); 98*d084a737SMarco Elver }; 99*d084a737SMarco Elver 100*d084a737SMarco Elver void init_my_data(struct my_data *d) 101*d084a737SMarco Elver { 102*d084a737SMarco Elver ... 103*d084a737SMarco Elver guard(spinlock_init)(&d->lock); 104*d084a737SMarco Elver d->counter = 0; 105*d084a737SMarco Elver ... 106*d084a737SMarco Elver } 107*d084a737SMarco Elver 108*d084a737SMarco ElverAlternatively, initializing guarded variables can be done with context analysis 109*d084a737SMarco Elverdisabled, preferably in the smallest possible scope (due to lack of any other 110*d084a737SMarco Elverchecking): either with a ``context_unsafe(var = init)`` expression, or by 111*d084a737SMarco Elvermarking small initialization functions with the ``__context_unsafe(init)`` 112*d084a737SMarco Elverattribute. 1138f32441dSMarco Elver 1148f32441dSMarco ElverLockdep assertions, such as `lockdep_assert_held()`, inform the compiler's 1158f32441dSMarco Elvercontext analysis that the associated synchronization primitive is held after 1168f32441dSMarco Elverthe assertion. This avoids false positives in complex control-flow scenarios 1178f32441dSMarco Elverand encourages the use of Lockdep where static analysis is limited. For 1188f32441dSMarco Elverexample, this is useful when a function doesn't *always* require a lock, making 1198f32441dSMarco Elver`__must_hold()` inappropriate. 1208f32441dSMarco Elver 1218f32441dSMarco ElverKeywords 1228f32441dSMarco Elver~~~~~~~~ 1238f32441dSMarco Elver 1248f32441dSMarco Elver.. kernel-doc:: include/linux/compiler-context-analysis.h 1258f32441dSMarco Elver :identifiers: context_lock_struct 1268f32441dSMarco Elver token_context_lock token_context_lock_instance 1278f32441dSMarco Elver __guarded_by __pt_guarded_by 1288f32441dSMarco Elver __must_hold 1298f32441dSMarco Elver __must_not_hold 1308f32441dSMarco Elver __acquires 1318f32441dSMarco Elver __cond_acquires 1328f32441dSMarco Elver __releases 1338f32441dSMarco Elver __must_hold_shared 1348f32441dSMarco Elver __acquires_shared 1358f32441dSMarco Elver __cond_acquires_shared 1368f32441dSMarco Elver __releases_shared 1378f32441dSMarco Elver __acquire 1388f32441dSMarco Elver __release 1398f32441dSMarco Elver __acquire_shared 1408f32441dSMarco Elver __release_shared 1418f32441dSMarco Elver __acquire_ret 1428f32441dSMarco Elver __acquire_shared_ret 1438f32441dSMarco Elver context_unsafe 1448f32441dSMarco Elver __context_unsafe 1458f32441dSMarco Elver disable_context_analysis enable_context_analysis 1468f32441dSMarco Elver 1478f32441dSMarco Elver.. note:: 1488f32441dSMarco Elver The function attribute `__no_context_analysis` is reserved for internal 1498f32441dSMarco Elver implementation of context lock types, and should be avoided in normal code. 1508f32441dSMarco Elver 1518f32441dSMarco ElverBackground 1528f32441dSMarco Elver---------- 1538f32441dSMarco Elver 1548f32441dSMarco ElverClang originally called the feature `Thread Safety Analysis 1558f32441dSMarco Elver<https://clang.llvm.org/docs/ThreadSafetyAnalysis.html>`_, with some keywords 1568f32441dSMarco Elverand documentation still using the thread-safety-analysis-only terminology. This 1578f32441dSMarco Elverwas later changed and the feature became more flexible, gaining the ability to 1588f32441dSMarco Elverdefine custom "capabilities". Its foundations can be found in `Capability 1598f32441dSMarco ElverSystems <https://www.cs.cornell.edu/talc/papers/capabilities.pdf>`_, used to 1608f32441dSMarco Elverspecify the permissibility of operations to depend on some "capability" being 1618f32441dSMarco Elverheld (or not held). 1628f32441dSMarco Elver 1638f32441dSMarco ElverBecause the feature is not just able to express capabilities related to 1648f32441dSMarco Elversynchronization primitives, and "capability" is already overloaded in the 1658f32441dSMarco Elverkernel, the naming chosen for the kernel departs from Clang's initial "Thread 1668f32441dSMarco ElverSafety" and "capability" nomenclature; we refer to the feature as "Context 1678f32441dSMarco ElverAnalysis" to avoid confusion. The internal implementation still makes 1688f32441dSMarco Elverreferences to Clang's terminology in a few places, such as `-Wthread-safety` 1698f32441dSMarco Elverbeing the warning option that also still appears in diagnostic messages. 170