IPI(9) Kernel Developer's Manual IPI(9)

ipi
MI IPI interface

#include <sys/ipi.h>

typedef void (*ipi_func_t)(void *);

u_int
ipi_register(ipi_func_t func, void *arg);

void
ipi_unregister(u_int ipi_id);

void
ipi_trigger(u_int ipi_id, struct cpu_info *ci);

void
ipi_unicast(ipi_msg_t *msg, struct cpu_info *ci);

void
ipi_multicast(ipi_msg_t *msg, const kcpuset_t *target);

void
ipi_broadcast(ipi_msg_t *msg);

void
ipi_wait(ipi_msg_t *msg);

The machine-independent ipi interface provides capability to send inter-processor interrupts (IPIs) amongst CPUs. The interface has two mechanisms: asynchronous IPI to invoke functions with a constant argument and synchronous IPIs with the cross-call support.

Other synchronization interfaces are built using the MI IPI interface. For a general purpose inter-processor cross-calls or remote interrupts, use the xcall(9) or softint(9) interfaces.

The primary use cases of the MI IPIs include the following:

This interface allows dynamic registration of IPI handlers with a constant argument and asynchronous triggering of interrupts.
ipi_register(func, arg)
Register an IPI handler func with an arbitrary argument arg. Returns a non-zero IPI identifier on success and zero on failure.
ipi_unregister(ipi_id)
Unregister the IPI handler identified by the ipi_id.
ipi_trigger(ipi_id, ci)
Trigger an IPI identified by ipi_id on a remote CPU specified by ci. This function must be called with the kernel preemption disabled and the target CPU must be remote.

This interface provides capability to perform cross-calls, i.e. invoke an arbitrary function on a remote CPU. The invocations are performed synchronously and the caller must wait for completion. The cross-call is described by an IPI "message". The caller has to fill in an ipi_msg_t structure which has the following public members:
        ipi_func_t	func;
        void		arg;

The func member specifies a function to invoke and arg is the argument to be passed to the function.

ipi_unicast(msg, ci)
Send an IPI to a remote CPU specified by ci.
ipi_multicast(msg, target)
Send IPIs to a CPU set specified by target.
ipi_broadcast(msg)
Send IPIs to all CPUs.
ipi_wait(msg)
Wait until all IPIs complete.

All described functions, except ipi_wait(), must be called with the kernel preemption disabled. All synchronous IPI invocations must be completed (wait for them with the ipi_wait() function) before the IPI message structure can be destroyed or new cross-call requests can be performed.

Functions being called must be lightweight. They run at IPL_HIGH and should generally not use any other synchronization interfaces such as mutex(9). If spin-locks are used, they must be used carefully and have no contention.

The ipi interface is implemented within the file sys/kern/subr_ipi.c.

kcpuset(9), kpreempt(9), softint(9), spl(9), xcall(9)

The ipi interface first appeared in NetBSD 7.0.

Mindaugas Rasiukevicius <rmind@NetBSD.org>
May 25, 2014 NetBSD 8.99