XCALL(9) | Kernel Developer's Manual | XCALL(9) |
xcall
, xc_broadcast
,
xc_unicast
, xc_wait
—
#include <sys/xcall.h>
typedef void (*xcfunc_t)(void *, void *);
uint64_t
xc_broadcast
(u_int
flags, xcfunc_t
func, void *arg1,
void *arg2);
uint64_t
xc_unicast
(u_int
flags, xcfunc_t
func, void *arg1,
void *arg2,
struct cpu_info *ci);
void
xc_wait
(uint64_t
where);
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 be found.
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 interrupting 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 preemption.
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 running on the CPU.
xc_broadcast
(flags,
func, arg1,
arg2)(*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 priority" call, and 0 for a "low priority"
call. XC_HIGHPRI
uses an
IPL_SOFTSERIAL
software interrupt while
XC_HIGHPRI_IPL
() uses a software interrupt with an
IPL specified by ipl.
xc_broadcast
() should not be called from interrupt
context.xc_unicast
(flags,
func, arg1,
arg2, ci)xc_broadcast
(), but call
(*func)
() on only the CPU indicated by
ci. xc_unicast
() also
returns a “ticket”.xc_wait
(where)xc_broadcast
() or
xc_unicast
() for the corresponding cross-call to
complete. xc_wait
() should be called from a thread
context.xcall
interface is implemented within the file
sys/kern/subr_xcall.c.
xcall
interface first appeared in
NetBSD 5.0.
February 1, 2018 | NetBSD 9.0 |