- NetBSD Manual Pages
XCALL(9) NetBSD Kernel Developer's Manual XCALL(9)
Powered by man-cgi (2021-06-01).
Maintained for NetBSD
by Kimmo Suominen.
Based on man-cgi by Panagiotis Christias.
xcall, xc_broadcast, xc_unicast, xc_wait, xc_barrier -- cross-call inter-
typedef void (*xcfunc_t)(void *, void *);
xc_broadcast(u_int flags, xcfunc_t func, void *arg1, void *arg2);
xc_unicast(u_int flags, xcfunc_t func, void *arg1, void *arg2,
struct cpu_info *ci);
The machine-independent xcall interface allows any CPU in the system to
request that an arbitrary function be executed on any other CPU.
Sometimes it is necessary to modify hardware state that is tied directly
to individual CPUs (such as a CPU's local timer), and these updates can
not be done remotely by another CPU. The LWP requesting the update may
be unable to guarantee that it will be running on the CPU where the
update must occur, when the update occurs.
Additionally, it is sometimes necessary to modify per-CPU software state
from a remote CPU. Where these update operations are so rare or the
access to the per-CPU data so frequent that the cost of using locking or
atomic operations to provide coherency is prohibitive, another way must
Cross calls help to solve these types of problem. However, since this
facility is heavyweight, it is expected that it will not be used often.
xcall provides a mechanism for making ``low priority'' cross calls. The
function to be executed runs on the remote CPU within a thread context,
and not from a software interrupt, so it can ensure that it is not inter-
rupting other code running on the CPU, and so has exclusive access to the
CPU. Keep in mind that unless disabled, it may cause a kernel preemp-
xcall also provides a mechanism for making ``high priority'' cross calls.
The function to be executed runs on the remote CPU within a software
interrupt context, possibly interrupting other lower-priority code run-
ning on the CPU.
Functions being called should be relatively lightweight. They may block
on locks, but carefully and minimally, to not interfere with other cross
calls in the system.
xc_broadcast(flags, func, arg1, arg2)
Call (*func)(arg1, arg2) on all CPUs in the system. Return a
uint64_t ``ticket'' to xc_wait() on for the cross-call to complete.
flags should be XC_HIGHPRI or XC_HIGHPRI_IPL(ipl) for a "high pri-
ority" call, and 0 for a "low priority" call. XC_HIGHPRI uses an
IPL_SOFTSERIAL software interrupt while XC_HIGHPRI_IPL uses a soft-
ware interrupt with an IPL specified by ipl. xc_broadcast() should
not be called from interrupt context.
xc_unicast(flags, func, arg1, arg2, ci)
Like xc_broadcast(), but call func on only the CPU indicated by ci.
xc_unicast() also returns a ``ticket''.
Wait on the ``ticket'' returned by a prior xc_broadcast() or
xc_unicast() for the corresponding cross-call to complete.
xc_wait() should be called from a thread context.
Issue a broadcast cross-call that does nothing, and wait for it to
This functions like a memory barrier that forces all prior opera-
tions in program order to globally happen before all subsequent
operations in program order, as witnessed by every CPU.
This additionally waits for all higher-priority activity on the CPU
to complete, according to flags:
- xc_barrier(0 ) waits for any pending kpreempt_disable(9) sec-
tions or activity at interrupt priority level above IPL_NONE to
finish on all CPUs.
- xc_barrier(XC_HIGHPRI_IPL(ipl) ) waits for any pending activity
at the software interrupt priority level ipl or higher to fin-
ish on all CPUs.
xc_barrier() is much more expensive than membar_ops(3), so it
should be used sparingly, only to publish information infrequently
-- for example, during module load and unload -- when the cost of a
memory barrier on the consumer side would be prohibitive.
The xcall interface is implemented within the file sys/kern/subr_xcall.c.
membar_ops(3), kpreempt(9), percpu(9), softint(9)
The xcall interface first appeared in NetBSD 5.0.
Andrew Doran <ad@NetBSD.org>
NetBSD 10.99 February 1, 2020 NetBSD 10.99