diff --git a/share/man/man9/intr_event.9 b/share/man/man9/intr_event.9 index b735da931f64..621a02e3967b 100644 --- a/share/man/man9/intr_event.9 +++ b/share/man/man9/intr_event.9 @@ -1,312 +1,313 @@ .\" Copyright (c) 2001 John H. Baldwin .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" 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 .\" SUCH DAMAGE. .\" .\" $FreeBSD$ .\" .Dd October 15, 2022 .Dt INTR_EVENT 9 .Os .Sh NAME .Nm intr_event_add_handler , .Nm intr_event_create , .Nm intr_event_destroy , .Nm intr_event_remove_handler , .Nm intr_priority .Nd "kernel interrupt handler and thread API" .Sh SYNOPSIS .In sys/param.h .In sys/bus.h .In sys/interrupt.h .Ft int .Fo intr_event_add_handler .Fa "struct intr_event *ie" .Fa "const char *name" .Fa "driver_filter_t filter" .Fa "driver_intr_t handler" .Fa "void *arg" .Fa "u_char pri" .Fa "enum intr_type flags" .Fa "void **cookiep" .Fc .Ft int .Fo intr_event_create .Fa "struct intr_event **event" .Fa "void *source" .Fa "int flags" .Fa "int irq" .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 "..." .Fc .Ft int .Fn intr_event_destroy "struct intr_event *ie" .Ft int .Fn intr_event_remove_handler "void *cookie" .Ft u_char .Fn intr_priority "enum intr_type flags" .Sh DESCRIPTION Interrupt threads are kernel threads that run a list of handlers when triggered by either a hardware or software interrupt. Each interrupt handler has a name, handler function, handler argument, priority, and various flags. Each interrupt thread maintains a list of handlers sorted by priority. This results in higher priority handlers being executed prior to lower priority handlers. Each thread assumes the priority of its highest priority handler for its process priority, or .Dv PRIO_MAX if it has no handlers. Interrupt threads are also associated with a single interrupt source, represented as a vector number. .Pp The .Fn intr_event_create function creates a new interrupt thread. The .Fa source argument points to a .Vt struct intr_event event pointer that will point to the newly created thread upon success. The .Fa flags argument is a mask of properties of this thread. The only valid flag currently for .Fn intr_event_create is .Dv IE_SOFT to specify that this interrupt thread is a software interrupt. The .Fa enable and .Fa disable arguments specify optional functions used to enable and disable this 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 .Xr printf 9 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 name of the interrupt thread with the names of all of its interrupt handlers. .Pp The .Fn intr_event_destroy function destroys a previously created interrupt thread by releasing its resources and arranging for the backing kernel thread to terminate. An interrupt thread can only be destroyed if it has no handlers remaining. .Pp The .Fn intr_event_add_handler function adds a new handler to an existing interrupt thread specified by .Fa ithread . The .Fa name argument specifies a name for this handler. The .Fa handler and .Fa arg arguments provide the function to execute for this handler and an argument to pass to it. The .Fa pri argument specifies the priority of this handler and is used both in sorting it in relation to the other handlers for this thread and to specify the priority of the backing kernel thread. The .Fa flags argument can be used to specify properties of this handler as defined in .In sys/bus.h . If .Fa cookiep is not .Dv NULL , then it will be assigned a cookie that can be used later to remove this handler. .Pp The .Fn intr_event_remove_handler removes a handler from an interrupt thread. The .Fa cookie argument specifies the handler to remove from its thread. .Pp The .Fn intr_priority function translates the .Dv INTR_TYPE_* interrupt flags into interrupt thread scheduling 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 intr_event_add_handler , .Fn intr_event_create , .Fn intr_event_destroy , and .Fn intr_event_remove_handler functions return zero on success and non-zero on failure. The .Fn intr_priority function returns a process priority corresponding to the passed in interrupt flags. .Sh EXAMPLES The -.Fn swi_add +.Xr swi_add 9 function demonstrates the use of .Fn intr_event_create and .Fn intr_event_add_handler . .Bd -literal -offset indent int -swi_add(struct ithd **ithdp, const char *name, driver_intr_t handler, - void *arg, int pri, enum intr_type flags, void **cookiep) +swi_add(struct intr_event **eventp, const char *name, driver_intr_t handler, + void *arg, int pri, enum intr_type flags, void **cookiep) { - struct proc *p; - struct ithd *ithd; - int error; + struct intr_event *ie; + int error = 0; if (flags & INTR_ENTROPY) return (EINVAL); - ithd = (ithdp != NULL) ? *ithdp : NULL; + ie = (eventp != NULL) ? *eventp : NULL; - if (ithd != NULL) { - if ((ithd->it_flags & IT_SOFT) == 0) - return(EINVAL); + if (ie != NULL) { + if (!(ie->ie_flags & IE_SOFT)) + return (EINVAL); } else { - error = ithread_create(&ithd, pri, IT_SOFT, NULL, NULL, - "swi%d:", pri); + error = intr_event_create(&ie, NULL, IE_SOFT, 0, + NULL, NULL, NULL, swi_assign_cpu, "swi%d:", pri); if (error) return (error); - - if (ithdp != NULL) - *ithdp = ithd; + if (eventp != NULL) + *eventp = ie; + } + if (handler != NULL) { + error = intr_event_add_handler(ie, name, NULL, handler, arg, + PI_SWI(pri), flags, cookiep); } - return (ithread_add_handler(ithd, name, handler, arg, pri + PI_SOFT, - flags, cookiep)); + return (error); } .Ed .Sh ERRORS The .Fn intr_event_add_handler function will fail if: .Bl -tag -width Er .It Bq Er EINVAL The .Fa ie or .Fa name arguments are .Dv NULL . .It Bq Er EINVAL The .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 .Fa ie already has at least one handler, or the interrupt thread .Fa ie already has an exclusive handler. .El .Pp The .Fn intr_event_create function will fail if: .Bl -tag -width Er .It Bq Er EINVAL A flag other than .Dv IE_SOFT was specified in the .Fa flags parameter. .El .Pp The .Fn intr_event_destroy function will fail if: .Bl -tag -width Er .It Bq Er EINVAL The .Fa ie argument is .Dv NULL . .It Bq Er EBUSY The interrupt event pointed to by .Fa ie has at least one handler which has not been removed with .Fn intr_event_remove_handler . .El .Pp The .Fn intr_event_remove_handler function will fail if: .Bl -tag -width Er .It Bq Er EINVAL The .Fa cookie argument is .Dv NULL . .El .Sh SEE ALSO .Xr kthread 9 , .Xr malloc 9 , .Xr swi 9 , .Xr uma 9 .Sh HISTORY Interrupt threads and their corresponding API first appeared in .Fx 5.0 .