xref: /freebsd/share/man/man9/taskqueue.9 (revision fa9896e082a1046ff4fbc75fcba4d18d1f2efc19)
182323455SDoug Rabson.\" -*- nroff -*-
282323455SDoug Rabson.\"
382323455SDoug Rabson.\" Copyright (c) 2000 Doug Rabson
482323455SDoug Rabson.\"
582323455SDoug Rabson.\" All rights reserved.
682323455SDoug Rabson.\"
782323455SDoug Rabson.\" This program is free software.
882323455SDoug Rabson.\"
982323455SDoug Rabson.\" Redistribution and use in source and binary forms, with or without
1082323455SDoug Rabson.\" modification, are permitted provided that the following conditions
1182323455SDoug Rabson.\" are met:
1282323455SDoug Rabson.\" 1. Redistributions of source code must retain the above copyright
1382323455SDoug Rabson.\"    notice, this list of conditions and the following disclaimer.
1482323455SDoug Rabson.\" 2. Redistributions in binary form must reproduce the above copyright
1582323455SDoug Rabson.\"    notice, this list of conditions and the following disclaimer in the
1682323455SDoug Rabson.\"    documentation and/or other materials provided with the distribution.
1782323455SDoug Rabson.\"
1882323455SDoug Rabson.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
1982323455SDoug Rabson.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2082323455SDoug Rabson.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2182323455SDoug Rabson.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
2282323455SDoug Rabson.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2382323455SDoug Rabson.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2482323455SDoug Rabson.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2582323455SDoug Rabson.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2682323455SDoug Rabson.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2782323455SDoug Rabson.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2882323455SDoug Rabson.\"
29*b6f87b78SVladimir Kondratyev.Dd April 25, 2022
3082323455SDoug Rabson.Dt TASKQUEUE 9
3182323455SDoug Rabson.Os
3282323455SDoug Rabson.Sh NAME
3382323455SDoug Rabson.Nm taskqueue
3482323455SDoug Rabson.Nd asynchronous task execution
3582323455SDoug Rabson.Sh SYNOPSIS
3632eef9aeSRuslan Ermilov.In sys/param.h
37f16b3c0dSChad David.In sys/kernel.h
38f16b3c0dSChad David.In sys/malloc.h
3932eef9aeSRuslan Ermilov.In sys/queue.h
4032eef9aeSRuslan Ermilov.In sys/taskqueue.h
4182323455SDoug Rabson.Bd -literal
42f674e945SBruce M Simpsontypedef void (*task_fn_t)(void *context, int pending);
4382323455SDoug Rabson
4482323455SDoug Rabsontypedef void (*taskqueue_enqueue_fn)(void *context);
4582323455SDoug Rabson
4682323455SDoug Rabsonstruct task {
4782323455SDoug Rabson	STAILQ_ENTRY(task)	ta_link;	/* link for queue */
48cf82599dSSam Leffler	u_short			ta_pending;	/* count times queued */
49cf82599dSSam Leffler	u_short			ta_priority;	/* priority of task in queue */
50f674e945SBruce M Simpson	task_fn_t		ta_func;	/* task handler */
5182323455SDoug Rabson	void			*ta_context;	/* argument for handler */
5282323455SDoug Rabson};
53c3bd10b4SKonstantin Belousov
54fdbc7174SWill Andrewsenum taskqueue_callback_type {
55fdbc7174SWill Andrews	TASKQUEUE_CALLBACK_TYPE_INIT,
56fdbc7174SWill Andrews	TASKQUEUE_CALLBACK_TYPE_SHUTDOWN,
57fdbc7174SWill Andrews};
58fdbc7174SWill Andrews
59fdbc7174SWill Andrewstypedef void (*taskqueue_callback_fn)(void *context);
60fdbc7174SWill Andrews
61c3bd10b4SKonstantin Belousovstruct timeout_task;
6282323455SDoug Rabson.Ed
6382323455SDoug Rabson.Ft struct taskqueue *
648f668ffaSOleksandr Tymoshenko.Fn taskqueue_create "const char *name" "int mflags" "taskqueue_enqueue_fn enqueue" "void *context"
652eb30874SOleksandr Tymoshenko.Ft struct taskqueue *
662eb30874SOleksandr Tymoshenko.Fn taskqueue_create_fast "const char *name" "int mflags" "taskqueue_enqueue_fn enqueue" "void *context"
67fdbc7174SWill Andrews.Ft int
68fdbc7174SWill Andrews.Fn taskqueue_start_threads "struct taskqueue **tqp" "int count" "int pri" "const char *name" "..."
69ec5d37f4SBenjamin Kaduk.Ft int
70337f6465SAndriy Gapon.Fo taskqueue_start_threads_cpuset
71337f6465SAndriy Gapon.Fa "struct taskqueue **tqp" "int count" "int pri" "cpuset_t *mask"
72337f6465SAndriy Gapon.Fa "const char *name" "..."
73337f6465SAndriy Gapon.Fc
74337f6465SAndriy Gapon.Ft int
75337f6465SAndriy Gapon.Fo taskqueue_start_threads_in_proc
76337f6465SAndriy Gapon.Fa "struct taskqueue **tqp" "int count" "int pri" "struct proc *proc"
77ec5d37f4SBenjamin Kaduk.Fa "const char *name" "..."
78ec5d37f4SBenjamin Kaduk.Fc
79fdbc7174SWill Andrews.Ft void
80fdbc7174SWill Andrews.Fn taskqueue_set_callback "struct taskqueue *queue" "enum taskqueue_callback_type cb_type" "taskqueue_callback_fn callback" "void *context"
8182323455SDoug Rabson.Ft void
8282323455SDoug Rabson.Fn taskqueue_free "struct taskqueue *queue"
8382323455SDoug Rabson.Ft int
8482323455SDoug Rabson.Fn taskqueue_enqueue "struct taskqueue *queue" "struct task *task"
8524b4e9d1SScott Long.Ft int
86*b6f87b78SVladimir Kondratyev.Fn taskqueue_enqueue_flags "struct taskqueue *queue" "struct task *task" "int flags"
87*b6f87b78SVladimir Kondratyev.Ft int
88c3bd10b4SKonstantin Belousov.Fn taskqueue_enqueue_timeout "struct taskqueue *queue" "struct timeout_task *timeout_task" "int ticks"
89c3bd10b4SKonstantin Belousov.Ft int
90f37b7fc2SIan Lepore.Fn taskqueue_enqueue_timeout_sbt "struct taskqueue *queue" "struct timeout_task *timeout_task" "sbintime_t sbt" "sbintime_t pr" "int flags"
91f37b7fc2SIan Lepore.Ft int
92f46276a9SMatthew D Fleming.Fn taskqueue_cancel "struct taskqueue *queue" "struct task *task" "u_int *pendp"
93c3bd10b4SKonstantin Belousov.Ft int
94c3bd10b4SKonstantin Belousov.Fn taskqueue_cancel_timeout "struct taskqueue *queue" "struct timeout_task *timeout_task" "u_int *pendp"
9582323455SDoug Rabson.Ft void
96fff7ff71SGleb Smirnoff.Fn taskqueue_drain "struct taskqueue *queue" "struct task *task"
97c3bd10b4SKonstantin Belousov.Ft void
98c3bd10b4SKonstantin Belousov.Fn taskqueue_drain_timeout "struct taskqueue *queue" "struct timeout_task *timeout_task"
99cb03508fSAndriy Gapon.Ft void
100cb03508fSAndriy Gapon.Fn taskqueue_drain_all "struct taskqueue *queue"
101cb03508fSAndriy Gapon.Ft void
102bb58b5d6SMark Johnston.Fn taskqueue_quiesce "struct taskqueue *queue"
103bb58b5d6SMark Johnston.Ft void
104cb03508fSAndriy Gapon.Fn taskqueue_block "struct taskqueue *queue"
105cb03508fSAndriy Gapon.Ft void
106cb03508fSAndriy Gapon.Fn taskqueue_unblock "struct taskqueue *queue"
107159ef108SPawel Jakub Dawidek.Ft int
108159ef108SPawel Jakub Dawidek.Fn taskqueue_member "struct taskqueue *queue" "struct thread *td"
109a92f0ee8SMatthew D Fleming.Ft void
110bf73d4d2SMatthew D Fleming.Fn taskqueue_run "struct taskqueue *queue"
111c3bd10b4SKonstantin Belousov.Fn TASK_INIT "struct task *task" "int priority" "task_fn_t func" "void *context"
112a7f5f794SJohn Baldwin.Fn TASK_INITIALIZER "int priority" "task_fn_t func" "void *context"
11382323455SDoug Rabson.Fn TASKQUEUE_DECLARE "name"
114f16b3c0dSChad David.Fn TASKQUEUE_DEFINE "name" "taskqueue_enqueue_fn enqueue" "void *context" "init"
1152eb30874SOleksandr Tymoshenko.Fn TASKQUEUE_FAST_DEFINE "name" "taskqueue_enqueue_fn enqueue" "void *context" "init"
116227559d1SJohn-Mark Gurney.Fn TASKQUEUE_DEFINE_THREAD "name"
1172eb30874SOleksandr Tymoshenko.Fn TASKQUEUE_FAST_DEFINE_THREAD "name"
118c3bd10b4SKonstantin Belousov.Fn TIMEOUT_TASK_INIT "struct taskqueue *queue" "struct timeout_task *timeout_task" "int priority" "task_fn_t func" "void *context"
11982323455SDoug Rabson.Sh DESCRIPTION
12082323455SDoug RabsonThese functions provide a simple interface for asynchronous execution
12182323455SDoug Rabsonof code.
12282323455SDoug Rabson.Pp
12382323455SDoug RabsonThe function
12482323455SDoug Rabson.Fn taskqueue_create
12582323455SDoug Rabsonis used to create new queues.
12682323455SDoug RabsonThe arguments to
12782323455SDoug Rabson.Fn taskqueue_create
128cf82599dSSam Lefflerinclude a name that should be unique,
12982323455SDoug Rabsona set of
13082323455SDoug Rabson.Xr malloc 9
131cf82599dSSam Lefflerflags that specify whether the call to
13282323455SDoug Rabson.Fn malloc
133cf82599dSSam Leffleris allowed to sleep,
134cf82599dSSam Lefflera function that is called from
13582323455SDoug Rabson.Fn taskqueue_enqueue
136cf82599dSSam Lefflerwhen a task is added to the queue,
137cf82599dSSam Lefflerand a pointer to the memory location where the identity of the
138cf82599dSSam Lefflerthread that services the queue is recorded.
13982323455SDoug Rabson.\" XXX	The rest of the sentence gets lots in relation to the first part.
140cf82599dSSam LefflerThe function called from
141cf82599dSSam Leffler.Fn taskqueue_enqueue
142cf82599dSSam Lefflermust arrange for the queue to be processed
14382323455SDoug Rabson(for instance by scheduling a software interrupt or waking a kernel
14482323455SDoug Rabsonthread).
145cf82599dSSam LefflerThe memory location where the thread identity is recorded is used
146cf82599dSSam Lefflerto signal the service thread(s) to terminate--when this value is set to
147cf82599dSSam Lefflerzero and the thread is signaled it will terminate.
1482eb30874SOleksandr TymoshenkoIf the queue is intended for use in fast interrupt handlers
1492eb30874SOleksandr Tymoshenko.Fn taskqueue_create_fast
1502eb30874SOleksandr Tymoshenkoshould be used in place of
1512eb30874SOleksandr Tymoshenko.Fn taskqueue_create .
15282323455SDoug Rabson.Pp
15382323455SDoug RabsonThe function
15482323455SDoug Rabson.Fn taskqueue_free
155e477e4feSPawel Jakub Dawidekshould be used to free the memory used by the queue.
156cf82599dSSam LefflerAny tasks that are on the queue will be executed at this time after
157cf82599dSSam Lefflerwhich the thread servicing the queue will be signaled that it should exit.
15882323455SDoug Rabson.Pp
159fdbc7174SWill AndrewsOnce a taskqueue has been created, its threads should be started using
160337f6465SAndriy Gapon.Fn taskqueue_start_threads ,
161337f6465SAndriy Gapon.Fn taskqueue_start_threads_cpuset
162ec5d37f4SBenjamin Kadukor
163337f6465SAndriy Gapon.Fn taskqueue_start_threads_in_proc .
164337f6465SAndriy Gapon.Fn taskqueue_start_threads_cpuset
165ec5d37f4SBenjamin Kaduktakes a
166337f6465SAndriy Gapon.Va cpuset
167ec5d37f4SBenjamin Kadukargument which will cause the threads which are started for the taskqueue
168337f6465SAndriy Gaponto be restricted to run on the given CPUs.
169337f6465SAndriy Gapon.Fn taskqueue_start_threads_in_proc
170337f6465SAndriy Gapontakes a
171337f6465SAndriy Gapon.Va proc
172337f6465SAndriy Gaponargument which will cause the threads which are started for the taskqueue
173337f6465SAndriy Gaponto be assigned to the given kernel process.
174fdbc7174SWill AndrewsCallbacks may optionally be registered using
175fdbc7174SWill Andrews.Fn taskqueue_set_callback .
176fdbc7174SWill AndrewsCurrently, callbacks may be registered for the following purposes:
177fdbc7174SWill Andrews.Bl -tag -width TASKQUEUE_CALLBACK_TYPE_SHUTDOWN
178fdbc7174SWill Andrews.It Dv TASKQUEUE_CALLBACK_TYPE_INIT
179fdbc7174SWill AndrewsThis callback is called by every thread in the taskqueue, before it executes
180fdbc7174SWill Andrewsany tasks.
181fdbc7174SWill AndrewsThis callback must be set before the taskqueue's threads are started.
182fdbc7174SWill Andrews.It Dv TASKQUEUE_CALLBACK_TYPE_SHUTDOWN
183fdbc7174SWill AndrewsThis callback is called by every thread in the taskqueue, after it executes
184fdbc7174SWill Andrewsits last task.
185fdbc7174SWill AndrewsThis callback will always be called before the taskqueue structure is
186fdbc7174SWill Andrewsreclaimed.
187fdbc7174SWill Andrews.El
188fdbc7174SWill Andrews.Pp
18982323455SDoug RabsonTo add a task to the list of tasks queued on a taskqueue, call
19082323455SDoug Rabson.Fn taskqueue_enqueue
19182323455SDoug Rabsonwith pointers to the queue and task.
19282323455SDoug RabsonIf the task's
19382323455SDoug Rabson.Va ta_pending
19482323455SDoug Rabsonfield is non-zero,
19582323455SDoug Rabsonthen it is simply incremented to reflect the number of times the task
196d2849f27SAdrian Chaddwas enqueued, up to a cap of USHRT_MAX.
19782323455SDoug RabsonOtherwise,
19882323455SDoug Rabsonthe task is added to the list before the first task which has a lower
19982323455SDoug Rabson.Va ta_priority
20082323455SDoug Rabsonvalue or at the end of the list if no tasks have a lower priority.
20182323455SDoug RabsonEnqueueing a task does not perform any memory allocation which makes
20282323455SDoug Rabsonit suitable for calling from an interrupt handler.
20382323455SDoug RabsonThis function will return
204b92a189eSRuslan Ermilov.Er EPIPE
20582323455SDoug Rabsonif the queue is being freed.
20682323455SDoug Rabson.Pp
20782323455SDoug RabsonWhen a task is executed,
20882323455SDoug Rabsonfirst it is removed from the queue,
20982323455SDoug Rabsonthe value of
21082323455SDoug Rabson.Va ta_pending
21182323455SDoug Rabsonis recorded and then the field is zeroed.
21282323455SDoug RabsonThe function
21382323455SDoug Rabson.Va ta_func
21482323455SDoug Rabsonfrom the task structure is called with the value of the field
21582323455SDoug Rabson.Va ta_context
21682323455SDoug Rabsonas its first argument
21782323455SDoug Rabsonand the value of
21882323455SDoug Rabson.Va ta_pending
21982323455SDoug Rabsonas its second argument.
220f616cf33SJohn-Mark GurneyAfter the function
221f616cf33SJohn-Mark Gurney.Va ta_func
222f616cf33SJohn-Mark Gurneyreturns,
223f616cf33SJohn-Mark Gurney.Xr wakeup 9
224f616cf33SJohn-Mark Gurneyis called on the task pointer passed to
225f616cf33SJohn-Mark Gurney.Fn taskqueue_enqueue .
22682323455SDoug Rabson.Pp
227fff7ff71SGleb SmirnoffThe
228*b6f87b78SVladimir Kondratyev.Fn taskqueue_enqueue_flags
229*b6f87b78SVladimir Kondratyevaccepts an extra
230*b6f87b78SVladimir Kondratyev.Va flags
231*b6f87b78SVladimir Kondratyevparameter which specifies a set of optional flags to alter the behavior of
232*b6f87b78SVladimir Kondratyev.Fn taskqueue_enqueue .
233*b6f87b78SVladimir KondratyevIt contains one or more of the following flags:
234*b6f87b78SVladimir Kondratyev.Bl -tag -width TASKQUEUE_FAIL_IF_CANCELING
235*b6f87b78SVladimir Kondratyev.It Dv TASKQUEUE_FAIL_IF_PENDING
236*b6f87b78SVladimir Kondratyev.Fn taskqueue_enqueue_flags
237*b6f87b78SVladimir Kondratyevfails if the task is already scheduled for execution.
238*b6f87b78SVladimir Kondratyev.Er EEXIST
239*b6f87b78SVladimir Kondratyevis returned and the
240*b6f87b78SVladimir Kondratyev.Va ta_pending
241*b6f87b78SVladimir Kondratyevcounter value remains unchanged.
242*b6f87b78SVladimir Kondratyev.It Dv TASKQUEUE_FAIL_IF_CANCELING
243*b6f87b78SVladimir Kondratyev.Fn taskqueue_enqueue_flags
244*b6f87b78SVladimir Kondratyevfails if the task is in the canceling state and
245*b6f87b78SVladimir Kondratyev.Er ECANCELED
246*b6f87b78SVladimir Kondratyevis returned.
247*b6f87b78SVladimir Kondratyev.El
248*b6f87b78SVladimir Kondratyev.Pp
249*b6f87b78SVladimir KondratyevThe
250c3bd10b4SKonstantin Belousov.Fn taskqueue_enqueue_timeout
251f37b7fc2SIan Leporefunction is used to schedule the enqueue after the specified number of
252c3bd10b4SKonstantin Belousov.Va ticks .
253f37b7fc2SIan LeporeThe
254f37b7fc2SIan Lepore.Fn taskqueue_enqueue_timeout_sbt
255f37b7fc2SIan Leporefunction provides finer control over the scheduling based on
256f37b7fc2SIan Lepore.Va sbt ,
257f37b7fc2SIan Lepore.Va pr ,
258f37b7fc2SIan Leporeand
259f37b7fc2SIan Lepore.Va flags ,
260f37b7fc2SIan Leporeas detailed in
2612faadf10SYuri Pankov.Xr callout 9 .
262471af3a8SKonstantin BelousovIf the
263471af3a8SKonstantin Belousov.Va ticks
264471af3a8SKonstantin Belousovargument is negative, the already scheduled enqueueing is not re-scheduled.
265c1e231bcSKonstantin BelousovOtherwise, the task is scheduled for enqueueing in the future,
266471af3a8SKonstantin Belousovafter the absolute value of
267471af3a8SKonstantin Belousov.Va ticks
268471af3a8SKonstantin Belousovis passed.
2696a3536aaSHans Petter SelaskyThis function returns -1 if the task is being drained.
2706a3536aaSHans Petter SelaskyOtherwise, the number of pending calls is returned.
271c3bd10b4SKonstantin Belousov.Pp
272c3bd10b4SKonstantin BelousovThe
273f46276a9SMatthew D Fleming.Fn taskqueue_cancel
274f46276a9SMatthew D Flemingfunction is used to cancel a task.
275f46276a9SMatthew D FlemingThe
276f46276a9SMatthew D Fleming.Va ta_pending
277f46276a9SMatthew D Flemingcount is cleared, and the old value returned in the reference
278f46276a9SMatthew D Flemingparameter
279f46276a9SMatthew D Fleming.Fa pendp ,
28073bbeaa5SGlen Barberif it is
28173bbeaa5SGlen Barber.Pf non- Dv NULL .
282f46276a9SMatthew D FlemingIf the task is currently running,
283f46276a9SMatthew D Fleming.Dv EBUSY
284f46276a9SMatthew D Flemingis returned, otherwise 0.
285f46276a9SMatthew D FlemingTo implement a blocking
286f46276a9SMatthew D Fleming.Fn taskqueue_cancel
287f46276a9SMatthew D Flemingthat waits for a running task to finish, it could look like:
288f46276a9SMatthew D Fleming.Bd -literal -offset indent
289f46276a9SMatthew D Flemingwhile (taskqueue_cancel(tq, task, NULL) != 0)
290f46276a9SMatthew D Fleming	taskqueue_drain(tq, task);
291f46276a9SMatthew D Fleming.Ed
292f46276a9SMatthew D Fleming.Pp
293f46276a9SMatthew D FlemingNote that, as with
294f46276a9SMatthew D Fleming.Fn taskqueue_drain ,
295f46276a9SMatthew D Flemingthe caller is responsible for ensuring that the task is not re-enqueued
296f46276a9SMatthew D Flemingafter being canceled.
297f46276a9SMatthew D Fleming.Pp
298c3bd10b4SKonstantin BelousovSimilarly, the
299c3bd10b4SKonstantin Belousov.Fn taskqueue_cancel_timeout
300c3bd10b4SKonstantin Belousovfunction is used to cancel the scheduled task execution.
301c3bd10b4SKonstantin Belousov.Pp
302f46276a9SMatthew D FlemingThe
303fff7ff71SGleb Smirnoff.Fn taskqueue_drain
304c3bd10b4SKonstantin Belousovfunction is used to wait for the task to finish, and
305c3bd10b4SKonstantin Belousovthe
306c3bd10b4SKonstantin Belousov.Fn taskqueue_drain_timeout
307c3bd10b4SKonstantin Belousovfunction is used to wait for the scheduled task to finish.
308fff7ff71SGleb SmirnoffThere is no guarantee that the task will not be
309fff7ff71SGleb Smirnoffenqueued after call to
310fff7ff71SGleb Smirnoff.Fn taskqueue_drain .
311cb03508fSAndriy GaponIf the caller wants to put the task into a known state,
312cb03508fSAndriy Gaponthen before calling
313cb03508fSAndriy Gapon.Fn taskqueue_drain
314cb03508fSAndriy Gaponthe caller should use out-of-band means to ensure that the task
315cb03508fSAndriy Gaponwould not be enqueued.
316cb03508fSAndriy GaponFor example, if the task is enqueued by an interrupt filter, then
317cb03508fSAndriy Gaponthe interrupt could be disabled.
318cb03508fSAndriy Gapon.Pp
319cb03508fSAndriy GaponThe
320cb03508fSAndriy Gapon.Fn taskqueue_drain_all
321cb03508fSAndriy Gaponfunction is used to wait for all pending and running tasks that
322cb03508fSAndriy Gaponare enqueued on the taskqueue to finish.
3235b326a32SJustin T. GibbsTasks posted to the taskqueue after
324cb03508fSAndriy Gapon.Fn taskqueue_drain_all
3255b326a32SJustin T. Gibbsbegins processing,
3265b326a32SJustin T. Gibbsincluding pending enqueues scheduled by a previous call to
3275b326a32SJustin T. Gibbs.Fn taskqueue_enqueue_timeout ,
3285b326a32SJustin T. Gibbsdo not extend the wait time of
3295b326a32SJustin T. Gibbs.Fn taskqueue_drain_all
3305b326a32SJustin T. Gibbsand may complete after
3315b326a32SJustin T. Gibbs.Fn taskqueue_drain_all
3325b326a32SJustin T. Gibbsreturns.
333bb58b5d6SMark JohnstonThe
334bb58b5d6SMark Johnston.Fn taskqueue_quiesce
335bb58b5d6SMark Johnstonfunction is used to wait for the queue to become empty and for all
336bb58b5d6SMark Johnstonrunning tasks to finish.
337bb58b5d6SMark JohnstonTo avoid blocking indefinitely, the caller must ensure by some mechanism
338bb58b5d6SMark Johnstonthat tasks will eventually stop being posted to the queue.
339cb03508fSAndriy Gapon.Pp
340cb03508fSAndriy GaponThe
341cb03508fSAndriy Gapon.Fn taskqueue_block
342cb03508fSAndriy Gaponfunction blocks the taskqueue.
343cb03508fSAndriy GaponIt prevents any enqueued but not running tasks from being executed.
344cb03508fSAndriy GaponFuture calls to
345cb03508fSAndriy Gapon.Fn taskqueue_enqueue
346cb03508fSAndriy Gaponwill enqueue tasks, but the tasks will not be run until
347cb03508fSAndriy Gapon.Fn taskqueue_unblock
348cb03508fSAndriy Gaponis called.
349cb03508fSAndriy GaponPlease note that
350cb03508fSAndriy Gapon.Fn taskqueue_block
351cb03508fSAndriy Gapondoes not wait for any currently running tasks to finish.
352cb03508fSAndriy GaponThus, the
353cb03508fSAndriy Gapon.Fn taskqueue_block
354cb03508fSAndriy Gapondoes not provide a guarantee that
355cb03508fSAndriy Gapon.Fn taskqueue_run
356cb03508fSAndriy Gaponis not running after
357cb03508fSAndriy Gapon.Fn taskqueue_block
358cb03508fSAndriy Gaponreturns, but it does provide a guarantee that
359cb03508fSAndriy Gapon.Fn taskqueue_run
360cb03508fSAndriy Gaponwill not be called again
361cb03508fSAndriy Gaponuntil
362cb03508fSAndriy Gapon.Fn taskqueue_unblock
363cb03508fSAndriy Gaponis called.
364cb03508fSAndriy GaponIf the caller requires a guarantee that
365cb03508fSAndriy Gapon.Fn taskqueue_run
366cb03508fSAndriy Gaponis not running, then this must be arranged by the caller.
367cb03508fSAndriy GaponNote that if
368cb03508fSAndriy Gapon.Fn taskqueue_drain
369cb03508fSAndriy Gaponis called on a task that is enqueued on a taskqueue that is blocked by
370cb03508fSAndriy Gapon.Fn taskqueue_block ,
371cb03508fSAndriy Gaponthen
372cb03508fSAndriy Gapon.Fn taskqueue_drain
373cb03508fSAndriy Gaponcan not return until the taskqueue is unblocked.
374cb03508fSAndriy GaponThis can result in a deadlock if the thread blocked in
375cb03508fSAndriy Gapon.Fn taskqueue_drain
376cb03508fSAndriy Gaponis the thread that is supposed to call
377cb03508fSAndriy Gapon.Fn taskqueue_unblock .
378cb03508fSAndriy GaponThus, use of
379cb03508fSAndriy Gapon.Fn taskqueue_drain
380cb03508fSAndriy Gaponafter
381cb03508fSAndriy Gapon.Fn taskqueue_block
382cb03508fSAndriy Gaponis discouraged, because the state of the task can not be known in advance.
383cb03508fSAndriy GaponThe same caveat applies to
384cb03508fSAndriy Gapon.Fn taskqueue_drain_all .
385cb03508fSAndriy Gapon.Pp
386cb03508fSAndriy GaponThe
387cb03508fSAndriy Gapon.Fn taskqueue_unblock
388cb03508fSAndriy Gaponfunction unblocks the previously blocked taskqueue.
389cb03508fSAndriy GaponAll enqueued tasks can be run after this call.
390fff7ff71SGleb Smirnoff.Pp
391159ef108SPawel Jakub DawidekThe
392159ef108SPawel Jakub Dawidek.Fn taskqueue_member
393159ef108SPawel Jakub Dawidekfunction returns
394159ef108SPawel Jakub Dawidek.No 1
3959c1a8ce4SPawel Jakub Dawidekif the given thread
396159ef108SPawel Jakub Dawidek.Fa td
3979ba47352SJoel Dahlis part of the given taskqueue
398159ef108SPawel Jakub Dawidek.Fa queue
399159ef108SPawel Jakub Dawidekand
400159ef108SPawel Jakub Dawidek.No 0
401159ef108SPawel Jakub Dawidekotherwise.
402159ef108SPawel Jakub Dawidek.Pp
403a92f0ee8SMatthew D FlemingThe
404a92f0ee8SMatthew D Fleming.Fn taskqueue_run
405a92f0ee8SMatthew D Flemingfunction will run all pending tasks in the specified
406a92f0ee8SMatthew D Fleming.Fa queue .
407a92f0ee8SMatthew D FlemingNormally this function is only used internally.
408a92f0ee8SMatthew D Fleming.Pp
40982323455SDoug RabsonA convenience macro,
41082323455SDoug Rabson.Fn TASK_INIT "task" "priority" "func" "context"
41182323455SDoug Rabsonis provided to initialise a
41282323455SDoug Rabson.Va task
41382323455SDoug Rabsonstructure.
414a7f5f794SJohn BaldwinThe
415a7f5f794SJohn Baldwin.Fn TASK_INITIALIZER
416a7f5f794SJohn Baldwinmacro generates an initializer for a task structure.
417c3bd10b4SKonstantin BelousovA macro
418c3bd10b4SKonstantin Belousov.Fn TIMEOUT_TASK_INIT "queue" "timeout_task" "priority" "func" "context"
419a7f5f794SJohn Baldwininitializes the
420a7f5f794SJohn Baldwin.Va timeout_task
421a7f5f794SJohn Baldwinstructure.
42282323455SDoug RabsonThe values of
42382323455SDoug Rabson.Va priority ,
42482323455SDoug Rabson.Va func ,
42582323455SDoug Rabsonand
42682323455SDoug Rabson.Va context
42782323455SDoug Rabsonare simply copied into the task structure fields and the
42882323455SDoug Rabson.Va ta_pending
42982323455SDoug Rabsonfield is cleared.
43082323455SDoug Rabson.Pp
4312eb30874SOleksandr TymoshenkoFive macros
432227559d1SJohn-Mark Gurney.Fn TASKQUEUE_DECLARE "name" ,
433227559d1SJohn-Mark Gurney.Fn TASKQUEUE_DEFINE "name" "enqueue" "context" "init" ,
4342eb30874SOleksandr Tymoshenko.Fn TASKQUEUE_FAST_DEFINE "name" "enqueue" "context" "init" ,
43582323455SDoug Rabsonand
436227559d1SJohn-Mark Gurney.Fn TASKQUEUE_DEFINE_THREAD "name"
4372eb30874SOleksandr Tymoshenko.Fn TASKQUEUE_FAST_DEFINE_THREAD "name"
438227559d1SJohn-Mark Gurneyare used to declare a reference to a global queue, to define the
439c0854fb7SRuslan Ermilovimplementation of the queue, and declare a queue that uses its own thread.
44082323455SDoug RabsonThe
44182323455SDoug Rabson.Fn TASKQUEUE_DEFINE
44282323455SDoug Rabsonmacro arranges to call
44382323455SDoug Rabson.Fn taskqueue_create
44482323455SDoug Rabsonwith the values of its
44582323455SDoug Rabson.Va name ,
44682323455SDoug Rabson.Va enqueue
44782323455SDoug Rabsonand
44882323455SDoug Rabson.Va context
44982323455SDoug Rabsonarguments during system initialisation.
45082323455SDoug RabsonAfter calling
45182323455SDoug Rabson.Fn taskqueue_create ,
45282323455SDoug Rabsonthe
45382323455SDoug Rabson.Va init
45482323455SDoug Rabsonargument to the macro is executed as a C statement,
45582323455SDoug Rabsonallowing any further initialisation to be performed
4562e17a50fSBenjamin Kaduk(such as registering an interrupt handler, etc.).
45782323455SDoug Rabson.Pp
458227559d1SJohn-Mark GurneyThe
459227559d1SJohn-Mark Gurney.Fn TASKQUEUE_DEFINE_THREAD
460c0854fb7SRuslan Ermilovmacro defines a new taskqueue with its own kernel thread to serve tasks.
461c0854fb7SRuslan ErmilovThe variable
462227559d1SJohn-Mark Gurney.Vt struct taskqueue *taskqueue_name
463227559d1SJohn-Mark Gurneyis used to enqueue tasks onto the queue.
4642eb30874SOleksandr Tymoshenko.Pp
4652eb30874SOleksandr Tymoshenko.Fn TASKQUEUE_FAST_DEFINE
4662eb30874SOleksandr Tymoshenkoand
4672eb30874SOleksandr Tymoshenko.Fn TASKQUEUE_FAST_DEFINE_THREAD
4682eb30874SOleksandr Tymoshenkoact just like
4692eb30874SOleksandr Tymoshenko.Fn TASKQUEUE_DEFINE
4702eb30874SOleksandr Tymoshenkoand
4712eb30874SOleksandr Tymoshenko.Fn TASKQUEUE_DEFINE_THREAD
4722eb30874SOleksandr Tymoshenkorespectively but taskqueue is created with
4732eb30874SOleksandr Tymoshenko.Fn taskqueue_create_fast .
4744c49b002SJoseph Koshy.Ss Predefined Task Queues
4754c49b002SJoseph KoshyThe system provides four global taskqueues,
4764c49b002SJoseph Koshy.Va taskqueue_fast ,
47782323455SDoug Rabson.Va taskqueue_swi ,
478cb32189eSKenneth D. Merry.Va taskqueue_swi_giant ,
479cb32189eSKenneth D. Merryand
480cb32189eSKenneth D. Merry.Va taskqueue_thread .
4814c49b002SJoseph KoshyThe
4824c49b002SJoseph Koshy.Va taskqueue_fast
4834c49b002SJoseph Koshyqueue is for swi handlers dispatched from fast interrupt handlers,
4844c49b002SJoseph Koshywhere sleep mutexes cannot be used.
485cb32189eSKenneth D. MerryThe swi taskqueues are run via a software interrupt mechanism.
4864c49b002SJoseph KoshyThe
4874c49b002SJoseph Koshy.Va taskqueue_swi
4884c49b002SJoseph Koshyqueue runs without the protection of the
4894c49b002SJoseph Koshy.Va Giant
4904c49b002SJoseph Koshykernel lock, and the
4914c49b002SJoseph Koshy.Va taskqueue_swi_giant
4924c49b002SJoseph Koshyqueue runs with the protection of the
4934c49b002SJoseph Koshy.Va Giant
494cb32189eSKenneth D. Merrykernel lock.
4954c49b002SJoseph KoshyThe thread taskqueue
4964c49b002SJoseph Koshy.Va taskqueue_thread
4974c49b002SJoseph Koshyruns in a kernel thread context, and tasks run from this thread do
4984c49b002SJoseph Koshynot run under the
4994c49b002SJoseph Koshy.Va Giant
5004c49b002SJoseph Koshykernel lock.
5014c49b002SJoseph KoshyIf the caller wants to run under
5024c49b002SJoseph Koshy.Va Giant ,
5034c49b002SJoseph Koshyhe should explicitly acquire and release
5044c49b002SJoseph Koshy.Va Giant
5054c49b002SJoseph Koshyin his taskqueue handler routine.
506bf7f20c2SRuslan Ermilov.Pp
507cb32189eSKenneth D. MerryTo use these queues,
50882323455SDoug Rabsoncall
50982323455SDoug Rabson.Fn taskqueue_enqueue
510cb32189eSKenneth D. Merrywith the value of the global taskqueue variable for the queue you wish to
511cbc4d2dbSJohn Baldwinuse.
51282323455SDoug Rabson.Pp
513e0254f10SKenneth D. MerryThe software interrupt queues can be used,
51482323455SDoug Rabsonfor instance, for implementing interrupt handlers which must perform a
51582323455SDoug Rabsonsignificant amount of processing in the handler.
51682323455SDoug RabsonThe hardware interrupt handler would perform minimal processing of the
51782323455SDoug Rabsoninterrupt and then enqueue a task to finish the work.
51882323455SDoug RabsonThis reduces to a minimum
51982323455SDoug Rabsonthe amount of time spent with interrupts disabled.
520cb32189eSKenneth D. Merry.Pp
521cb32189eSKenneth D. MerryThe thread queue can be used, for instance, by interrupt level routines
522cb32189eSKenneth D. Merrythat need to call kernel functions that do things that can only be done
523cb32189eSKenneth D. Merryfrom a thread context.
524cb32189eSKenneth D. Merry(e.g., call malloc with the M_WAITOK flag.)
525cf82599dSSam Leffler.Pp
526cf82599dSSam LefflerNote that tasks queued on shared taskqueues such as
527cf82599dSSam Leffler.Va taskqueue_swi
528cf82599dSSam Lefflermay be delayed an indeterminate amount of time before execution.
529cf82599dSSam LefflerIf queueing delays cannot be tolerated then a private taskqueue should
530cf82599dSSam Lefflerbe created with a dedicated processing thread.
5313bbf58f9SJoseph Koshy.Sh SEE ALSO
5322faadf10SYuri Pankov.Xr callout 9 ,
5333bbf58f9SJoseph Koshy.Xr ithread 9 ,
5343bbf58f9SJoseph Koshy.Xr kthread 9 ,
5353bbf58f9SJoseph Koshy.Xr swi 9
53682323455SDoug Rabson.Sh HISTORY
53782323455SDoug RabsonThis interface first appeared in
53882323455SDoug Rabson.Fx 5.0 .
539c3bd10b4SKonstantin BelousovThere is a similar facility called work_queue in the Linux kernel.
54082323455SDoug Rabson.Sh AUTHORS
541571dba6eSHiten PandyaThis manual page was written by
54282323455SDoug Rabson.An Doug Rabson .
543