| PERCPU(9) | Kernel Developer's Manual | PERCPU(9) |
percpu,
percpu_alloc, percpu_create,
percpu_free, percpu_getref,
percpu_putref,
percpu_foreach,
percpu_foreach_xcall —
per-CPU storage allocator
#include
<sys/percpu.h>
typedef void (*percpu_callback_t)(void *, void *, struct cpu_info *);
percpu_t *
percpu_alloc(size_t
size);
percpu_t *
percpu_create(size_t
size, percpu_callback_t
ctor, percpu_callback_t
dtor, void
*arg);
void
percpu_free(percpu_t
*pc, size_t
size);
void *
percpu_getref(percpu_t
*pc);
void
percpu_putref(percpu_t
*pc);
void
percpu_foreach(percpu_t
*pc, percpu_callback_t
cb, void *arg);
void
percpu_foreach_xcall(percpu_t
*pc, u_int xcflags,
percpu_callback_t cb,
void *arg);
The machine-independent percpu interface
provides per-CPU, CPU-local memory reservations to kernel subsystems.
percpu_alloc(size);
reserves on each CPU an independent memory region of
size bytes that is local to that CPU, returning a
handle (percpu_t) to those regions. A thread may
subsequently ask for a pointer, p, to the region held
by the percpu_t on the thread's current CPU. Until the
thread relinquishes the pointer, or voluntarily sleeps, the thread may read
or write the region at p without causing
interprocessor memory synchronization.
percpu_alloc(size)percpu_alloc() returns a handle for the per-CPU
storage.percpu_create(size,
ctor, dtor,
arg)percpu_alloc(), but before any access to the
storage on any CPU, arrange to call
(*ctor)(p,
arg, ci), where
p is the pointer to that CPU's storage and
ci is the struct cpu_info *
for that CPU. This may happen synchronously in
percpu_create() or when a CPU is attached later.
Further, arrange that percpu_free() will do the
same with (*dtor)(p,
arg, ci).
ctor and dtor MAY sleep, e.g. to allocate memory or to wait for users to drain before deallocating memory. Do not rely on any particular order of iteration over the CPUs.
percpu_free(pc,
size)percpu_alloc() or
percpu_create().
When percpu_free() returns,
pc is undefined. Treat this as an expensive
operation.percpu_getref(pc)percpu_getref() in either thread or interrupt
context. Follow each percpu_getref() call with a
matching call to percpu_putref().
Caller MUST NOT sleep
after
percpu_getref(),
not even on an adaptive lock, before
percpu_putref().
percpu_putref(pc)percpu_getref(). Re-enables
preemption.percpu_foreach(pc,
cb, arg)(*cb)(p,
arg, ci);. The call to
cb runs in the current thread; use
percpu_foreach_xcall() to execute the call to
cb on the remote CPUs.
Must be used in thread context. cb MUST NOT sleep except on adaptive locks, and should be fast. Do not rely on any particular order of iteration over the CPUs.
percpu_foreach_xcall(pc,
xcflags, cb,
arg)percpu_foreach(),
except the call to cb executes on the remote CPUs.
The xcflags argument specifies how the cross calls
are invoked; see
xc_broadcast(9). The
same caveats and restrictions that apply to
percpu_foreach() also apply to
percpu_foreach_xcall().The percpu interface is implemented within
the file sys/kern/subr_percpu.c.
The percpu interface first appeared in
NetBSD 6.0.
YAMAMOTO Takashi <yamt@NetBSD.org>
| February 7, 2020 | NetBSD 11.0 |