]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - share/man/man9/taskqueue.9
Remove $FreeBSD$: two-line nroff pattern
[FreeBSD/FreeBSD.git] / share / man / man9 / taskqueue.9
1 .\" -*- nroff -*-
2 .\"
3 .\" Copyright (c) 2000 Doug Rabson
4 .\"
5 .\" All rights reserved.
6 .\"
7 .\" This program is free software.
8 .\"
9 .\" Redistribution and use in source and binary forms, with or without
10 .\" modification, are permitted provided that the following conditions
11 .\" are met:
12 .\" 1. Redistributions of source code must retain the above copyright
13 .\"    notice, this list of conditions and the following disclaimer.
14 .\" 2. Redistributions in binary form must reproduce the above copyright
15 .\"    notice, this list of conditions and the following disclaimer in the
16 .\"    documentation and/or other materials provided with the distribution.
17 .\"
18 .\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
19 .\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 .\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 .\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
22 .\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 .\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 .\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 .\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 .\"
29 .Dd April 25, 2022
30 .Dt TASKQUEUE 9
31 .Os
32 .Sh NAME
33 .Nm taskqueue
34 .Nd asynchronous task execution
35 .Sh SYNOPSIS
36 .In sys/param.h
37 .In sys/kernel.h
38 .In sys/malloc.h
39 .In sys/queue.h
40 .In sys/taskqueue.h
41 .Bd -literal
42 typedef void (*task_fn_t)(void *context, int pending);
43
44 typedef void (*taskqueue_enqueue_fn)(void *context);
45
46 struct task {
47         STAILQ_ENTRY(task)      ta_link;        /* link for queue */
48         u_short                 ta_pending;     /* count times queued */
49         u_short                 ta_priority;    /* priority of task in queue */
50         task_fn_t               ta_func;        /* task handler */
51         void                    *ta_context;    /* argument for handler */
52 };
53
54 enum taskqueue_callback_type {
55         TASKQUEUE_CALLBACK_TYPE_INIT,
56         TASKQUEUE_CALLBACK_TYPE_SHUTDOWN,
57 };
58
59 typedef void (*taskqueue_callback_fn)(void *context);
60
61 struct timeout_task;
62 .Ed
63 .Ft struct taskqueue *
64 .Fn taskqueue_create "const char *name" "int mflags" "taskqueue_enqueue_fn enqueue" "void *context"
65 .Ft struct taskqueue *
66 .Fn taskqueue_create_fast "const char *name" "int mflags" "taskqueue_enqueue_fn enqueue" "void *context"
67 .Ft int
68 .Fn taskqueue_start_threads "struct taskqueue **tqp" "int count" "int pri" "const char *name" "..."
69 .Ft int
70 .Fo taskqueue_start_threads_cpuset
71 .Fa "struct taskqueue **tqp" "int count" "int pri" "cpuset_t *mask"
72 .Fa "const char *name" "..."
73 .Fc
74 .Ft int
75 .Fo taskqueue_start_threads_in_proc
76 .Fa "struct taskqueue **tqp" "int count" "int pri" "struct proc *proc"
77 .Fa "const char *name" "..."
78 .Fc
79 .Ft void
80 .Fn taskqueue_set_callback "struct taskqueue *queue" "enum taskqueue_callback_type cb_type" "taskqueue_callback_fn callback" "void *context"
81 .Ft void
82 .Fn taskqueue_free "struct taskqueue *queue"
83 .Ft int
84 .Fn taskqueue_enqueue "struct taskqueue *queue" "struct task *task"
85 .Ft int
86 .Fn taskqueue_enqueue_flags "struct taskqueue *queue" "struct task *task" "int flags"
87 .Ft int
88 .Fn taskqueue_enqueue_timeout "struct taskqueue *queue" "struct timeout_task *timeout_task" "int ticks"
89 .Ft int
90 .Fn taskqueue_enqueue_timeout_sbt "struct taskqueue *queue" "struct timeout_task *timeout_task" "sbintime_t sbt" "sbintime_t pr" "int flags"
91 .Ft int
92 .Fn taskqueue_cancel "struct taskqueue *queue" "struct task *task" "u_int *pendp"
93 .Ft int
94 .Fn taskqueue_cancel_timeout "struct taskqueue *queue" "struct timeout_task *timeout_task" "u_int *pendp"
95 .Ft void
96 .Fn taskqueue_drain "struct taskqueue *queue" "struct task *task"
97 .Ft void
98 .Fn taskqueue_drain_timeout "struct taskqueue *queue" "struct timeout_task *timeout_task"
99 .Ft void
100 .Fn taskqueue_drain_all "struct taskqueue *queue"
101 .Ft void
102 .Fn taskqueue_quiesce "struct taskqueue *queue"
103 .Ft void
104 .Fn taskqueue_block "struct taskqueue *queue"
105 .Ft void
106 .Fn taskqueue_unblock "struct taskqueue *queue"
107 .Ft int
108 .Fn taskqueue_member "struct taskqueue *queue" "struct thread *td"
109 .Ft void
110 .Fn taskqueue_run "struct taskqueue *queue"
111 .Fn TASK_INIT "struct task *task" "int priority" "task_fn_t func" "void *context"
112 .Fn TASK_INITIALIZER "int priority" "task_fn_t func" "void *context"
113 .Fn TASKQUEUE_DECLARE "name"
114 .Fn TASKQUEUE_DEFINE "name" "taskqueue_enqueue_fn enqueue" "void *context" "init"
115 .Fn TASKQUEUE_FAST_DEFINE "name" "taskqueue_enqueue_fn enqueue" "void *context" "init"
116 .Fn TASKQUEUE_DEFINE_THREAD "name"
117 .Fn TASKQUEUE_FAST_DEFINE_THREAD "name"
118 .Fn TIMEOUT_TASK_INIT "struct taskqueue *queue" "struct timeout_task *timeout_task" "int priority" "task_fn_t func" "void *context"
119 .Sh DESCRIPTION
120 These functions provide a simple interface for asynchronous execution
121 of code.
122 .Pp
123 The function
124 .Fn taskqueue_create
125 is used to create new queues.
126 The arguments to
127 .Fn taskqueue_create
128 include a name that should be unique,
129 a set of
130 .Xr malloc 9
131 flags that specify whether the call to
132 .Fn malloc
133 is allowed to sleep,
134 a function that is called from
135 .Fn taskqueue_enqueue
136 when a task is added to the queue,
137 and a pointer to the memory location where the identity of the
138 thread that services the queue is recorded.
139 .\" XXX The rest of the sentence gets lots in relation to the first part.
140 The function called from
141 .Fn taskqueue_enqueue
142 must arrange for the queue to be processed
143 (for instance by scheduling a software interrupt or waking a kernel
144 thread).
145 The memory location where the thread identity is recorded is used
146 to signal the service thread(s) to terminate--when this value is set to
147 zero and the thread is signaled it will terminate.
148 If the queue is intended for use in fast interrupt handlers
149 .Fn taskqueue_create_fast
150 should be used in place of
151 .Fn taskqueue_create .
152 .Pp
153 The function
154 .Fn taskqueue_free
155 should be used to free the memory used by the queue.
156 Any tasks that are on the queue will be executed at this time after
157 which the thread servicing the queue will be signaled that it should exit.
158 .Pp
159 Once a taskqueue has been created, its threads should be started using
160 .Fn taskqueue_start_threads ,
161 .Fn taskqueue_start_threads_cpuset
162 or
163 .Fn taskqueue_start_threads_in_proc .
164 .Fn taskqueue_start_threads_cpuset
165 takes a
166 .Va cpuset
167 argument which will cause the threads which are started for the taskqueue
168 to be restricted to run on the given CPUs.
169 .Fn taskqueue_start_threads_in_proc
170 takes a
171 .Va proc
172 argument which will cause the threads which are started for the taskqueue
173 to be assigned to the given kernel process.
174 Callbacks may optionally be registered using
175 .Fn taskqueue_set_callback .
176 Currently, callbacks may be registered for the following purposes:
177 .Bl -tag -width TASKQUEUE_CALLBACK_TYPE_SHUTDOWN
178 .It Dv TASKQUEUE_CALLBACK_TYPE_INIT
179 This callback is called by every thread in the taskqueue, before it executes
180 any tasks.
181 This callback must be set before the taskqueue's threads are started.
182 .It Dv TASKQUEUE_CALLBACK_TYPE_SHUTDOWN
183 This callback is called by every thread in the taskqueue, after it executes
184 its last task.
185 This callback will always be called before the taskqueue structure is
186 reclaimed.
187 .El
188 .Pp
189 To add a task to the list of tasks queued on a taskqueue, call
190 .Fn taskqueue_enqueue
191 with pointers to the queue and task.
192 If the task's
193 .Va ta_pending
194 field is non-zero,
195 then it is simply incremented to reflect the number of times the task
196 was enqueued, up to a cap of USHRT_MAX.
197 Otherwise,
198 the task is added to the list before the first task which has a lower
199 .Va ta_priority
200 value or at the end of the list if no tasks have a lower priority.
201 Enqueueing a task does not perform any memory allocation which makes
202 it suitable for calling from an interrupt handler.
203 This function will return
204 .Er EPIPE
205 if the queue is being freed.
206 .Pp
207 When a task is executed,
208 first it is removed from the queue,
209 the value of
210 .Va ta_pending
211 is recorded and then the field is zeroed.
212 The function
213 .Va ta_func
214 from the task structure is called with the value of the field
215 .Va ta_context
216 as its first argument
217 and the value of
218 .Va ta_pending
219 as its second argument.
220 After the function
221 .Va ta_func
222 returns,
223 .Xr wakeup 9
224 is called on the task pointer passed to
225 .Fn taskqueue_enqueue .
226 .Pp
227 The
228 .Fn taskqueue_enqueue_flags
229 accepts an extra
230 .Va flags
231 parameter which specifies a set of optional flags to alter the behavior of
232 .Fn taskqueue_enqueue .
233 It contains one or more of the following flags:
234 .Bl -tag -width TASKQUEUE_FAIL_IF_CANCELING
235 .It Dv TASKQUEUE_FAIL_IF_PENDING
236 .Fn taskqueue_enqueue_flags
237 fails if the task is already scheduled for execution.
238 .Er EEXIST
239 is returned and the
240 .Va ta_pending
241 counter value remains unchanged.
242 .It Dv TASKQUEUE_FAIL_IF_CANCELING
243 .Fn taskqueue_enqueue_flags
244 fails if the task is in the canceling state and
245 .Er ECANCELED
246 is returned.
247 .El
248 .Pp
249 The
250 .Fn taskqueue_enqueue_timeout
251 function is used to schedule the enqueue after the specified number of
252 .Va ticks .
253 The
254 .Fn taskqueue_enqueue_timeout_sbt
255 function provides finer control over the scheduling based on
256 .Va sbt ,
257 .Va pr ,
258 and
259 .Va flags ,
260 as detailed in
261 .Xr callout 9 .
262 If the
263 .Va ticks
264 argument is negative, the already scheduled enqueueing is not re-scheduled.
265 Otherwise, the task is scheduled for enqueueing in the future,
266 after the absolute value of
267 .Va ticks
268 is passed.
269 This function returns -1 if the task is being drained.
270 Otherwise, the number of pending calls is returned.
271 .Pp
272 The
273 .Fn taskqueue_cancel
274 function is used to cancel a task.
275 The
276 .Va ta_pending
277 count is cleared, and the old value returned in the reference
278 parameter
279 .Fa pendp ,
280 if it is
281 .Pf non- Dv NULL .
282 If the task is currently running,
283 .Dv EBUSY
284 is returned, otherwise 0.
285 To implement a blocking
286 .Fn taskqueue_cancel
287 that waits for a running task to finish, it could look like:
288 .Bd -literal -offset indent
289 while (taskqueue_cancel(tq, task, NULL) != 0)
290         taskqueue_drain(tq, task);
291 .Ed
292 .Pp
293 Note that, as with
294 .Fn taskqueue_drain ,
295 the caller is responsible for ensuring that the task is not re-enqueued
296 after being canceled.
297 .Pp
298 Similarly, the
299 .Fn taskqueue_cancel_timeout
300 function is used to cancel the scheduled task execution.
301 .Pp
302 The
303 .Fn taskqueue_drain
304 function is used to wait for the task to finish, and
305 the
306 .Fn taskqueue_drain_timeout
307 function is used to wait for the scheduled task to finish.
308 There is no guarantee that the task will not be
309 enqueued after call to
310 .Fn taskqueue_drain .
311 If the caller wants to put the task into a known state,
312 then before calling
313 .Fn taskqueue_drain
314 the caller should use out-of-band means to ensure that the task
315 would not be enqueued.
316 For example, if the task is enqueued by an interrupt filter, then
317 the interrupt could be disabled.
318 .Pp
319 The
320 .Fn taskqueue_drain_all
321 function is used to wait for all pending and running tasks that
322 are enqueued on the taskqueue to finish.
323 Tasks posted to the taskqueue after
324 .Fn taskqueue_drain_all
325 begins processing,
326 including pending enqueues scheduled by a previous call to
327 .Fn taskqueue_enqueue_timeout ,
328 do not extend the wait time of
329 .Fn taskqueue_drain_all
330 and may complete after
331 .Fn taskqueue_drain_all
332 returns.
333 The
334 .Fn taskqueue_quiesce
335 function is used to wait for the queue to become empty and for all
336 running tasks to finish.
337 To avoid blocking indefinitely, the caller must ensure by some mechanism
338 that tasks will eventually stop being posted to the queue.
339 .Pp
340 The
341 .Fn taskqueue_block
342 function blocks the taskqueue.
343 It prevents any enqueued but not running tasks from being executed.
344 Future calls to
345 .Fn taskqueue_enqueue
346 will enqueue tasks, but the tasks will not be run until
347 .Fn taskqueue_unblock
348 is called.
349 Please note that
350 .Fn taskqueue_block
351 does not wait for any currently running tasks to finish.
352 Thus, the
353 .Fn taskqueue_block
354 does not provide a guarantee that
355 .Fn taskqueue_run
356 is not running after
357 .Fn taskqueue_block
358 returns, but it does provide a guarantee that
359 .Fn taskqueue_run
360 will not be called again
361 until
362 .Fn taskqueue_unblock
363 is called.
364 If the caller requires a guarantee that
365 .Fn taskqueue_run
366 is not running, then this must be arranged by the caller.
367 Note that if
368 .Fn taskqueue_drain
369 is called on a task that is enqueued on a taskqueue that is blocked by
370 .Fn taskqueue_block ,
371 then
372 .Fn taskqueue_drain
373 can not return until the taskqueue is unblocked.
374 This can result in a deadlock if the thread blocked in
375 .Fn taskqueue_drain
376 is the thread that is supposed to call
377 .Fn taskqueue_unblock .
378 Thus, use of
379 .Fn taskqueue_drain
380 after
381 .Fn taskqueue_block
382 is discouraged, because the state of the task can not be known in advance.
383 The same caveat applies to
384 .Fn taskqueue_drain_all .
385 .Pp
386 The
387 .Fn taskqueue_unblock
388 function unblocks the previously blocked taskqueue.
389 All enqueued tasks can be run after this call.
390 .Pp
391 The
392 .Fn taskqueue_member
393 function returns
394 .No 1
395 if the given thread
396 .Fa td
397 is part of the given taskqueue
398 .Fa queue
399 and
400 .No 0
401 otherwise.
402 .Pp
403 The
404 .Fn taskqueue_run
405 function will run all pending tasks in the specified
406 .Fa queue .
407 Normally this function is only used internally.
408 .Pp
409 A convenience macro,
410 .Fn TASK_INIT "task" "priority" "func" "context"
411 is provided to initialise a
412 .Va task
413 structure.
414 The
415 .Fn TASK_INITIALIZER
416 macro generates an initializer for a task structure.
417 A macro
418 .Fn TIMEOUT_TASK_INIT "queue" "timeout_task" "priority" "func" "context"
419 initializes the
420 .Va timeout_task
421 structure.
422 The values of
423 .Va priority ,
424 .Va func ,
425 and
426 .Va context
427 are simply copied into the task structure fields and the
428 .Va ta_pending
429 field is cleared.
430 .Pp
431 Five macros
432 .Fn TASKQUEUE_DECLARE "name" ,
433 .Fn TASKQUEUE_DEFINE "name" "enqueue" "context" "init" ,
434 .Fn TASKQUEUE_FAST_DEFINE "name" "enqueue" "context" "init" ,
435 and
436 .Fn TASKQUEUE_DEFINE_THREAD "name"
437 .Fn TASKQUEUE_FAST_DEFINE_THREAD "name"
438 are used to declare a reference to a global queue, to define the
439 implementation of the queue, and declare a queue that uses its own thread.
440 The
441 .Fn TASKQUEUE_DEFINE
442 macro arranges to call
443 .Fn taskqueue_create
444 with the values of its
445 .Va name ,
446 .Va enqueue
447 and
448 .Va context
449 arguments during system initialisation.
450 After calling
451 .Fn taskqueue_create ,
452 the
453 .Va init
454 argument to the macro is executed as a C statement,
455 allowing any further initialisation to be performed
456 (such as registering an interrupt handler, etc.).
457 .Pp
458 The
459 .Fn TASKQUEUE_DEFINE_THREAD
460 macro defines a new taskqueue with its own kernel thread to serve tasks.
461 The variable
462 .Vt struct taskqueue *taskqueue_name
463 is used to enqueue tasks onto the queue.
464 .Pp
465 .Fn TASKQUEUE_FAST_DEFINE
466 and
467 .Fn TASKQUEUE_FAST_DEFINE_THREAD
468 act just like
469 .Fn TASKQUEUE_DEFINE
470 and
471 .Fn TASKQUEUE_DEFINE_THREAD
472 respectively but taskqueue is created with
473 .Fn taskqueue_create_fast .
474 .Ss Predefined Task Queues
475 The system provides four global taskqueues,
476 .Va taskqueue_fast ,
477 .Va taskqueue_swi ,
478 .Va taskqueue_swi_giant ,
479 and
480 .Va taskqueue_thread .
481 The
482 .Va taskqueue_fast
483 queue is for swi handlers dispatched from fast interrupt handlers,
484 where sleep mutexes cannot be used.
485 The swi taskqueues are run via a software interrupt mechanism.
486 The
487 .Va taskqueue_swi
488 queue runs without the protection of the
489 .Va Giant
490 kernel lock, and the
491 .Va taskqueue_swi_giant
492 queue runs with the protection of the
493 .Va Giant
494 kernel lock.
495 The thread taskqueue
496 .Va taskqueue_thread
497 runs in a kernel thread context, and tasks run from this thread do
498 not run under the
499 .Va Giant
500 kernel lock.
501 If the caller wants to run under
502 .Va Giant ,
503 he should explicitly acquire and release
504 .Va Giant
505 in his taskqueue handler routine.
506 .Pp
507 To use these queues,
508 call
509 .Fn taskqueue_enqueue
510 with the value of the global taskqueue variable for the queue you wish to
511 use.
512 .Pp
513 The software interrupt queues can be used,
514 for instance, for implementing interrupt handlers which must perform a
515 significant amount of processing in the handler.
516 The hardware interrupt handler would perform minimal processing of the
517 interrupt and then enqueue a task to finish the work.
518 This reduces to a minimum
519 the amount of time spent with interrupts disabled.
520 .Pp
521 The thread queue can be used, for instance, by interrupt level routines
522 that need to call kernel functions that do things that can only be done
523 from a thread context.
524 (e.g., call malloc with the M_WAITOK flag.)
525 .Pp
526 Note that tasks queued on shared taskqueues such as
527 .Va taskqueue_swi
528 may be delayed an indeterminate amount of time before execution.
529 If queueing delays cannot be tolerated then a private taskqueue should
530 be created with a dedicated processing thread.
531 .Sh SEE ALSO
532 .Xr callout 9 ,
533 .Xr ithread 9 ,
534 .Xr kthread 9 ,
535 .Xr swi 9
536 .Sh HISTORY
537 This interface first appeared in
538 .Fx 5.0 .
539 There is a similar facility called work_queue in the Linux kernel.
540 .Sh AUTHORS
541 This manual page was written by
542 .An Doug Rabson .