Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

docs: Improve discussion of this_cpu_ptr(), add raw_cpu_ptr()

Most of the this_cpu_*() operations may be used in preemptible code,
but not this_cpu_ptr(), and for good reasons. Therefore, better explain
the reasons and call out raw_cpu_ptr() as an alternative in certain very
special cases.

Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Boqun Feng <boqun.feng@gmail.com>
Cc: <linux-doc@vger.kernel.org>
Signed-off-by: Boqun Feng <boqun.feng@gmail.com>

authored by

Paul E. McKenney and committed by
Boqun Feng
df0cee43 bea1d19f

+15 -5
+15 -5
Documentation/core-api/this_cpu_ops.rst
··· 138 138 available. Instead, the offset of the local per cpu area is simply 139 139 added to the per cpu offset. 140 140 141 - Note that this operation is usually used in a code segment when 142 - preemption has been disabled. The pointer is then used to 143 - access local per cpu data in a critical section. When preemption 144 - is re-enabled this pointer is usually no longer useful since it may 145 - no longer point to per cpu data of the current processor. 141 + Note that this operation can only be used in code segments where 142 + smp_processor_id() may be used, for example, where preemption has been 143 + disabled. The pointer is then used to access local per cpu data in a 144 + critical section. When preemption is re-enabled this pointer is usually 145 + no longer useful since it may no longer point to per cpu data of the 146 + current processor. 146 147 148 + The special cases where it makes sense to obtain a per-CPU pointer in 149 + preemptible code are addressed by raw_cpu_ptr(), but such use cases need 150 + to handle cases where two different CPUs are accessing the same per cpu 151 + variable, which might well be that of a third CPU. These use cases are 152 + typically performance optimizations. For example, SRCU implements a pair 153 + of counters as a pair of per-CPU variables, and rcu_read_lock_nmisafe() 154 + uses raw_cpu_ptr() to get a pointer to some CPU's counter, and uses 155 + atomic_inc_long() to handle migration between the raw_cpu_ptr() and 156 + the atomic_inc_long(). 147 157 148 158 Per cpu variables and offsets 149 159 -----------------------------