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