]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - share/man/man9/taskqueue.9
bhnd_erom(9): Fix a few mandoc related issues
[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 .\" $FreeBSD$
30 .\"
31 .Dd June 6, 2020
32 .Dt TASKQUEUE 9
33 .Os
34 .Sh NAME
35 .Nm taskqueue
36 .Nd asynchronous task execution
37 .Sh SYNOPSIS
38 .In sys/param.h
39 .In sys/kernel.h
40 .In sys/malloc.h
41 .In sys/queue.h
42 .In sys/taskqueue.h
43 .Bd -literal
44 typedef void (*task_fn_t)(void *context, int pending);
45
46 typedef void (*taskqueue_enqueue_fn)(void *context);
47
48 struct task {
49         STAILQ_ENTRY(task)      ta_link;        /* link for queue */
50         u_short                 ta_pending;     /* count times queued */
51         u_short                 ta_priority;    /* priority of task in queue */
52         task_fn_t               ta_func;        /* task handler */
53         void                    *ta_context;    /* argument for handler */
54 };
55
56 enum taskqueue_callback_type {
57         TASKQUEUE_CALLBACK_TYPE_INIT,
58         TASKQUEUE_CALLBACK_TYPE_SHUTDOWN,
59 };
60
61 typedef void (*taskqueue_callback_fn)(void *context);
62
63 struct timeout_task;
64 .Ed
65 .Ft struct taskqueue *
66 .Fn taskqueue_create "const char *name" "int mflags" "taskqueue_enqueue_fn enqueue" "void *context"
67 .Ft struct taskqueue *
68 .Fn taskqueue_create_fast "const char *name" "int mflags" "taskqueue_enqueue_fn enqueue" "void *context"
69 .Ft int
70 .Fn taskqueue_start_threads "struct taskqueue **tqp" "int count" "int pri" "const char *name" "..."
71 .Ft int
72 .Fo taskqueue_start_threads_cpuset
73 .Fa "struct taskqueue **tqp" "int count" "int pri" "cpuset_t *mask"
74 .Fa "const char *name" "..."
75 .Fc
76 .Ft int
77 .Fo taskqueue_start_threads_in_proc
78 .Fa "struct taskqueue **tqp" "int count" "int pri" "struct proc *proc"
79 .Fa "const char *name" "..."
80 .Fc
81 .Ft void
82 .Fn taskqueue_set_callback "struct taskqueue *queue" "enum taskqueue_callback_type cb_type" "taskqueue_callback_fn callback" "void *context"
83 .Ft void
84 .Fn taskqueue_free "struct taskqueue *queue"
85 .Ft int
86 .Fn taskqueue_enqueue "struct taskqueue *queue" "struct task *task"
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_timeout
229 function is used to schedule the enqueue after the specified number of
230 .Va ticks .
231 The
232 .Fn taskqueue_enqueue_timeout_sbt
233 function provides finer control over the scheduling based on
234 .Va sbt ,
235 .Va pr ,
236 and
237 .Va flags ,
238 as detailed in
239 .Xr callout 9 .
240 Only non-fast task queues can be used for
241 .Va timeout_task
242 scheduling.
243 If the
244 .Va ticks
245 argument is negative, the already scheduled enqueueing is not re-scheduled.
246 Otherwise, the task is scheduled for enqueueing in the future,
247 after the absolute value of
248 .Va ticks
249 is passed.
250 This function returns -1 if the task is being drained.
251 Otherwise, the number of pending calls is returned.
252 .Pp
253 The
254 .Fn taskqueue_cancel
255 function is used to cancel a task.
256 The
257 .Va ta_pending
258 count is cleared, and the old value returned in the reference
259 parameter
260 .Fa pendp ,
261 if it is
262 .Pf non- Dv NULL .
263 If the task is currently running,
264 .Dv EBUSY
265 is returned, otherwise 0.
266 To implement a blocking
267 .Fn taskqueue_cancel
268 that waits for a running task to finish, it could look like:
269 .Bd -literal -offset indent
270 while (taskqueue_cancel(tq, task, NULL) != 0)
271         taskqueue_drain(tq, task);
272 .Ed
273 .Pp
274 Note that, as with
275 .Fn taskqueue_drain ,
276 the caller is responsible for ensuring that the task is not re-enqueued
277 after being canceled.
278 .Pp
279 Similarly, the
280 .Fn taskqueue_cancel_timeout
281 function is used to cancel the scheduled task execution.
282 .Pp
283 The
284 .Fn taskqueue_drain
285 function is used to wait for the task to finish, and
286 the
287 .Fn taskqueue_drain_timeout
288 function is used to wait for the scheduled task to finish.
289 There is no guarantee that the task will not be
290 enqueued after call to
291 .Fn taskqueue_drain .
292 If the caller wants to put the task into a known state,
293 then before calling
294 .Fn taskqueue_drain
295 the caller should use out-of-band means to ensure that the task
296 would not be enqueued.
297 For example, if the task is enqueued by an interrupt filter, then
298 the interrupt could be disabled.
299 .Pp
300 The
301 .Fn taskqueue_drain_all
302 function is used to wait for all pending and running tasks that
303 are enqueued on the taskqueue to finish.
304 Tasks posted to the taskqueue after
305 .Fn taskqueue_drain_all
306 begins processing,
307 including pending enqueues scheduled by a previous call to
308 .Fn taskqueue_enqueue_timeout ,
309 do not extend the wait time of
310 .Fn taskqueue_drain_all
311 and may complete after
312 .Fn taskqueue_drain_all
313 returns.
314 The
315 .Fn taskqueue_quiesce
316 function is used to wait for the queue to become empty and for all
317 running tasks to finish.
318 To avoid blocking indefinitely, the caller must ensure by some mechanism
319 that tasks will eventually stop being posted to the queue.
320 .Pp
321 The
322 .Fn taskqueue_block
323 function blocks the taskqueue.
324 It prevents any enqueued but not running tasks from being executed.
325 Future calls to
326 .Fn taskqueue_enqueue
327 will enqueue tasks, but the tasks will not be run until
328 .Fn taskqueue_unblock
329 is called.
330 Please note that
331 .Fn taskqueue_block
332 does not wait for any currently running tasks to finish.
333 Thus, the
334 .Fn taskqueue_block
335 does not provide a guarantee that
336 .Fn taskqueue_run
337 is not running after
338 .Fn taskqueue_block
339 returns, but it does provide a guarantee that
340 .Fn taskqueue_run
341 will not be called again
342 until
343 .Fn taskqueue_unblock
344 is called.
345 If the caller requires a guarantee that
346 .Fn taskqueue_run
347 is not running, then this must be arranged by the caller.
348 Note that if
349 .Fn taskqueue_drain
350 is called on a task that is enqueued on a taskqueue that is blocked by
351 .Fn taskqueue_block ,
352 then
353 .Fn taskqueue_drain
354 can not return until the taskqueue is unblocked.
355 This can result in a deadlock if the thread blocked in
356 .Fn taskqueue_drain
357 is the thread that is supposed to call
358 .Fn taskqueue_unblock .
359 Thus, use of
360 .Fn taskqueue_drain
361 after
362 .Fn taskqueue_block
363 is discouraged, because the state of the task can not be known in advance.
364 The same caveat applies to
365 .Fn taskqueue_drain_all .
366 .Pp
367 The
368 .Fn taskqueue_unblock
369 function unblocks the previously blocked taskqueue.
370 All enqueued tasks can be run after this call.
371 .Pp
372 The
373 .Fn taskqueue_member
374 function returns
375 .No 1
376 if the given thread
377 .Fa td
378 is part of the given taskqueue
379 .Fa queue
380 and
381 .No 0
382 otherwise.
383 .Pp
384 The
385 .Fn taskqueue_run
386 function will run all pending tasks in the specified
387 .Fa queue .
388 Normally this function is only used internally.
389 .Pp
390 A convenience macro,
391 .Fn TASK_INIT "task" "priority" "func" "context"
392 is provided to initialise a
393 .Va task
394 structure.
395 The
396 .Fn TASK_INITIALIZER
397 macro generates an initializer for a task structure.
398 A macro
399 .Fn TIMEOUT_TASK_INIT "queue" "timeout_task" "priority" "func" "context"
400 initializes the
401 .Va timeout_task
402 structure.
403 The values of
404 .Va priority ,
405 .Va func ,
406 and
407 .Va context
408 are simply copied into the task structure fields and the
409 .Va ta_pending
410 field is cleared.
411 .Pp
412 Five macros
413 .Fn TASKQUEUE_DECLARE "name" ,
414 .Fn TASKQUEUE_DEFINE "name" "enqueue" "context" "init" ,
415 .Fn TASKQUEUE_FAST_DEFINE "name" "enqueue" "context" "init" ,
416 and
417 .Fn TASKQUEUE_DEFINE_THREAD "name"
418 .Fn TASKQUEUE_FAST_DEFINE_THREAD "name"
419 are used to declare a reference to a global queue, to define the
420 implementation of the queue, and declare a queue that uses its own thread.
421 The
422 .Fn TASKQUEUE_DEFINE
423 macro arranges to call
424 .Fn taskqueue_create
425 with the values of its
426 .Va name ,
427 .Va enqueue
428 and
429 .Va context
430 arguments during system initialisation.
431 After calling
432 .Fn taskqueue_create ,
433 the
434 .Va init
435 argument to the macro is executed as a C statement,
436 allowing any further initialisation to be performed
437 (such as registering an interrupt handler, etc.).
438 .Pp
439 The
440 .Fn TASKQUEUE_DEFINE_THREAD
441 macro defines a new taskqueue with its own kernel thread to serve tasks.
442 The variable
443 .Vt struct taskqueue *taskqueue_name
444 is used to enqueue tasks onto the queue.
445 .Pp
446 .Fn TASKQUEUE_FAST_DEFINE
447 and
448 .Fn TASKQUEUE_FAST_DEFINE_THREAD
449 act just like
450 .Fn TASKQUEUE_DEFINE
451 and
452 .Fn TASKQUEUE_DEFINE_THREAD
453 respectively but taskqueue is created with
454 .Fn taskqueue_create_fast .
455 .Ss Predefined Task Queues
456 The system provides four global taskqueues,
457 .Va taskqueue_fast ,
458 .Va taskqueue_swi ,
459 .Va taskqueue_swi_giant ,
460 and
461 .Va taskqueue_thread .
462 The
463 .Va taskqueue_fast
464 queue is for swi handlers dispatched from fast interrupt handlers,
465 where sleep mutexes cannot be used.
466 The swi taskqueues are run via a software interrupt mechanism.
467 The
468 .Va taskqueue_swi
469 queue runs without the protection of the
470 .Va Giant
471 kernel lock, and the
472 .Va taskqueue_swi_giant
473 queue runs with the protection of the
474 .Va Giant
475 kernel lock.
476 The thread taskqueue
477 .Va taskqueue_thread
478 runs in a kernel thread context, and tasks run from this thread do
479 not run under the
480 .Va Giant
481 kernel lock.
482 If the caller wants to run under
483 .Va Giant ,
484 he should explicitly acquire and release
485 .Va Giant
486 in his taskqueue handler routine.
487 .Pp
488 To use these queues,
489 call
490 .Fn taskqueue_enqueue
491 with the value of the global taskqueue variable for the queue you wish to
492 use.
493 .Pp
494 The software interrupt queues can be used,
495 for instance, for implementing interrupt handlers which must perform a
496 significant amount of processing in the handler.
497 The hardware interrupt handler would perform minimal processing of the
498 interrupt and then enqueue a task to finish the work.
499 This reduces to a minimum
500 the amount of time spent with interrupts disabled.
501 .Pp
502 The thread queue can be used, for instance, by interrupt level routines
503 that need to call kernel functions that do things that can only be done
504 from a thread context.
505 (e.g., call malloc with the M_WAITOK flag.)
506 .Pp
507 Note that tasks queued on shared taskqueues such as
508 .Va taskqueue_swi
509 may be delayed an indeterminate amount of time before execution.
510 If queueing delays cannot be tolerated then a private taskqueue should
511 be created with a dedicated processing thread.
512 .Sh SEE ALSO
513 .Xr callout 9 ,
514 .Xr ithread 9 ,
515 .Xr kthread 9 ,
516 .Xr swi 9
517 .Sh HISTORY
518 This interface first appeared in
519 .Fx 5.0 .
520 There is a similar facility called work_queue in the Linux kernel.
521 .Sh AUTHORS
522 This manual page was written by
523 .An Doug Rabson .