Changeset View
Changeset View
Standalone View
Standalone View
share/man/man9/ithread.9
Show All 17 Lines | |||||||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||||||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||||||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||||||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||||||||
.\" SUCH DAMAGE. | .\" SUCH DAMAGE. | ||||||||
.\" | .\" | ||||||||
.\" $FreeBSD$ | .\" $FreeBSD$ | ||||||||
.\" | .\" | ||||||||
.Dd August 25, 2006 | .Dd December 15, 2021 | ||||||||
.Dt ITHREAD 9 | .Dt ITHREAD 9 | ||||||||
pauamma_gundo.com: Reminder (if needed) to bump on commit. | |||||||||
Done Inline ActionsYes, will do. mhorne: Yes, will do. | |||||||||
.Os | .Os | ||||||||
.Sh NAME | .Sh NAME | ||||||||
.Nm ithread_add_handler , | .Nm intr_event_add_handler , | ||||||||
.Nm ithread_create , | .Nm intr_event_create , | ||||||||
.Nm ithread_destroy , | .Nm intr_event_destroy , | ||||||||
.Nm ithread_priority , | .Nm intr_event_remove_handler , | ||||||||
.Nm ithread_remove_handler , | .Nm intr_priority , | ||||||||
.Nm ithread_schedule | .Nd "kernel interrupt threads" | ||||||||
.Nd kernel interrupt threads | |||||||||
.Sh SYNOPSIS | .Sh SYNOPSIS | ||||||||
.In sys/param.h | .In sys/param.h | ||||||||
.In sys/bus.h | .In sys/bus.h | ||||||||
.In sys/interrupt.h | .In sys/interrupt.h | ||||||||
.Ft int | .Ft int | ||||||||
.Fo ithread_add_handler | .Fo intr_event_add_handler | ||||||||
.Fa "struct ithd *ithread" | .Fa "struct intr_event *ie" | ||||||||
.Fa "const char *name" | .Fa "const char *name" | ||||||||
.Fa "driver_filter_t filter" | |||||||||
.Fa "driver_intr_t handler" | .Fa "driver_intr_t handler" | ||||||||
.Fa "void *arg" | .Fa "void *arg" | ||||||||
.Fa "u_char pri" | .Fa "u_char pri" | ||||||||
.Fa "enum intr_type flags" | .Fa "enum intr_type flags" | ||||||||
.Fa "void **cookiep" | .Fa "void **cookiep" | ||||||||
.Fc | .Fc | ||||||||
.Ft int | .Ft int | ||||||||
.Fo ithread_create | .Fo intr_event_create | ||||||||
.Fa "struct ithd **ithread" | .Fa "struct intr_event **event" | ||||||||
.Fa "int vector" | .Fa "void *source" | ||||||||
.Fa "int flags" | .Fa "int flags" | ||||||||
.Fa "void (*disable)(int)" | .Fa "int irq" | ||||||||
.Fa "void (*enable)(int)" | .Fa "void (*pre_ithread)(void *)" | ||||||||
.Fa "void (*post_ithread)(void *)" | |||||||||
.Fa "void (*post_filter)(void *)" | |||||||||
.Fa "int (*assign_cpu)(void *, int)" | |||||||||
.Fa "const char *fmt" | .Fa "const char *fmt" | ||||||||
.Fa "..." | .Fa "..." | ||||||||
.Fc | .Fc | ||||||||
.Ft int | .Ft int | ||||||||
.Fn ithread_destroy "struct ithd *ithread" | .Fn intr_event_destroy "struct intr_event *ie" | ||||||||
.Ft u_char | |||||||||
.Fn ithread_priority "enum intr_type flags" | |||||||||
.Ft int | .Ft int | ||||||||
.Fn ithread_remove_handler "void *cookie" | .Fn intr_event_remove_handler "void *cookie" | ||||||||
.Ft int | .Ft u_char | ||||||||
.Fn ithread_schedule "struct ithd *ithread" "int do_switch" | .Fn intr_priority "enum intr_type flags" | ||||||||
.Sh DESCRIPTION | .Sh DESCRIPTION | ||||||||
Interrupt threads are kernel threads that run a list of handlers when | Interrupt threads are kernel threads that run a list of handlers when | ||||||||
triggered by either a hardware or software interrupt. | triggered by either a hardware or software interrupt. | ||||||||
Each interrupt handler has a name, handler function, handler argument, | Each interrupt handler has a name, handler function, handler argument, | ||||||||
priority, and various flags. | priority, and various flags. | ||||||||
Each interrupt thread maintains a list of handlers sorted by priority. | Each interrupt thread maintains a list of handlers sorted by priority. | ||||||||
This results in higher priority handlers being executed prior to lower | This results in higher priority handlers being executed prior to lower | ||||||||
priority handlers. | priority handlers. | ||||||||
Each thread assumes the priority of its highest priority handler for its | Each thread assumes the priority of its highest priority handler for its | ||||||||
process priority, or | process priority, or | ||||||||
.Dv PRIO_MAX | .Dv PRIO_MAX | ||||||||
if it has no handlers. | if it has no handlers. | ||||||||
Interrupt threads are also associated with a single interrupt source, | Interrupt threads are also associated with a single interrupt source, | ||||||||
represented as a vector number. | represented as a vector number. | ||||||||
.Pp | .Pp | ||||||||
The | The | ||||||||
.Fn ithread_create | .Fn intr_event_create | ||||||||
function creates a new interrupt thread. | function creates a new interrupt thread. | ||||||||
The | The | ||||||||
.Fa ithread | .Fa source | ||||||||
argument points to an | argument points to a | ||||||||
.Vt struct ithd | .Vt struct entr_event event | ||||||||
pauamma_gundo.comUnsubmitted Not Done Inline ActionsIs "entr" a typo for "intr"? pauamma_gundo.com: Is "entr" a typo for "intr"? | |||||||||
pointer that will point to the newly created thread upon success. | pointer that will point to the newly created thread upon success. | ||||||||
The | The | ||||||||
.Fa vector | |||||||||
argument specifies the interrupt source to associate this thread with. | |||||||||
The | |||||||||
.Fa flags | .Fa flags | ||||||||
argument is a mask of properties of this thread. | argument is a mask of properties of this thread. | ||||||||
The only valid flag currently for | The only valid flag currently for | ||||||||
.Fn ithread_create | .Fn intr_event_create | ||||||||
is | is | ||||||||
.Dv IT_SOFT | .Dv IE_SOFT | ||||||||
to specify that this interrupt thread is a software interrupt. | to specify that this interrupt thread is a software interrupt. | ||||||||
The | The | ||||||||
.Fa enable | .Fa enable | ||||||||
and | argument specify optional functions used to enable this | ||||||||
pauamma_gundo.comUnsubmitted Done Inline Actions
pauamma_gundo.com: | |||||||||
.Fa disable | |||||||||
arguments specify optional functions used to enable and disable this | |||||||||
interrupt thread's interrupt source. | interrupt thread's interrupt source. | ||||||||
The functions receive the vector corresponding to the thread's interrupt | |||||||||
source as their only argument. | |||||||||
The remaining arguments form a | The remaining arguments form a | ||||||||
.Xr printf 9 | .Xr printf 9 | ||||||||
argument list that is used to build the base name of the new ithread. | argument list that is used to build the base name of the new interrupt thread. | ||||||||
The full name of an interrupt thread is formed by concatenating the base | The full name of an interrupt thread is formed by concatenating the base | ||||||||
name of an interrupt thread with the names of all of its interrupt handlers. | name of an interrupt thread with the names of all of its interrupt handlers. | ||||||||
pauamma_gundo.comUnsubmitted Done Inline ActionsSince you're touching that area, "an interrupt thread" should be "the interrupt thread" here, if you're referring to the same one mentioned on the previous line. pauamma_gundo.com: Since you're touching that area, "an interrupt thread" should be "the interrupt thread" here… | |||||||||
.Pp | .Pp | ||||||||
The | The | ||||||||
.Fn ithread_destroy | .Fn intr_event_destroy | ||||||||
function destroys a previously created interrupt thread by releasing its | function destroys a previously created interrupt thread by releasing its | ||||||||
resources and arranging for the backing kernel thread to terminate. | resources and arranging for the backing kernel thread to terminate. | ||||||||
An interrupt thread can only be destroyed if it has no handlers remaining. | An interrupt thread can only be destroyed if it has no handlers remaining. | ||||||||
.Pp | .Pp | ||||||||
The | The | ||||||||
.Fn ithread_add_handler | .Fn intr_event_add_handler | ||||||||
function adds a new handler to an existing interrupt thread specified by | function adds a new handler to an existing interrupt thread specified by | ||||||||
.Fa ithread . | .Fa ithread . | ||||||||
The | The | ||||||||
.Fa name | .Fa name | ||||||||
argument specifies a name for this handler. | argument specifies a name for this handler. | ||||||||
The | The | ||||||||
.Fa handler | .Fa handler | ||||||||
and | and | ||||||||
Show All 12 Lines | |||||||||
If | If | ||||||||
.Fa cookiep | .Fa cookiep | ||||||||
is not | is not | ||||||||
.Dv NULL , | .Dv NULL , | ||||||||
then it will be assigned a cookie that can be used later to remove this | then it will be assigned a cookie that can be used later to remove this | ||||||||
handler. | handler. | ||||||||
.Pp | .Pp | ||||||||
The | The | ||||||||
.Fn ithread_remove_handler | .Fn intr_event_remove_handler | ||||||||
removes a handler from an interrupt thread. | removes a handler from an interrupt thread. | ||||||||
The | The | ||||||||
.Fa cookie | .Fa cookie | ||||||||
argument specifies the handler to remove from its thread. | argument specifies the handler to remove from its thread. | ||||||||
.Pp | |||||||||
The | |||||||||
.Fn ithread_schedule | |||||||||
function schedules an interrupt thread to run. | |||||||||
If the | |||||||||
.Fa do_switch | |||||||||
argument is non-zero and the interrupt thread is idle, then a context switch | |||||||||
will be forced after putting the interrupt thread on the run queue. | |||||||||
.Pp | |||||||||
The | |||||||||
.Fn ithread_priority | |||||||||
function translates the | |||||||||
.Dv INTR_TYPE_* | |||||||||
interrupt flags into interrupt handler priorities. | |||||||||
.Pp | |||||||||
The interrupt flags not related to the type of a particular interrupt | |||||||||
.Pq Dv INTR_TYPE_* | |||||||||
can be used to specify additional properties of both hardware and software | |||||||||
interrupt handlers. | |||||||||
The | |||||||||
.Dv INTR_EXCL | |||||||||
flag specifies that this handler cannot share an interrupt thread with | |||||||||
another handler. | |||||||||
The | |||||||||
.Dv INTR_MPSAFE | |||||||||
flag specifies that this handler is MP safe in that it does not need the | |||||||||
Giant mutex to be held while it is executed. | |||||||||
The | |||||||||
.Dv INTR_ENTROPY | |||||||||
flag specifies that the interrupt source this handler is tied to is a good | |||||||||
source of entropy, and thus that entropy should be gathered when an interrupt | |||||||||
from the handler's source triggers. | |||||||||
Presently, the | |||||||||
.Dv INTR_ENTROPY | |||||||||
flag is not valid for software interrupt handlers. | |||||||||
.Pp | |||||||||
It is not permitted to sleep in an interrupt thread; hence, any memory | |||||||||
or zone allocations in an interrupt thread should be specified with the | |||||||||
.Dv M_NOWAIT | |||||||||
flag set. | |||||||||
Any allocation errors must be handled thereafter. | |||||||||
.Sh RETURN VALUES | |||||||||
The | |||||||||
.Fn ithread_add_handler , | |||||||||
.Fn ithread_create , | |||||||||
.Fn ithread_destroy , | |||||||||
.Fn ithread_remove_handler , | |||||||||
and | |||||||||
.Fn ithread_schedule | |||||||||
functions return zero on success and non-zero on failure. | |||||||||
The | |||||||||
.Fn ithread_priority | |||||||||
function returns a process priority corresponding to the passed in interrupt | |||||||||
flags. | |||||||||
.Sh EXAMPLES | .Sh EXAMPLES | ||||||||
The | The | ||||||||
.Fn swi_add | .Fn swi_add | ||||||||
Not Done Inline ActionsWhile there, maybe change this to .Xr swi_add 9 to make it clearer it's not just an example and for easier comprehension of what the example does, not just how it does it? (I'm not part of the intended audience, so if you feel it's not needed, that's fine with me.) pauamma_gundo.com: While there, maybe change this to .Xr swi_add 9 to make it clearer it's not just an example and… | |||||||||
Done Inline ActionsSure, it will be done as part of D33476. mhorne: Sure, it will be done as part of D33476. | |||||||||
function demonstrates the use of | function demonstrates the use of | ||||||||
.Fn ithread_create | .Fn intr_event_create | ||||||||
and | and | ||||||||
.Fn ithread_add_handler . | .Fn intr_event_add_handler . | ||||||||
.Bd -literal -offset indent | .Bd -literal -offset indent | ||||||||
int | int | ||||||||
swi_add(struct ithd **ithdp, const char *name, driver_intr_t handler, | swi_add(struct ithd **ithdp, const char *name, driver_intr_t handler, | ||||||||
void *arg, int pri, enum intr_type flags, void **cookiep) | void *arg, int pri, enum intr_type flags, void **cookiep) | ||||||||
{ | { | ||||||||
struct proc *p; | struct proc *p; | ||||||||
struct ithd *ithd; | struct ithd *ithd; | ||||||||
int error; | int error; | ||||||||
Show All 16 Lines | if (ithdp != NULL) | ||||||||
*ithdp = ithd; | *ithdp = ithd; | ||||||||
} | } | ||||||||
return (ithread_add_handler(ithd, name, handler, arg, pri + PI_SOFT, | return (ithread_add_handler(ithd, name, handler, arg, pri + PI_SOFT, | ||||||||
flags, cookiep)); | flags, cookiep)); | ||||||||
} | } | ||||||||
.Ed | .Ed | ||||||||
.Sh ERRORS | .Sh ERRORS | ||||||||
The | The | ||||||||
.Fn ithread_add_handler | .Fn intr_event_add_handler | ||||||||
function will fail if: | function will fail if: | ||||||||
.Bl -tag -width Er | .Bl -tag -width Er | ||||||||
.It Bq Er EINVAL | .It Bq Er EINVAL | ||||||||
Any of the | The | ||||||||
.Fa ithread , | .Fa ie | ||||||||
.Fa handler , | |||||||||
or | or | ||||||||
.Fa name | .Fa name | ||||||||
arguments are | arguments are | ||||||||
.Dv NULL . | .Dv NULL. | ||||||||
.It Bq Er EINVAL | .It Bq Er EINVAL | ||||||||
The | The | ||||||||
.Dv INTR_EXCL | .Fa handler | ||||||||
and | |||||||||
.Fa filter | |||||||||
arguments are both | |||||||||
.Dv NULL. | |||||||||
.It Bq Er EINVAL | |||||||||
The | |||||||||
.Dv IH_EXCLUSIVE | |||||||||
flag is specified and the interrupt thread | flag is specified and the interrupt thread | ||||||||
.Fa ithread | .Fa ie | ||||||||
already has at least one handler, or the interrupt thread | already has at least one handler, or the interrupt thread | ||||||||
.Fa ithread | .Fa ie | ||||||||
already has an exclusive handler. | already has an exclusive handler. | ||||||||
.It Bq Er ENOMEM | |||||||||
Could not allocate needed memory for this handler. | |||||||||
.El | .El | ||||||||
.Pp | .Pp | ||||||||
The | The | ||||||||
.Fn ithread_create | .Fn intr_event_create | ||||||||
function will fail if: | function will fail if: | ||||||||
.Bl -tag -width Er | .Bl -tag -width Er | ||||||||
.It Bq Er EAGAIN | |||||||||
The system-imposed limit on the total | |||||||||
number of processes under execution would be exceeded. | |||||||||
The limit is given by the | |||||||||
.Xr sysctl 3 | |||||||||
MIB variable | |||||||||
.Dv KERN_MAXPROC . | |||||||||
.It Bq Er EINVAL | .It Bq Er EINVAL | ||||||||
A flag other than | A flag other than | ||||||||
.Dv IT_SOFT | .Dv IE_SOFT | ||||||||
was specified in the | was specified in the | ||||||||
.Fa flags | .Fa flags | ||||||||
parameter. | parameter. | ||||||||
.It Bq Er ENOMEM | |||||||||
Could not allocate needed memory for this interrupt thread. | |||||||||
.El | .El | ||||||||
.Pp | .Pp | ||||||||
The | The | ||||||||
.Fn ithread_destroy | .Fn intr_event_destroy | ||||||||
function will fail if: | function will fail if: | ||||||||
.Bl -tag -width Er | .Bl -tag -width Er | ||||||||
.It Bq Er EINVAL | .It Bq Er EINVAL | ||||||||
The | The | ||||||||
.Fa ithread | .Fa ie | ||||||||
argument is | argument is | ||||||||
.Dv NULL . | .Dv NULL . | ||||||||
.It Bq Er EINVAL | .It Bq Er EBUSY | ||||||||
The interrupt thread pointed to by | The interrupt event pointed to by | ||||||||
.Fa ithread | .Fa ie | ||||||||
has at least one handler. | has at least one handler which has not been removed with | ||||||||
.Fn intr_event_remove_handler . | |||||||||
.El | .El | ||||||||
.Pp | .Pp | ||||||||
The | The | ||||||||
.Fn ithread_remove_handler | .Fn intr_event_remove_handler | ||||||||
function will fail if: | function will fail if: | ||||||||
.Bl -tag -width Er | .Bl -tag -width Er | ||||||||
.It Bq Er EINVAL | .It Bq Er EINVAL | ||||||||
The | The | ||||||||
.Fa cookie | .Fa cookie | ||||||||
argument is | argument is | ||||||||
.Dv NULL . | .Dv NULL . | ||||||||
.El | .El | ||||||||
.Pp | |||||||||
The | |||||||||
.Fn ithread_schedule | |||||||||
function will fail if: | |||||||||
.Bl -tag -width Er | |||||||||
.It Bq Er EINVAL | |||||||||
The | |||||||||
.Fa ithread | |||||||||
argument is | |||||||||
.Dv NULL . | |||||||||
.It Bq Er EINVAL | |||||||||
The interrupt thread pointed to by | |||||||||
.Fa ithread | |||||||||
has no interrupt handlers. | |||||||||
.El | |||||||||
.Sh SEE ALSO | .Sh SEE ALSO | ||||||||
.Xr kthread 9 , | .Xr kthread 9 , | ||||||||
.Xr malloc 9 , | .Xr malloc 9 , | ||||||||
.Xr swi 9 , | .Xr swi 9 , | ||||||||
.Xr uma 9 | .Xr uma 9 | ||||||||
.Sh HISTORY | .Sh HISTORY | ||||||||
Interrupt threads and their corresponding API first appeared in | Interrupt threads and their corresponding API first appeared in | ||||||||
.Fx 5.0 . | .Fx 5.0 . | ||||||||
.Sh BUGS | |||||||||
Currently | |||||||||
.Vt struct ithd | |||||||||
represents both an interrupt source and an interrupt thread. | |||||||||
There should be a separate | |||||||||
.Vt struct isrc | |||||||||
that contains a vector number, enable and disable functions, etc.\& that | |||||||||
an ithread holds a reference to. |
Reminder (if needed) to bump on commit.