access-marking.txt 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624
  1. MARKING SHARED-MEMORY ACCESSES
  2. ==============================
  3. This document provides guidelines for marking intentionally concurrent
  4. normal accesses to shared memory, that is "normal" as in accesses that do
  5. not use read-modify-write atomic operations. It also describes how to
  6. document these accesses, both with comments and with special assertions
  7. processed by the Kernel Concurrency Sanitizer (KCSAN). This discussion
  8. builds on an earlier LWN article [1] and Linux Foundation mentorship
  9. session [2].
  10. ACCESS-MARKING OPTIONS
  11. ======================
  12. The Linux kernel provides the following access-marking options:
  13. 1. Plain C-language accesses (unmarked), for example, "a = b;"
  14. 2. Data-race marking, for example, "data_race(a = b);"
  15. 3. READ_ONCE(), for example, "a = READ_ONCE(b);"
  16. The various forms of atomic_read() also fit in here.
  17. 4. WRITE_ONCE(), for example, "WRITE_ONCE(a, b);"
  18. The various forms of atomic_set() also fit in here.
  19. 5. __data_racy, for example "int __data_racy a;"
  20. 6. KCSAN's negative-marking assertions, ASSERT_EXCLUSIVE_ACCESS()
  21. and ASSERT_EXCLUSIVE_WRITER(), are described in the
  22. "ACCESS-DOCUMENTATION OPTIONS" section below.
  23. These may be used in combination, as shown in this admittedly improbable
  24. example:
  25. WRITE_ONCE(a, b + data_race(c + d) + READ_ONCE(e));
  26. Neither plain C-language accesses nor data_race() (#1 and #2 above) place
  27. any sort of constraint on the compiler's choice of optimizations [3].
  28. In contrast, READ_ONCE() and WRITE_ONCE() (#3 and #4 above) restrict the
  29. compiler's use of code-motion and common-subexpression optimizations.
  30. Therefore, if a given access is involved in an intentional data race,
  31. using READ_ONCE() for loads and WRITE_ONCE() for stores is usually
  32. preferable to data_race(), which in turn is usually preferable to plain
  33. C-language accesses. It is permissible to combine #2 and #3, for example,
  34. data_race(READ_ONCE(a)), which will both restrict compiler optimizations
  35. and disable KCSAN diagnostics.
  36. KCSAN will complain about many types of data races involving plain
  37. C-language accesses, but marking all accesses involved in a given data
  38. race with one of data_race(), READ_ONCE(), or WRITE_ONCE(), will prevent
  39. KCSAN from complaining. Of course, lack of KCSAN complaints does not
  40. imply correct code. Therefore, please take a thoughtful approach
  41. when responding to KCSAN complaints. Churning the code base with
  42. ill-considered additions of data_race(), READ_ONCE(), and WRITE_ONCE()
  43. is unhelpful.
  44. In fact, the following sections describe situations where use of
  45. data_race() and even plain C-language accesses is preferable to
  46. READ_ONCE() and WRITE_ONCE().
  47. Use of the data_race() Macro
  48. ----------------------------
  49. Here are some situations where data_race() should be used instead of
  50. READ_ONCE() and WRITE_ONCE():
  51. 1. Data-racy loads from shared variables whose values are used only
  52. for diagnostic purposes.
  53. 2. Data-racy reads whose values are checked against marked reload.
  54. 3. Reads whose values feed into error-tolerant heuristics.
  55. 4. Writes setting values that feed into error-tolerant heuristics.
  56. Data-Racy Reads for Approximate Diagnostics
  57. Approximate diagnostics include lockdep reports, monitoring/statistics
  58. (including /proc and /sys output), WARN*()/BUG*() checks whose return
  59. values are ignored, and other situations where reads from shared variables
  60. are not an integral part of the core concurrency design.
  61. In fact, use of data_race() instead READ_ONCE() for these diagnostic
  62. reads can enable better checking of the remaining accesses implementing
  63. the core concurrency design. For example, suppose that the core design
  64. prevents any non-diagnostic reads from shared variable x from running
  65. concurrently with updates to x. Then using plain C-language writes
  66. to x allows KCSAN to detect reads from x from within regions of code
  67. that fail to exclude the updates. In this case, it is important to use
  68. data_race() for the diagnostic reads because otherwise KCSAN would give
  69. false-positive warnings about these diagnostic reads.
  70. If it is necessary to both restrict compiler optimizations and disable
  71. KCSAN diagnostics, use both data_race() and READ_ONCE(), for example,
  72. data_race(READ_ONCE(a)).
  73. In theory, plain C-language loads can also be used for this use case.
  74. However, in practice this will have the disadvantage of causing KCSAN
  75. to generate false positives because KCSAN will have no way of knowing
  76. that the resulting data race was intentional.
  77. Data-Racy Reads That Are Checked Against Marked Reload
  78. The values from some reads are not implicitly trusted. They are instead
  79. fed into some operation that checks the full value against a later marked
  80. load from memory, which means that the occasional arbitrarily bogus value
  81. is not a problem. For example, if a bogus value is fed into cmpxchg(),
  82. all that happens is that this cmpxchg() fails, which normally results
  83. in a retry. Unless the race condition that resulted in the bogus value
  84. recurs, this retry will with high probability succeed, so no harm done.
  85. However, please keep in mind that a data_race() load feeding into
  86. a cmpxchg_relaxed() might still be subject to load fusing on some
  87. architectures. Therefore, it is best to capture the return value from
  88. the failing cmpxchg() for the next iteration of the loop, an approach
  89. that provides the compiler much less scope for mischievous optimizations.
  90. Capturing the return value from cmpxchg() also saves a memory reference
  91. in many cases.
  92. In theory, plain C-language loads can also be used for this use case.
  93. However, in practice this will have the disadvantage of causing KCSAN
  94. to generate false positives because KCSAN will have no way of knowing
  95. that the resulting data race was intentional.
  96. Reads Feeding Into Error-Tolerant Heuristics
  97. Values from some reads feed into heuristics that can tolerate occasional
  98. errors. Such reads can use data_race(), thus allowing KCSAN to focus on
  99. the other accesses to the relevant shared variables. But please note
  100. that data_race() loads are subject to load fusing, which can result in
  101. consistent errors, which in turn are quite capable of breaking heuristics.
  102. Therefore use of data_race() should be limited to cases where some other
  103. code (such as a barrier() call) will force the occasional reload.
  104. Note that this use case requires that the heuristic be able to handle
  105. any possible error. In contrast, if the heuristics might be fatally
  106. confused by one or more of the possible erroneous values, use READ_ONCE()
  107. instead of data_race().
  108. In theory, plain C-language loads can also be used for this use case.
  109. However, in practice this will have the disadvantage of causing KCSAN
  110. to generate false positives because KCSAN will have no way of knowing
  111. that the resulting data race was intentional.
  112. Writes Setting Values Feeding Into Error-Tolerant Heuristics
  113. The values read into error-tolerant heuristics come from somewhere,
  114. for example, from sysfs. This means that some code in sysfs writes
  115. to this same variable, and these writes can also use data_race().
  116. After all, if the heuristic can tolerate the occasional bogus value
  117. due to compiler-mangled reads, it can also tolerate the occasional
  118. compiler-mangled write, at least assuming that the proper value is in
  119. place once the write completes.
  120. Plain C-language stores can also be used for this use case. However,
  121. in kernels built with CONFIG_KCSAN_ASSUME_PLAIN_WRITES_ATOMIC=n, this
  122. will have the disadvantage of causing KCSAN to generate false positives
  123. because KCSAN will have no way of knowing that the resulting data race
  124. was intentional.
  125. Use of Plain C-Language Accesses
  126. --------------------------------
  127. Here are some example situations where plain C-language accesses should
  128. used instead of READ_ONCE(), WRITE_ONCE(), and data_race():
  129. 1. Accesses protected by mutual exclusion, including strict locking
  130. and sequence locking.
  131. 2. Initialization-time and cleanup-time accesses. This covers a
  132. wide variety of situations, including the uniprocessor phase of
  133. system boot, variables to be used by not-yet-spawned kthreads,
  134. structures not yet published to reference-counted or RCU-protected
  135. data structures, and the cleanup side of any of these situations.
  136. 3. Per-CPU variables that are not accessed from other CPUs.
  137. 4. Private per-task variables, including on-stack variables, some
  138. fields in the task_struct structure, and task-private heap data.
  139. 5. Any other loads for which there is not supposed to be a concurrent
  140. store to that same variable.
  141. 6. Any other stores for which there should be neither concurrent
  142. loads nor concurrent stores to that same variable.
  143. But note that KCSAN makes two explicit exceptions to this rule
  144. by default, refraining from flagging plain C-language stores:
  145. a. No matter what. You can override this default by building
  146. with CONFIG_KCSAN_ASSUME_PLAIN_WRITES_ATOMIC=n.
  147. b. When the store writes the value already contained in
  148. that variable. You can override this default by building
  149. with CONFIG_KCSAN_REPORT_VALUE_CHANGE_ONLY=n.
  150. c. When one of the stores is in an interrupt handler and
  151. the other in the interrupted code. You can override this
  152. default by building with CONFIG_KCSAN_INTERRUPT_WATCHER=y.
  153. Note that it is important to use plain C-language accesses in these cases,
  154. because doing otherwise prevents KCSAN from detecting violations of your
  155. code's synchronization rules.
  156. Use of __data_racy
  157. ------------------
  158. Adding the __data_racy type qualifier to the declaration of a variable
  159. causes KCSAN to treat all accesses to that variable as if they were
  160. enclosed by data_race(). However, __data_racy does not affect the
  161. compiler, though one could imagine hardened kernel builds treating the
  162. __data_racy type qualifier as if it was the volatile keyword.
  163. Note well that __data_racy is subject to the same pointer-declaration
  164. rules as are other type qualifiers such as const and volatile.
  165. For example:
  166. int __data_racy *p; // Pointer to data-racy data.
  167. int *__data_racy p; // Data-racy pointer to non-data-racy data.
  168. ACCESS-DOCUMENTATION OPTIONS
  169. ============================
  170. It is important to comment marked accesses so that people reading your
  171. code, yourself included, are reminded of the synchronization design.
  172. However, it is even more important to comment plain C-language accesses
  173. that are intentionally involved in data races. Such comments are
  174. needed to remind people reading your code, again, yourself included,
  175. of how the compiler has been prevented from optimizing those accesses
  176. into concurrency bugs.
  177. It is also possible to tell KCSAN about your synchronization design.
  178. For example, ASSERT_EXCLUSIVE_ACCESS(foo) tells KCSAN that any
  179. concurrent access to variable foo by any other CPU is an error, even
  180. if that concurrent access is marked with READ_ONCE(). In addition,
  181. ASSERT_EXCLUSIVE_WRITER(foo) tells KCSAN that although it is OK for there
  182. to be concurrent reads from foo from other CPUs, it is an error for some
  183. other CPU to be concurrently writing to foo, even if that concurrent
  184. write is marked with data_race() or WRITE_ONCE().
  185. Note that although KCSAN will call out data races involving either
  186. ASSERT_EXCLUSIVE_ACCESS() or ASSERT_EXCLUSIVE_WRITER() on the one hand
  187. and data_race() writes on the other, KCSAN will not report the location
  188. of these data_race() writes.
  189. EXAMPLES
  190. ========
  191. As noted earlier, the goal is to prevent the compiler from destroying
  192. your concurrent algorithm, to help the human reader, and to inform
  193. KCSAN of aspects of your concurrency design. This section looks at a
  194. few examples showing how this can be done.
  195. Lock Protection With Lockless Diagnostic Access
  196. -----------------------------------------------
  197. For example, suppose a shared variable "foo" is read only while a
  198. reader-writer spinlock is read-held, written only while that same
  199. spinlock is write-held, except that it is also read locklessly for
  200. diagnostic purposes. The code might look as follows:
  201. int foo;
  202. DEFINE_RWLOCK(foo_rwlock);
  203. void update_foo(int newval)
  204. {
  205. write_lock(&foo_rwlock);
  206. foo = newval;
  207. do_something(newval);
  208. write_unlock(&foo_rwlock);
  209. }
  210. int read_foo(void)
  211. {
  212. int ret;
  213. read_lock(&foo_rwlock);
  214. do_something_else();
  215. ret = foo;
  216. read_unlock(&foo_rwlock);
  217. return ret;
  218. }
  219. void read_foo_diagnostic(void)
  220. {
  221. pr_info("Current value of foo: %d\n", data_race(foo));
  222. }
  223. The reader-writer lock prevents the compiler from introducing concurrency
  224. bugs into any part of the main algorithm using foo, which means that
  225. the accesses to foo within both update_foo() and read_foo() can (and
  226. should) be plain C-language accesses. One benefit of making them be
  227. plain C-language accesses is that KCSAN can detect any erroneous lockless
  228. reads from or updates to foo. The data_race() in read_foo_diagnostic()
  229. tells KCSAN that data races are expected, and should be silently
  230. ignored. This data_race() also tells the human reading the code that
  231. read_foo_diagnostic() might sometimes return a bogus value.
  232. If it is necessary to suppress compiler optimization and also detect
  233. buggy lockless writes, read_foo_diagnostic() can be updated as follows:
  234. void read_foo_diagnostic(void)
  235. {
  236. pr_info("Current value of foo: %d\n", data_race(READ_ONCE(foo)));
  237. }
  238. Alternatively, given that KCSAN is to ignore all accesses in this function,
  239. this function can be marked __no_kcsan and the data_race() can be dropped:
  240. void __no_kcsan read_foo_diagnostic(void)
  241. {
  242. pr_info("Current value of foo: %d\n", READ_ONCE(foo));
  243. }
  244. However, in order for KCSAN to detect buggy lockless writes, your kernel
  245. must be built with CONFIG_KCSAN_ASSUME_PLAIN_WRITES_ATOMIC=n. If you
  246. need KCSAN to detect such a write even if that write did not change
  247. the value of foo, you also need CONFIG_KCSAN_REPORT_VALUE_CHANGE_ONLY=n.
  248. If you need KCSAN to detect such a write happening in an interrupt handler
  249. running on the same CPU doing the legitimate lock-protected write, you
  250. also need CONFIG_KCSAN_INTERRUPT_WATCHER=y. With some or all of these
  251. Kconfig options set properly, KCSAN can be quite helpful, although
  252. it is not necessarily a full replacement for hardware watchpoints.
  253. On the other hand, neither are hardware watchpoints a full replacement
  254. for KCSAN because it is not always easy to tell hardware watchpoint to
  255. conditionally trap on accesses.
  256. Lock-Protected Writes With Lockless Reads
  257. -----------------------------------------
  258. For another example, suppose a shared variable "foo" is updated only
  259. while holding a spinlock, but is read locklessly. The code might look
  260. as follows:
  261. int foo;
  262. DEFINE_SPINLOCK(foo_lock);
  263. void update_foo(int newval)
  264. {
  265. spin_lock(&foo_lock);
  266. WRITE_ONCE(foo, newval);
  267. ASSERT_EXCLUSIVE_WRITER(foo);
  268. do_something(newval);
  269. spin_unlock(&foo_wlock);
  270. }
  271. int read_foo(void)
  272. {
  273. do_something_else();
  274. return READ_ONCE(foo);
  275. }
  276. Because foo is read locklessly, all accesses are marked. The purpose
  277. of the ASSERT_EXCLUSIVE_WRITER() is to allow KCSAN to check for a buggy
  278. concurrent write, whether marked or not.
  279. Lock-Protected Writes With Heuristic Lockless Reads
  280. ---------------------------------------------------
  281. For another example, suppose that the code can normally make use of
  282. a per-data-structure lock, but there are times when a global lock
  283. is required. These times are indicated via a global flag. The code
  284. might look as follows, and is based loosely on nf_conntrack_lock(),
  285. nf_conntrack_all_lock(), and nf_conntrack_all_unlock():
  286. bool global_flag;
  287. DEFINE_SPINLOCK(global_lock);
  288. struct foo {
  289. spinlock_t f_lock;
  290. int f_data;
  291. };
  292. /* All foo structures are in the following array. */
  293. int nfoo;
  294. struct foo *foo_array;
  295. void do_something_locked(struct foo *fp)
  296. {
  297. /* This works even if data_race() returns nonsense. */
  298. if (!data_race(global_flag)) {
  299. spin_lock(&fp->f_lock);
  300. if (!smp_load_acquire(&global_flag)) {
  301. do_something(fp);
  302. spin_unlock(&fp->f_lock);
  303. return;
  304. }
  305. spin_unlock(&fp->f_lock);
  306. }
  307. spin_lock(&global_lock);
  308. /* global_lock held, thus global flag cannot be set. */
  309. spin_lock(&fp->f_lock);
  310. spin_unlock(&global_lock);
  311. /*
  312. * global_flag might be set here, but begin_global()
  313. * will wait for ->f_lock to be released.
  314. */
  315. do_something(fp);
  316. spin_unlock(&fp->f_lock);
  317. }
  318. void begin_global(void)
  319. {
  320. int i;
  321. spin_lock(&global_lock);
  322. WRITE_ONCE(global_flag, true);
  323. for (i = 0; i < nfoo; i++) {
  324. /*
  325. * Wait for pre-existing local locks. One at
  326. * a time to avoid lockdep limitations.
  327. */
  328. spin_lock(&fp->f_lock);
  329. spin_unlock(&fp->f_lock);
  330. }
  331. }
  332. void end_global(void)
  333. {
  334. smp_store_release(&global_flag, false);
  335. spin_unlock(&global_lock);
  336. }
  337. All code paths leading from the do_something_locked() function's first
  338. read from global_flag acquire a lock, so endless load fusing cannot
  339. happen.
  340. If the value read from global_flag is true, then global_flag is
  341. rechecked while holding ->f_lock, which, if global_flag is now false,
  342. prevents begin_global() from completing. It is therefore safe to invoke
  343. do_something().
  344. Otherwise, if either value read from global_flag is true, then after
  345. global_lock is acquired global_flag must be false. The acquisition of
  346. ->f_lock will prevent any call to begin_global() from returning, which
  347. means that it is safe to release global_lock and invoke do_something().
  348. For this to work, only those foo structures in foo_array[] may be passed
  349. to do_something_locked(). The reason for this is that the synchronization
  350. with begin_global() relies on momentarily holding the lock of each and
  351. every foo structure.
  352. The smp_load_acquire() and smp_store_release() are required because
  353. changes to a foo structure between calls to begin_global() and
  354. end_global() are carried out without holding that structure's ->f_lock.
  355. The smp_load_acquire() and smp_store_release() ensure that the next
  356. invocation of do_something() from do_something_locked() will see those
  357. changes.
  358. Lockless Reads and Writes
  359. -------------------------
  360. For another example, suppose a shared variable "foo" is both read and
  361. updated locklessly. The code might look as follows:
  362. int foo;
  363. int update_foo(int newval)
  364. {
  365. int ret;
  366. ret = xchg(&foo, newval);
  367. do_something(newval);
  368. return ret;
  369. }
  370. int read_foo(void)
  371. {
  372. do_something_else();
  373. return READ_ONCE(foo);
  374. }
  375. Because foo is accessed locklessly, all accesses are marked. It does
  376. not make sense to use ASSERT_EXCLUSIVE_WRITER() in this case because
  377. there really can be concurrent lockless writers. KCSAN would
  378. flag any concurrent plain C-language reads from foo, and given
  379. CONFIG_KCSAN_ASSUME_PLAIN_WRITES_ATOMIC=n, also any concurrent plain
  380. C-language writes to foo.
  381. Lockless Reads and Writes, But With Single-Threaded Initialization
  382. ------------------------------------------------------------------
  383. For yet another example, suppose that foo is initialized in a
  384. single-threaded manner, but that a number of kthreads are then created
  385. that locklessly and concurrently access foo. Some snippets of this code
  386. might look as follows:
  387. int foo;
  388. void initialize_foo(int initval, int nkthreads)
  389. {
  390. int i;
  391. foo = initval;
  392. ASSERT_EXCLUSIVE_ACCESS(foo);
  393. for (i = 0; i < nkthreads; i++)
  394. kthread_run(access_foo_concurrently, ...);
  395. }
  396. /* Called from access_foo_concurrently(). */
  397. int update_foo(int newval)
  398. {
  399. int ret;
  400. ret = xchg(&foo, newval);
  401. do_something(newval);
  402. return ret;
  403. }
  404. /* Also called from access_foo_concurrently(). */
  405. int read_foo(void)
  406. {
  407. do_something_else();
  408. return READ_ONCE(foo);
  409. }
  410. The initialize_foo() uses a plain C-language write to foo because there
  411. are not supposed to be concurrent accesses during initialization. The
  412. ASSERT_EXCLUSIVE_ACCESS() allows KCSAN to flag buggy concurrent unmarked
  413. reads, and the ASSERT_EXCLUSIVE_ACCESS() call further allows KCSAN to
  414. flag buggy concurrent writes, even if: (1) Those writes are marked or
  415. (2) The kernel was built with CONFIG_KCSAN_ASSUME_PLAIN_WRITES_ATOMIC=y.
  416. Checking Stress-Test Race Coverage
  417. ----------------------------------
  418. When designing stress tests it is important to ensure that race conditions
  419. of interest really do occur. For example, consider the following code
  420. fragment:
  421. int foo;
  422. int update_foo(int newval)
  423. {
  424. return xchg(&foo, newval);
  425. }
  426. int xor_shift_foo(int shift, int mask)
  427. {
  428. int old, new, newold;
  429. newold = data_race(foo); /* Checked by cmpxchg(). */
  430. do {
  431. old = newold;
  432. new = (old << shift) ^ mask;
  433. newold = cmpxchg(&foo, old, new);
  434. } while (newold != old);
  435. return old;
  436. }
  437. int read_foo(void)
  438. {
  439. return READ_ONCE(foo);
  440. }
  441. If it is possible for update_foo(), xor_shift_foo(), and read_foo() to be
  442. invoked concurrently, the stress test should force this concurrency to
  443. actually happen. KCSAN can evaluate the stress test when the above code
  444. is modified to read as follows:
  445. int foo;
  446. int update_foo(int newval)
  447. {
  448. ASSERT_EXCLUSIVE_ACCESS(foo);
  449. return xchg(&foo, newval);
  450. }
  451. int xor_shift_foo(int shift, int mask)
  452. {
  453. int old, new, newold;
  454. newold = data_race(foo); /* Checked by cmpxchg(). */
  455. do {
  456. old = newold;
  457. new = (old << shift) ^ mask;
  458. ASSERT_EXCLUSIVE_ACCESS(foo);
  459. newold = cmpxchg(&foo, old, new);
  460. } while (newold != old);
  461. return old;
  462. }
  463. int read_foo(void)
  464. {
  465. ASSERT_EXCLUSIVE_ACCESS(foo);
  466. return READ_ONCE(foo);
  467. }
  468. If a given stress-test run does not result in KCSAN complaints from
  469. each possible pair of ASSERT_EXCLUSIVE_ACCESS() invocations, the
  470. stress test needs improvement. If the stress test was to be evaluated
  471. on a regular basis, it would be wise to place the above instances of
  472. ASSERT_EXCLUSIVE_ACCESS() under #ifdef so that they did not result in
  473. false positives when not evaluating the stress test.
  474. REFERENCES
  475. ==========
  476. [1] "Concurrency bugs should fear the big bad data-race detector (part 2)"
  477. https://lwn.net/Articles/816854/
  478. [2] "The Kernel Concurrency Sanitizer"
  479. https://www.linuxfoundation.org/webinars/the-kernel-concurrency-sanitizer
  480. [3] "Who's afraid of a big bad optimizing compiler?"
  481. https://lwn.net/Articles/793253/