Skip to content

Commit 020e6c2

Browse files
committed
kcsan: Add example to data_race() kerneldoc header
Although the data_race() kerneldoc header accurately states what it does, some of the implications and usage patterns are non-obvious. Therefore, add a brief locking example and also state how to have KCSAN ignore accesses while also preventing the compiler from folding, spindling, or otherwise mutilating the access. [ paulmck: Apply Bart Van Assche feedback. ] [ paulmck: Apply feedback from Marco Elver. ] Reported-by: Bart Van Assche <[email protected]> Signed-off-by: Paul E. McKenney <[email protected]> Cc: Marco Elver <[email protected]> Cc: Breno Leitao <[email protected]> Cc: Jens Axboe <[email protected]>
1 parent 1613e60 commit 020e6c2

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

include/linux/compiler.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,9 +194,17 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val,
194194
* This data_race() macro is useful for situations in which data races
195195
* should be forgiven. One example is diagnostic code that accesses
196196
* shared variables but is not a part of the core synchronization design.
197+
* For example, if accesses to a given variable are protected by a lock,
198+
* except for diagnostic code, then the accesses under the lock should
199+
* be plain C-language accesses and those in the diagnostic code should
200+
* use data_race(). This way, KCSAN will complain if buggy lockless
201+
* accesses to that variable are introduced, even if the buggy accesses
202+
* are protected by READ_ONCE() or WRITE_ONCE().
197203
*
198204
* This macro *does not* affect normal code generation, but is a hint
199-
* to tooling that data races here are to be ignored.
205+
* to tooling that data races here are to be ignored. If the access must
206+
* be atomic *and* KCSAN should ignore the access, use both data_race()
207+
* and READ_ONCE(), for example, data_race(READ_ONCE(x)).
200208
*/
201209
#define data_race(expr) \
202210
({ \

tools/memory-model/Documentation/access-marking.txt

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ The Linux kernel provides the following access-marking options:
2424
4. WRITE_ONCE(), for example, "WRITE_ONCE(a, b);"
2525
The various forms of atomic_set() also fit in here.
2626

27+
5. __data_racy, for example "int __data_racy a;"
28+
29+
6. KCSAN's negative-marking assertions, ASSERT_EXCLUSIVE_ACCESS()
30+
and ASSERT_EXCLUSIVE_WRITER(), are described in the
31+
"ACCESS-DOCUMENTATION OPTIONS" section below.
2732

2833
These may be used in combination, as shown in this admittedly improbable
2934
example:
@@ -205,6 +210,23 @@ because doing otherwise prevents KCSAN from detecting violations of your
205210
code's synchronization rules.
206211

207212

213+
Use of __data_racy
214+
------------------
215+
216+
Adding the __data_racy type qualifier to the declaration of a variable
217+
causes KCSAN to treat all accesses to that variable as if they were
218+
enclosed by data_race(). However, __data_racy does not affect the
219+
compiler, though one could imagine hardened kernel builds treating the
220+
__data_racy type qualifier as if it was the volatile keyword.
221+
222+
Note well that __data_racy is subject to the same pointer-declaration
223+
rules as are other type qualifiers such as const and volatile.
224+
For example:
225+
226+
int __data_racy *p; // Pointer to data-racy data.
227+
int *__data_racy p; // Data-racy pointer to non-data-racy data.
228+
229+
208230
ACCESS-DOCUMENTATION OPTIONS
209231
============================
210232

@@ -342,7 +364,7 @@ as follows:
342364

343365
Because foo is read locklessly, all accesses are marked. The purpose
344366
of the ASSERT_EXCLUSIVE_WRITER() is to allow KCSAN to check for a buggy
345-
concurrent lockless write.
367+
concurrent write, whether marked or not.
346368

347369

348370
Lock-Protected Writes With Heuristic Lockless Reads

0 commit comments

Comments
 (0)