XCALL(9)
XCALL(9) โ cross-call interface (Kernel Developer's Manual) ๐ โจ
Ok bestie, this is the XCALL(9) page โ the one about making one CPU politely ask another CPU to run a function. Cross-call interface, but make it group-chat. ๐ซถ
โจ NAME โจ
xcall, xc_broadcast, xc_unicast, xc_wait, xc_barrier โ cross-call interface. That's the whole lineup, no cap. ๐
๐ฆ 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);
void
xc_barrier(u_int flags);
๐ DESCRIPTION ๐
The machine-independent xcall interface lets any CPU in the system request that an arbitrary function be executed on any other CPU. Literally remote-control for functions. ๐ฎ
Sometimes you gotta modify hardware state that is tied directly to individual CPUs โ think a CPU's local timer โ and those updates can't 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. So it's giving โI need this done over there, but I can't be over there.โ ๐ญ
Also: sometimes it is 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. Enter cross calls, stage left. ๐ฆ
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. It's an occasional main-character entrance, not an every-episode thing. ๐
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. Lowkey important. ๐ซถ
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. High-priority means it does not wait its turn. ๐
โญ 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. No hogging the group chat. ๐
๐ฅ FUNCTIONS ๐ฅ
xc_broadcast(flags, func, arg1, arg2)โ Call(*func)(arg1, arg2)on all CPUs in the system. Return auint64_tโticketโ toxc_wait()on for the cross-call to complete.flagsshould beXC_HIGHPRIorXC_HIGHPRI_IPL(ipl)for a "high priority" call, and0for a "low priority" call.XC_HIGHPRIuses anIPL_SOFTSERIALsoftware interrupt whileXC_HIGHPRI_IPLuses a software interrupt with an IPL specified byipl.xc_broadcast()should not be called from interrupt context.
๐จ Important vibe check: xc_broadcast() should not be called from interrupt context.
xc_unicast(flags, func, arg1, arg2, ci)โ Likexc_broadcast(), but callfuncon only the CPU indicated byci.xc_unicast()also returns a โticketโ. It's the DM version of a broadcast. ๐xc_wait(where)โ Wait on the โticketโ returned by a priorxc_broadcast()orxc_unicast()for the corresponding cross-call to complete.xc_wait()should be called from a thread context.xc_barrier(flags)โ Issue a broadcast cross-call that does nothing, and wait for it to complete.
This functions like a memory barrier that forces all prior operations 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 pendingkpreempt_disable(9)sections or activity at interrupt priority level aboveIPL_NONEto finish on all CPUs.xc_barrier(XC_HIGHPRI_IPL(ipl) )waits for any pending activity at the software interrupt priority leveliplor higher to finish 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. Use it like the fancy perfume, not the daily body spray. ๐
๐ CODE REFERENCES ๐
The xcall interface is implemented within the file sys/kern/subr_xcall.c. Go peek if you want the source tea. โ
๐ SEE ALSO ๐
membar_ops(3), kpreempt(9), percpu(9), softint(9). The whole friend group. ๐ซถ
๐ HISTORY ๐
The xcall interface first appeared in NetBSD 5.0. Vintage but still iconic. ๐
๐ AUTHORS ๐
Andrew Doran <ad@NetBSD.org> โ thank you for the cross-call lore. ๐
๐ That's the whole vibe: this page is from Debian, dated February 1, 2020, and it's the XCALL(9) manual page. Go make those cross-CPU calls behave, bestie. ๐ซถโจ
๐ฆ where this page comes from
- nixpkgs unstable: netbsd-source 11.0
- Copyright (c) 2010 The NetBSD Foundation, Inc
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms