IPI(9)

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

# NAME

ipi — MI IPI interface

# SYNOPSIS

#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);

# DESCRIPTION

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:

- provide a facility for the softint(9) subsystem to schedule software interrupts on remote CPUs
- provide a facility for the xcall(9) subsystem
- abstract IPI handling and facilitate machine-dependent code

## Asynchronous IPI interface

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.

## Synchronous IPI interface

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.

# NOTES

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.

# CODE REFERENCES

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

# SEE ALSO

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

# HISTORY

The ipi interface first appeared in NetBSD 7.0.

# AUTHORS

Mindaugas Rasiukevicius <rmind@NetBSD.org>

May 25, 2014 | NetBSD 8.0