1.\" Copyright (c) 2001 John H. Baldwin <[email protected]> 2.\" 3.\" Redistribution and use in source and binary forms, with or without 4.\" modification, are permitted provided that the following conditions 5.\" are met: 6.\" 1. Redistributions of source code must retain the above copyright 7.\" notice, this list of conditions and the following disclaimer. 8.\" 2. Redistributions in binary form must reproduce the above copyright 9.\" notice, this list of conditions and the following disclaimer in the 10.\" documentation and/or other materials provided with the distribution. 11.\" 12.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 13.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 14.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 15.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 16.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 17.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 18.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 19.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 20.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 21.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 22.\" SUCH DAMAGE. 23.\" 24.\" $FreeBSD$ 25.\" 26.Dd August 25, 2006 27.Dt ITHREAD 9 28.Os 29.Sh NAME 30.Nm ithread_add_handler , 31.Nm ithread_create , 32.Nm ithread_destroy , 33.Nm ithread_priority , 34.Nm ithread_remove_handler , 35.Nm ithread_schedule 36.Nd kernel interrupt threads 37.Sh SYNOPSIS 38.In sys/param.h 39.In sys/bus.h 40.In sys/interrupt.h 41.Ft int 42.Fo ithread_add_handler 43.Fa "struct ithd *ithread" 44.Fa "const char *name" 45.Fa "driver_intr_t handler" 46.Fa "void *arg" 47.Fa "u_char pri" 48.Fa "enum intr_type flags" 49.Fa "void **cookiep" 50.Fc 51.Ft int 52.Fo ithread_create 53.Fa "struct ithd **ithread" 54.Fa "int vector" 55.Fa "int flags" 56.Fa "void (*disable)(int)" 57.Fa "void (*enable)(int)" 58.Fa "const char *fmt" 59.Fa "..." 60.Fc 61.Ft int 62.Fn ithread_destroy "struct ithd *ithread" 63.Ft u_char 64.Fn ithread_priority "enum intr_type flags" 65.Ft int 66.Fn ithread_remove_handler "void *cookie" 67.Ft int 68.Fn ithread_schedule "struct ithd *ithread" "int do_switch" 69.Sh DESCRIPTION 70Interrupt threads are kernel threads that run a list of handlers when 71triggered by either a hardware or software interrupt. 72Each interrupt handler has a name, handler function, handler argument, 73priority, and various flags. 74Each interrupt thread maintains a list of handlers sorted by priority. 75This results in higher priority handlers being executed prior to lower 76priority handlers. 77Each thread assumes the priority of its highest priority handler for its 78process priority, or 79.Dv PRIO_MAX 80if it has no handlers. 81Interrupt threads are also associated with a single interrupt source, 82represented as a vector number. 83.Pp 84The 85.Fn ithread_create 86function creates a new interrupt thread. 87The 88.Fa ithread 89argument points to an 90.Vt struct ithd 91pointer that will point to the newly created thread upon success. 92The 93.Fa vector 94argument specifies the interrupt source to associate this thread with. 95The 96.Fa flags 97argument is a mask of properties of this thread. 98The only valid flag currently for 99.Fn ithread_create 100is 101.Dv IT_SOFT 102to specify that this interrupt thread is a software interrupt. 103The 104.Fa enable 105and 106.Fa disable 107arguments specify optional functions used to enable and disable this 108interrupt thread's interrupt source. 109The functions receive the vector corresponding to the thread's interrupt 110source as their only argument. 111The remaining arguments form a 112.Xr printf 9 113argument list that is used to build the base name of the new ithread. 114The full name of an interrupt thread is formed by concatenating the base 115name of an interrupt thread with the names of all of its interrupt handlers. 116.Pp 117The 118.Fn ithread_destroy 119function destroys a previously created interrupt thread by releasing its 120resources and arranging for the backing kernel thread to terminate. 121An interrupt thread can only be destroyed if it has no handlers remaining. 122.Pp 123The 124.Fn ithread_add_handler 125function adds a new handler to an existing interrupt thread specified by 126.Fa ithread . 127The 128.Fa name 129argument specifies a name for this handler. 130The 131.Fa handler 132and 133.Fa arg 134arguments provide the function to execute for this handler and an argument 135to pass to it. 136The 137.Fa pri 138argument specifies the priority of this handler and is used both in sorting 139it in relation to the other handlers for this thread and to specify the 140priority of the backing kernel thread. 141The 142.Fa flags 143argument can be used to specify properties of this handler as defined in 144.In sys/bus.h . 145If 146.Fa cookiep 147is not 148.Dv NULL , 149then it will be assigned a cookie that can be used later to remove this 150handler. 151.Pp 152The 153.Fn ithread_remove_handler 154removes a handler from an interrupt thread. 155The 156.Fa cookie 157argument specifies the handler to remove from its thread. 158.Pp 159The 160.Fn ithread_schedule 161function schedules an interrupt thread to run. 162If the 163.Fa do_switch 164argument is non-zero and the interrupt thread is idle, then a context switch 165will be forced after putting the interrupt thread on the run queue. 166.Pp 167The 168.Fn ithread_priority 169function translates the 170.Dv INTR_TYPE_* 171interrupt flags into interrupt handler priorities. 172.Pp 173The interrupt flags not related to the type of a particular interrupt 174.Pq Dv INTR_TYPE_* 175can be used to specify additional properties of both hardware and software 176interrupt handlers. 177The 178.Dv INTR_EXCL 179flag specifies that this handler cannot share an interrupt thread with 180another handler. 181The 182.Dv INTR_MPSAFE 183flag specifies that this handler is MP safe in that it does not need the 184Giant mutex to be held while it is executed. 185The 186.Dv INTR_ENTROPY 187flag specifies that the interrupt source this handler is tied to is a good 188source of entropy, and thus that entropy should be gathered when an interrupt 189from the handler's source triggers. 190Presently, the 191.Dv INTR_ENTROPY 192flag is not valid for software interrupt handlers. 193.Pp 194It is not permitted to sleep in an interrupt thread; hence, any memory 195or zone allocations in an interrupt thread should be specified with the 196.Dv M_NOWAIT 197flag set. 198Any allocation errors must be handled thereafter. 199.Sh RETURN VALUES 200The 201.Fn ithread_add_handler , 202.Fn ithread_create , 203.Fn ithread_destroy , 204.Fn ithread_remove_handler , 205and 206.Fn ithread_schedule 207functions return zero on success and non-zero on failure. 208The 209.Fn ithread_priority 210function returns a process priority corresponding to the passed in interrupt 211flags. 212.Sh EXAMPLES 213The 214.Fn swi_add 215function demonstrates the use of 216.Fn ithread_create 217and 218.Fn ithread_add_handler . 219.Bd -literal -offset indent 220int 221swi_add(struct ithd **ithdp, const char *name, driver_intr_t handler, 222 void *arg, int pri, enum intr_type flags, void **cookiep) 223{ 224 struct proc *p; 225 struct ithd *ithd; 226 int error; 227 228 if (flags & INTR_ENTROPY) 229 return (EINVAL); 230 231 ithd = (ithdp != NULL) ? *ithdp : NULL; 232 233 if (ithd != NULL) { 234 if ((ithd->it_flags & IT_SOFT) == 0) 235 return(EINVAL); 236 } else { 237 error = ithread_create(&ithd, pri, IT_SOFT, NULL, NULL, 238 "swi%d:", pri); 239 if (error) 240 return (error); 241 242 if (ithdp != NULL) 243 *ithdp = ithd; 244 } 245 return (ithread_add_handler(ithd, name, handler, arg, pri + PI_SOFT, 246 flags, cookiep)); 247} 248.Ed 249.Sh ERRORS 250The 251.Fn ithread_add_handler 252function will fail if: 253.Bl -tag -width Er 254.It Bq Er EINVAL 255Any of the 256.Fa ithread , 257.Fa handler , 258or 259.Fa name 260arguments are 261.Dv NULL . 262.It Bq Er EINVAL 263The 264.Dv INTR_EXCL 265flag is specified and the interrupt thread 266.Fa ithread 267already has at least one handler, or the interrupt thread 268.Fa ithread 269already has an exclusive handler. 270.It Bq Er ENOMEM 271Could not allocate needed memory for this handler. 272.El 273.Pp 274The 275.Fn ithread_create 276function will fail if: 277.Bl -tag -width Er 278.It Bq Er EAGAIN 279The system-imposed limit on the total 280number of processes under execution would be exceeded. 281The limit is given by the 282.Xr sysctl 3 283MIB variable 284.Dv KERN_MAXPROC . 285.It Bq Er EINVAL 286A flag other than 287.Dv IT_SOFT 288was specified in the 289.Fa flags 290parameter. 291.It Bq Er ENOMEM 292Could not allocate needed memory for this interrupt thread. 293.El 294.Pp 295The 296.Fn ithread_destroy 297function will fail if: 298.Bl -tag -width Er 299.It Bq Er EINVAL 300The 301.Fa ithread 302argument is 303.Dv NULL . 304.It Bq Er EINVAL 305The interrupt thread pointed to by 306.Fa ithread 307has at least one handler. 308.El 309.Pp 310The 311.Fn ithread_remove_handler 312function will fail if: 313.Bl -tag -width Er 314.It Bq Er EINVAL 315The 316.Fa cookie 317argument is 318.Dv NULL . 319.El 320.Pp 321The 322.Fn ithread_schedule 323function will fail if: 324.Bl -tag -width Er 325.It Bq Er EINVAL 326The 327.Fa ithread 328argument is 329.Dv NULL . 330.It Bq Er EINVAL 331The interrupt thread pointed to by 332.Fa ithread 333has no interrupt handlers. 334.El 335.Sh SEE ALSO 336.Xr kthread 9 , 337.Xr malloc 9 , 338.Xr swi 9 , 339.Xr uma 9 340.Sh HISTORY 341Interrupt threads and their corresponding API first appeared in 342.Fx 5.0 . 343.Sh BUGS 344Currently 345.Vt struct ithd 346represents both an interrupt source and an interrupt thread. 347There should be a separate 348.Vt struct isrc 349that contains a vector number, enable and disable functions, etc.\& that 350an ithread holds a reference to. 351