I'm trying to gain some understanding of how mp_rendezvous works on x86, and I have a few questions:
- There are two variants,
mp_rendezvous_no_intrs
andmp_rendezvous
. The first states that it disables interrupts during the execution of the requested function. However both boil down tomp_cpus_call1
, which seems to disable interrupts for reasons not related to whether the "no_intrs" variant of mp_rendezvous was called (from osfmk/i386/mp.c), if the function is being called on cpus other than the master cpu:
topo_lock = (cpus != cpu_to_cpumask(master_cpu));
if (topo_lock) {
ml_set_interrupts_enabled(FALSE);
(void) mp_safe_spin_lock(&x86_topo_lock);
}
Additionally interrupts seem to be disabled for the execution on the current CPU, as well:
/* Call locally if mode not SYNC */
if (mode != SYNC && call_self) {
KERNEL_DEBUG_CONSTANT(
TRACE_MP_CPUS_CALL_LOCAL,
VM_KERNEL_UNSLIDE(action_func), VM_KERNEL_UNSLIDE_OR_PERM(arg0), VM_KERNEL_UNSLIDE_OR_PERM(arg1), 0, 0);
if (action_func != NULL) {
ml_set_interrupts_enabled(FALSE);
action_func(arg0, arg1);
ml_set_interrupts_enabled(intrs_enabled);
}
}
Finally, I noticed that if I have a function that is being called via mp_rendezvous, and trace it using DTrace, only the execution on the CPU that mp_rendezvous is called on hits the Dtrace probe. Is that because the other CPU's are executing the function on an interrupt thread when handling the IPI?
Thank you,
Neal