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>
This commit is contained in:
Paul E. McKenney 2025-01-08 13:37:17 -08:00 committed by Boqun Feng
parent bea1d19f03
commit df0cee4311

View File

@ -138,12 +138,22 @@ get_cpu/put_cpu sequence requires. No processor number is
available. Instead, the offset of the local per cpu area is simply
added to the per cpu offset.
Note that this operation is usually used in a code segment when
preemption has been disabled. The pointer is then used to
access local per cpu data in a critical section. When preemption
is re-enabled this pointer is usually no longer useful since it may
no longer point to per cpu data of the current processor.
Note that this operation can only be used in code segments where
smp_processor_id() may be used, for example, where preemption has been
disabled. The pointer is then used to access local per cpu data in a
critical section. When preemption is re-enabled this pointer is usually
no longer useful since it may no longer point to per cpu data of the
current processor.
The special cases where it makes sense to obtain a per-CPU pointer in
preemptible code are addressed by raw_cpu_ptr(), but such use cases need
to handle cases where two different CPUs are accessing the same per cpu
variable, which might well be that of a third CPU. These use cases are
typically performance optimizations. For example, SRCU implements a pair
of counters as a pair of per-CPU variables, and rcu_read_lock_nmisafe()
uses raw_cpu_ptr() to get a pointer to some CPU's counter, and uses
atomic_inc_long() to handle migration between the raw_cpu_ptr() and
the atomic_inc_long().
Per cpu variables and offsets
-----------------------------