1*3a85e55fSvisa.\" $OpenBSD: task_add.9,v 1.23 2022/06/22 14:10:49 visa Exp $ 28543007fSdlg.\" 38543007fSdlg.\" Copyright (c) 2013 David Gwynne <dlg@openbsd.org> 48543007fSdlg.\" 58543007fSdlg.\" Permission to use, copy, modify, and distribute this software for any 68543007fSdlg.\" purpose with or without fee is hereby granted, provided that the above 78543007fSdlg.\" copyright notice and this permission notice appear in all copies. 88543007fSdlg.\" 98543007fSdlg.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 108543007fSdlg.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 118543007fSdlg.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 128543007fSdlg.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 138543007fSdlg.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 148543007fSdlg.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 158543007fSdlg.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 168543007fSdlg.\" 17*3a85e55fSvisa.Dd $Mdocdate: June 22 2022 $ 188543007fSdlg.Dt TASK_ADD 9 198543007fSdlg.Os 208543007fSdlg.Sh NAME 218543007fSdlg.Nm taskq_create , 228543007fSdlg.Nm taskq_destroy , 236f1a6781Sdlg.Nm taskq_barrier , 2460aa962eSdlg.Nm taskq_del_barrier , 258543007fSdlg.Nm task_set , 268543007fSdlg.Nm task_add , 272d8576dcSdlg.Nm task_del , 2828f4af8aSdlg.Nm task_pending , 292d8576dcSdlg.Nm TASK_INITIALIZER 308543007fSdlg.Nd task queues 318543007fSdlg.Sh SYNOPSIS 328543007fSdlg.In sys/task.h 338543007fSdlg.Ft struct taskq * 345dfee228Sschwarze.Fo taskq_create 35d8021586Sdlg.Fa "const char *name" 36d8021586Sdlg.Fa "unsigned int nthreads" 37d8021586Sdlg.Fa "int ipl" 38d8021586Sdlg.Fa "unsigned int flags" 39d8021586Sdlg.Fc 408543007fSdlg.Ft void 415dfee228Sschwarze.Fn taskq_destroy "struct taskq *tq" 428543007fSdlg.Ft void 436f1a6781Sdlg.Fn taskq_barrier "struct taskq *tq" 446f1a6781Sdlg.Ft void 4560aa962eSdlg.Fn taskq_del_barrier "struct taskq *tq" "struct task *t" 4660aa962eSdlg.Ft void 475dfee228Sschwarze.Fn task_set "struct task *t" "void (*fn)(void *)" "void *arg" 488543007fSdlg.Ft int 495dfee228Sschwarze.Fn task_add "struct taskq *tq" "struct task *t" 508543007fSdlg.Ft int 515dfee228Sschwarze.Fn task_del "struct taskq *tq" "struct task *t" 5228f4af8aSdlg.Ft int 5328f4af8aSdlg.Fn task_pending "struct task *t" 5426b9056eSdlg.Vt extern struct taskq *const systq; 5553eebcffSblambert.Vt extern struct taskq *const systqmp; 565dfee228Sschwarze.Fn TASK_INITIALIZER "void (*fn)(void *)" "void *arg" 578543007fSdlg.Sh DESCRIPTION 588543007fSdlgThe 598543007fSdlgtaskq 608543007fSdlgAPI provides a mechanism to defer work to a process context. 618543007fSdlg.Pp 628543007fSdlg.Fn taskq_create 638543007fSdlgallocates a taskq and a set of threads to be used to complete work 648543007fSdlgthat would be inappropriate for the shared system taskq. 658543007fSdlgThe 66369bef3aSschwarze.Fa name 678543007fSdlgargument specifies the name of the kernel threads that are created 688543007fSdlgto service the work on the taskq. 69369bef3aSschwarze.Fa nthreads 708543007fSdlgspecifies the number of threads that will be created to handle the work. 71369bef3aSschwarze.Fa ipl 728543007fSdlgspecifies the highest interrupt protection level at which 738543007fSdlg.Fn task_add 748543007fSdlgand 758543007fSdlg.Fn task_del 768543007fSdlgwill be called against the created taskq. 778543007fSdlgSee 788543007fSdlg.Xr spl 9 798543007fSdlgfor a list of the IPLs. 80df25eaf8SjmcThe operational characteristics of the taskq 81df25eaf8Sjmccan be altered by OR'ing the following defines into the 82d8021586Sdlg.Fa flags 83df25eaf8Sjmcargument: 84d8021586Sdlg.Bl -tag -width xxx -offset indent 85d8021586Sdlg.It Dv TASKQ_MPSAFE 86d8021586SdlgThe threads servicing the taskq will be run without the kernel big lock. 87368f6097Sjmc.El 888543007fSdlg.Pp 898543007fSdlg.Fn taskq_destroy 908543007fSdlgcauses the resources associated with a previously created taskq to be freed. 918543007fSdlgIt will wait till all the tasks in the work queue are completed before 928543007fSdlgreturning. 938543007fSdlgCalling 948543007fSdlg.Fn taskq_destroy 958543007fSdlgagainst the system taskq is an error and will lead to undefined 968543007fSdlgbehaviour or a system fault. 978543007fSdlg.Pp 986f1a6781Sdlg.Fn taskq_barrier 996f1a6781Sdlgguarantees that any task that was running on the 1006f1a6781Sdlg.Fa tq 1016f1a6781Sdlgtaskq when the barrier was called has finished by the time the barrier 1026f1a6781Sdlgreturns. 1036f1a6781Sdlg.Pp 10460aa962eSdlg.Fn taskq_del_barrier 10560aa962eSdlgeither removes 10660aa962eSdlg.Fa t 10760aa962eSdlgfrom the list of pending tasks on the 10860aa962eSdlg.Fa tq 10960aa962eSdlgtaskq, or waits until any running task has completed. 11060aa962eSdlg.Pp 111*3a85e55fSvisaThe caller of 112*3a85e55fSvisa.Fn taskq_barrier 113*3a85e55fSvisaor 114*3a85e55fSvisa.Fn taskq_del_barrier 115*3a85e55fSvisamust not hold locks that can block the taskq. 116*3a85e55fSvisaOtherwise, the system will deadlock. 117*3a85e55fSvisa.Pp 1188543007fSdlgIt is the responsibility of the caller to provide the 1198543007fSdlg.Fn task_set , 1208543007fSdlg.Fn task_add , 1218543007fSdlgand 1228543007fSdlg.Fn task_del 1238543007fSdlgfunctions with pre-allocated task structures. 1248543007fSdlg.Pp 1258543007fSdlg.Fn task_set 1268543007fSdlgprepares the task structure 1278543007fSdlg.Fa t 1288543007fSdlgto be used in future calls to 1298543007fSdlg.Fn task_add 1308543007fSdlgand 1318543007fSdlg.Fn task_del . 1328543007fSdlg.Fa t 1338543007fSdlgwill be prepared to call the function 1348543007fSdlg.Fa fn 135e4195480Sdlgwith the argument specified by 136e4195480Sdlg.Fa arg . 1378543007fSdlgOnce initialised, the 1388543007fSdlg.Fa t 1398543007fSdlgstructure can be used repeatedly in calls to 1408543007fSdlg.Fn task_add 1418543007fSdlgand 1428543007fSdlg.Fn task_del 1438543007fSdlgand does not need to be reinitialised unless the function called 1448543007fSdlgand/or its argument must change. 1458543007fSdlg.Pp 1468543007fSdlg.Fn task_add 1478543007fSdlgschedules the execution of the work specified by the 1488543007fSdlgtask structure 1498543007fSdlg.Fa t 1508543007fSdlgon the 1518543007fSdlg.Fa tq 1528543007fSdlgtaskq. 1538543007fSdlgThe task structure must already be initialised by 1548543007fSdlg.Fn task_set . 1558543007fSdlg.Pp 1568543007fSdlg.Fn task_del 1578543007fSdlgwill remove the task structure 1588543007fSdlg.Fa t 1598543007fSdlgfrom the taskq 1604ce22707Sjmc.Fa tq . 1618543007fSdlgIf the work was already executed or has not been added to the taskq, 1628543007fSdlgthe call will have no effect. 1638543007fSdlgCalling 1648543007fSdlg.Fn task_del 1654ce22707Sjmcagainst a different taskq than the one given in a previous call to 1668543007fSdlg.Fn task_add 1678543007fSdlgis an error and will lead to undefined behaviour. 1688543007fSdlg.Pp 16953eebcffSblambertThe kernel provides two system taskqs: 17053eebcffSblambert.Va systq , 17153eebcffSblambertwhich executes while holding the kernel lock, and 17253eebcffSblambert.Va systqmp , 17353eebcffSblambertwhich does not hold the kernel lock during execution. 17453eebcffSblambertThey can both be used by any subsystem for short lived tasks. 17553eebcffSblambertThey are serviced by a single thread and can therefore provide predictable 17626b9056eSdlgordering of work. 17753eebcffSblambertWork can be scheduled on the system taskqs from callers at or below IPL_HIGH. 17826b9056eSdlg.Pp 17928f4af8aSdlgThe 18028f4af8aSdlg.Fn task_pending 18128f4af8aSdlgmacro can be used to check if a task is scheduled to run. 18228f4af8aSdlg.Pp 1832d8576dcSdlgA task declaration can be initialised with the 1842d8576dcSdlg.Fn TASK_INITIALIZER 1852d8576dcSdlgmacro. 1862d8576dcSdlgThe task will be prepared to call the function specified by the 1872d8576dcSdlg.Fa fn 1882d8576dcSdlgargument with the 1892d8576dcSdlg.Fa void * 190e4195480Sdlgargument given in 191e4195480Sdlg.Fa arg . 192ff4b1dfbSdlg.Sh CONTEXT 1938543007fSdlg.Fn taskq_create 1948543007fSdlgand 1958543007fSdlg.Fn taskq_destroy 1968543007fSdlgcan be called during autoconf, or from process context. 1976f1a6781Sdlg.Fn taskq_barrier 19860aa962eSdlgand 19960aa962eSdlg.Fn taskq_del_barrier 2006f1a6781Sdlgcan be called from process context. 2018543007fSdlg.Fn task_set , 2028543007fSdlg.Fn task_add , 20328f4af8aSdlg.Fn task_del , 2048543007fSdlgand 20528f4af8aSdlg.Fn task_pending 2068543007fSdlgcan be called during autoconf, from process context, or from interrupt context. 2074f33e759Sdlg.Sh RETURN VALUES 2084f33e759Sdlg.Fn taskq_create 2094f33e759Sdlgreturns a pointer to a taskq structure on success or 2104f33e759Sdlg.Dv NULL 2114f33e759Sdlgon failure. 2124f33e759Sdlg.Pp 2134f33e759Sdlg.Fn task_add 2144f33e759Sdlgwill return 1 if the task 2154f33e759Sdlg.Fa t 2164f33e759Sdlgwas added to the taskq 2174f33e759Sdlg.Fa tq 2184f33e759Sdlgor 0 if the task was already queued. 2194f33e759Sdlg.Pp 2204f33e759Sdlg.Fn task_del 2214f33e759Sdlgwill return 1 if the task 2224f33e759Sdlg.Fa t 2234f33e759Sdlgwas removed from the taskq 2244f33e759Sdlg.Fa tq 2254f33e759Sdlgor 0 if the task was not already on the queue. 22628f4af8aSdlg.Pp 22728f4af8aSdlg.Fn task_pending 22828f4af8aSdlgwill return non-zero if the task is queued to run, or 0 if the task 22928f4af8aSdlgis not queued. 230246b391cSmpi.Sh SEE ALSO 2318543007fSdlg.Xr autoconf 9 , 2328543007fSdlg.Xr spl 9 2338543007fSdlg.Sh HISTORY 2348543007fSdlgThe task API was originally written by 2358543007fSdlg.An David Gwynne Aq Mt dlg@openbsd.org . 2368543007fSdlgThe task API first appeared in 2378543007fSdlg.Ox 5.5 . 238