NAME
xcall,
xc_broadcast,
xc_unicast,
xc_wait —
cross-call interface
SYNOPSIS
#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);
DESCRIPTION
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 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.
NOTES
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.
FUNCTIONS
-
-
- 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 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)
- Like xc_broadcast(), but call
(*func)() on only the CPU indicated by
ci. xc_unicast() also returns a
“ticket”.
-
-
- xc_wait(where)
- 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.
CODE REFERENCES
The
xcall interface is implemented within the file
sys/kern/subr_xcall.c.
SEE ALSO
kpreempt(9),
percpu(9),
softint(9)
HISTORY
The
xcall interface first appeared in
NetBSD
5.0.
AUTHORS
Andrew Doran
<
ad@NetBSD.org>