]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - share/man/man9/taskqueue.9
VOP_REVOKE(9): update locking requirements per r143495
[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 November 21, 2018
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_pinned
73 .Fa "struct taskqueue **tqp" "int count" "int pri" "int cpu_id"
74 .Fa "const char *name" "..."
75 .Fc
76 .Ft void
77 .Fn taskqueue_set_callback "struct taskqueue *queue" "enum taskqueue_callback_type cb_type" "taskqueue_callback_fn callback" "void *context"
78 .Ft void
79 .Fn taskqueue_free "struct taskqueue *queue"
80 .Ft int
81 .Fn taskqueue_enqueue "struct taskqueue *queue" "struct task *task"
82 .Ft int
83 .Fn taskqueue_enqueue_timeout "struct taskqueue *queue" "struct timeout_task *timeout_task" "int ticks"
84 .Ft int
85 .Fn taskqueue_enqueue_timeout_sbt "struct taskqueue *queue" "struct timeout_task *timeout_task" "sbintime_t sbt" "sbintime_t pr" "int flags"
86 .Ft int
87 .Fn taskqueue_cancel "struct taskqueue *queue" "struct task *task" "u_int *pendp"
88 .Ft int
89 .Fn taskqueue_cancel_timeout "struct taskqueue *queue" "struct timeout_task *timeout_task" "u_int *pendp"
90 .Ft void
91 .Fn taskqueue_drain "struct taskqueue *queue" "struct task *task"
92 .Ft void
93 .Fn taskqueue_drain_timeout "struct taskqueue *queue" "struct timeout_task *timeout_task"
94 .Ft void
95 .Fn taskqueue_drain_all "struct taskqueue *queue"
96 .Ft void
97 .Fn taskqueue_quiesce "struct taskqueue *queue"
98 .Ft void
99 .Fn taskqueue_block "struct taskqueue *queue"
100 .Ft void
101 .Fn taskqueue_unblock "struct taskqueue *queue"
102 .Ft int
103 .Fn taskqueue_member "struct taskqueue *queue" "struct thread *td"
104 .Ft void
105 .Fn taskqueue_run "struct taskqueue *queue"
106 .Fn TASK_INIT "struct task *task" "int priority" "task_fn_t func" "void *context"
107 .Fn TASK_INITIALIZER "int priority" "task_fn_t func" "void *context"
108 .Fn TASKQUEUE_DECLARE "name"
109 .Fn TASKQUEUE_DEFINE "name" "taskqueue_enqueue_fn enqueue" "void *context" "init"
110 .Fn TASKQUEUE_FAST_DEFINE "name" "taskqueue_enqueue_fn enqueue" "void *context" "init"
111 .Fn TASKQUEUE_DEFINE_THREAD "name"
112 .Fn TASKQUEUE_FAST_DEFINE_THREAD "name"
113 .Fn TIMEOUT_TASK_INIT "struct taskqueue *queue" "struct timeout_task *timeout_task" "int priority" "task_fn_t func" "void *context"
114 .Sh DESCRIPTION
115 These functions provide a simple interface for asynchronous execution
116 of code.
117 .Pp
118 The function
119 .Fn taskqueue_create
120 is used to create new queues.
121 The arguments to
122 .Fn taskqueue_create
123 include a name that should be unique,
124 a set of
125 .Xr malloc 9
126 flags that specify whether the call to
127 .Fn malloc
128 is allowed to sleep,
129 a function that is called from
130 .Fn taskqueue_enqueue
131 when a task is added to the queue,
132 and a pointer to the memory location where the identity of the
133 thread that services the queue is recorded.
134 .\" XXX The rest of the sentence gets lots in relation to the first part.
135 The function called from
136 .Fn taskqueue_enqueue
137 must arrange for the queue to be processed
138 (for instance by scheduling a software interrupt or waking a kernel
139 thread).
140 The memory location where the thread identity is recorded is used
141 to signal the service thread(s) to terminate--when this value is set to
142 zero and the thread is signaled it will terminate.
143 If the queue is intended for use in fast interrupt handlers
144 .Fn taskqueue_create_fast
145 should be used in place of
146 .Fn taskqueue_create .
147 .Pp
148 The function
149 .Fn taskqueue_free
150 should be used to free the memory used by the queue.
151 Any tasks that are on the queue will be executed at this time after
152 which the thread servicing the queue will be signaled that it should exit.
153 .Pp
154 Once a taskqueue has been created, its threads should be started using
155 .Fn taskqueue_start_threads
156 or
157 .Fn taskqueue_start_threads_pinned .
158 .Fn taskqueue_start_threads_pinned
159 takes a
160 .Va cpu_id
161 argument which will cause the threads which are started for the taskqueue
162 to be pinned to run on the given CPU.
163 Callbacks may optionally be registered using
164 .Fn taskqueue_set_callback .
165 Currently, callbacks may be registered for the following purposes:
166 .Bl -tag -width TASKQUEUE_CALLBACK_TYPE_SHUTDOWN
167 .It Dv TASKQUEUE_CALLBACK_TYPE_INIT
168 This callback is called by every thread in the taskqueue, before it executes
169 any tasks.
170 This callback must be set before the taskqueue's threads are started.
171 .It Dv TASKQUEUE_CALLBACK_TYPE_SHUTDOWN
172 This callback is called by every thread in the taskqueue, after it executes
173 its last task.
174 This callback will always be called before the taskqueue structure is
175 reclaimed.
176 .El
177 .Pp
178 To add a task to the list of tasks queued on a taskqueue, call
179 .Fn taskqueue_enqueue
180 with pointers to the queue and task.
181 If the task's
182 .Va ta_pending
183 field is non-zero,
184 then it is simply incremented to reflect the number of times the task
185 was enqueued, up to a cap of USHRT_MAX.
186 Otherwise,
187 the task is added to the list before the first task which has a lower
188 .Va ta_priority
189 value or at the end of the list if no tasks have a lower priority.
190 Enqueueing a task does not perform any memory allocation which makes
191 it suitable for calling from an interrupt handler.
192 This function will return
193 .Er EPIPE
194 if the queue is being freed.
195 .Pp
196 When a task is executed,
197 first it is removed from the queue,
198 the value of
199 .Va ta_pending
200 is recorded and then the field is zeroed.
201 The function
202 .Va ta_func
203 from the task structure is called with the value of the field
204 .Va ta_context
205 as its first argument
206 and the value of
207 .Va ta_pending
208 as its second argument.
209 After the function
210 .Va ta_func
211 returns,
212 .Xr wakeup 9
213 is called on the task pointer passed to
214 .Fn taskqueue_enqueue .
215 .Pp
216 The
217 .Fn taskqueue_enqueue_timeout
218 function is used to schedule the enqueue after the specified number of
219 .Va ticks .
220 The
221 .Fn taskqueue_enqueue_timeout_sbt
222 function provides finer control over the scheduling based on
223 .Va sbt ,
224 .Va pr ,
225 and
226 .Va flags ,
227 as detailed in
228 .Xr timeout 9 .
229 Only non-fast task queues can be used for
230 .Va timeout_task
231 scheduling.
232 If the
233 .Va ticks
234 argument is negative, the already scheduled enqueueing is not re-scheduled.
235 Otherwise, the task is scheduled for enqueueing in the future,
236 after the absolute value of
237 .Va ticks
238 is passed.
239 This function returns -1 if the task is being drained.
240 Otherwise, the number of pending calls is returned.
241 .Pp
242 The
243 .Fn taskqueue_cancel
244 function is used to cancel a task.
245 The
246 .Va ta_pending
247 count is cleared, and the old value returned in the reference
248 parameter
249 .Fa pendp ,
250 if it is
251 .Pf non- Dv NULL .
252 If the task is currently running,
253 .Dv EBUSY
254 is returned, otherwise 0.
255 To implement a blocking
256 .Fn taskqueue_cancel
257 that waits for a running task to finish, it could look like:
258 .Bd -literal -offset indent
259 while (taskqueue_cancel(tq, task, NULL) != 0)
260         taskqueue_drain(tq, task);
261 .Ed
262 .Pp
263 Note that, as with
264 .Fn taskqueue_drain ,
265 the caller is responsible for ensuring that the task is not re-enqueued
266 after being canceled.
267 .Pp
268 Similarly, the
269 .Fn taskqueue_cancel_timeout
270 function is used to cancel the scheduled task execution.
271 .Pp
272 The
273 .Fn taskqueue_drain
274 function is used to wait for the task to finish, and
275 the
276 .Fn taskqueue_drain_timeout
277 function is used to wait for the scheduled task to finish.
278 There is no guarantee that the task will not be
279 enqueued after call to
280 .Fn taskqueue_drain .
281 If the caller wants to put the task into a known state,
282 then before calling
283 .Fn taskqueue_drain
284 the caller should use out-of-band means to ensure that the task
285 would not be enqueued.
286 For example, if the task is enqueued by an interrupt filter, then
287 the interrupt could be disabled.
288 .Pp
289 The
290 .Fn taskqueue_drain_all
291 function is used to wait for all pending and running tasks that
292 are enqueued on the taskqueue to finish.
293 Tasks posted to the taskqueue after
294 .Fn taskqueue_drain_all
295 begins processing,
296 including pending enqueues scheduled by a previous call to
297 .Fn taskqueue_enqueue_timeout ,
298 do not extend the wait time of
299 .Fn taskqueue_drain_all
300 and may complete after
301 .Fn taskqueue_drain_all
302 returns.
303 The
304 .Fn taskqueue_quiesce
305 function is used to wait for the queue to become empty and for all
306 running tasks to finish.
307 To avoid blocking indefinitely, the caller must ensure by some mechanism
308 that tasks will eventually stop being posted to the queue.
309 .Pp
310 The
311 .Fn taskqueue_block
312 function blocks the taskqueue.
313 It prevents any enqueued but not running tasks from being executed.
314 Future calls to
315 .Fn taskqueue_enqueue
316 will enqueue tasks, but the tasks will not be run until
317 .Fn taskqueue_unblock
318 is called.
319 Please note that
320 .Fn taskqueue_block
321 does not wait for any currently running tasks to finish.
322 Thus, the
323 .Fn taskqueue_block
324 does not provide a guarantee that
325 .Fn taskqueue_run
326 is not running after
327 .Fn taskqueue_block
328 returns, but it does provide a guarantee that
329 .Fn taskqueue_run
330 will not be called again
331 until
332 .Fn taskqueue_unblock
333 is called.
334 If the caller requires a guarantee that
335 .Fn taskqueue_run
336 is not running, then this must be arranged by the caller.
337 Note that if
338 .Fn taskqueue_drain
339 is called on a task that is enqueued on a taskqueue that is blocked by
340 .Fn taskqueue_block ,
341 then
342 .Fn taskqueue_drain
343 can not return until the taskqueue is unblocked.
344 This can result in a deadlock if the thread blocked in
345 .Fn taskqueue_drain
346 is the thread that is supposed to call
347 .Fn taskqueue_unblock .
348 Thus, use of
349 .Fn taskqueue_drain
350 after
351 .Fn taskqueue_block
352 is discouraged, because the state of the task can not be known in advance.
353 The same caveat applies to
354 .Fn taskqueue_drain_all .
355 .Pp
356 The
357 .Fn taskqueue_unblock
358 function unblocks the previously blocked taskqueue.
359 All enqueued tasks can be run after this call.
360 .Pp
361 The
362 .Fn taskqueue_member
363 function returns
364 .No 1
365 if the given thread
366 .Fa td
367 is part of the given taskqueue
368 .Fa queue
369 and
370 .No 0
371 otherwise.
372 .Pp
373 The
374 .Fn taskqueue_run
375 function will run all pending tasks in the specified
376 .Fa queue .
377 Normally this function is only used internally.
378 .Pp
379 A convenience macro,
380 .Fn TASK_INIT "task" "priority" "func" "context"
381 is provided to initialise a
382 .Va task
383 structure.
384 The
385 .Fn TASK_INITIALIZER
386 macro generates an initializer for a task structure.
387 A macro
388 .Fn TIMEOUT_TASK_INIT "queue" "timeout_task" "priority" "func" "context"
389 initializes the
390 .Va timeout_task
391 structure.
392 The values of
393 .Va priority ,
394 .Va func ,
395 and
396 .Va context
397 are simply copied into the task structure fields and the
398 .Va ta_pending
399 field is cleared.
400 .Pp
401 Five macros
402 .Fn TASKQUEUE_DECLARE "name" ,
403 .Fn TASKQUEUE_DEFINE "name" "enqueue" "context" "init" ,
404 .Fn TASKQUEUE_FAST_DEFINE "name" "enqueue" "context" "init" ,
405 and
406 .Fn TASKQUEUE_DEFINE_THREAD "name"
407 .Fn TASKQUEUE_FAST_DEFINE_THREAD "name"
408 are used to declare a reference to a global queue, to define the
409 implementation of the queue, and declare a queue that uses its own thread.
410 The
411 .Fn TASKQUEUE_DEFINE
412 macro arranges to call
413 .Fn taskqueue_create
414 with the values of its
415 .Va name ,
416 .Va enqueue
417 and
418 .Va context
419 arguments during system initialisation.
420 After calling
421 .Fn taskqueue_create ,
422 the
423 .Va init
424 argument to the macro is executed as a C statement,
425 allowing any further initialisation to be performed
426 (such as registering an interrupt handler, etc.).
427 .Pp
428 The
429 .Fn TASKQUEUE_DEFINE_THREAD
430 macro defines a new taskqueue with its own kernel thread to serve tasks.
431 The variable
432 .Vt struct taskqueue *taskqueue_name
433 is used to enqueue tasks onto the queue.
434 .Pp
435 .Fn TASKQUEUE_FAST_DEFINE
436 and
437 .Fn TASKQUEUE_FAST_DEFINE_THREAD
438 act just like
439 .Fn TASKQUEUE_DEFINE
440 and
441 .Fn TASKQUEUE_DEFINE_THREAD
442 respectively but taskqueue is created with
443 .Fn taskqueue_create_fast .
444 .Ss Predefined Task Queues
445 The system provides four global taskqueues,
446 .Va taskqueue_fast ,
447 .Va taskqueue_swi ,
448 .Va taskqueue_swi_giant ,
449 and
450 .Va taskqueue_thread .
451 The
452 .Va taskqueue_fast
453 queue is for swi handlers dispatched from fast interrupt handlers,
454 where sleep mutexes cannot be used.
455 The swi taskqueues are run via a software interrupt mechanism.
456 The
457 .Va taskqueue_swi
458 queue runs without the protection of the
459 .Va Giant
460 kernel lock, and the
461 .Va taskqueue_swi_giant
462 queue runs with the protection of the
463 .Va Giant
464 kernel lock.
465 The thread taskqueue
466 .Va taskqueue_thread
467 runs in a kernel thread context, and tasks run from this thread do
468 not run under the
469 .Va Giant
470 kernel lock.
471 If the caller wants to run under
472 .Va Giant ,
473 he should explicitly acquire and release
474 .Va Giant
475 in his taskqueue handler routine.
476 .Pp
477 To use these queues,
478 call
479 .Fn taskqueue_enqueue
480 with the value of the global taskqueue variable for the queue you wish to
481 use.
482 .Pp
483 The software interrupt queues can be used,
484 for instance, for implementing interrupt handlers which must perform a
485 significant amount of processing in the handler.
486 The hardware interrupt handler would perform minimal processing of the
487 interrupt and then enqueue a task to finish the work.
488 This reduces to a minimum
489 the amount of time spent with interrupts disabled.
490 .Pp
491 The thread queue can be used, for instance, by interrupt level routines
492 that need to call kernel functions that do things that can only be done
493 from a thread context.
494 (e.g., call malloc with the M_WAITOK flag.)
495 .Pp
496 Note that tasks queued on shared taskqueues such as
497 .Va taskqueue_swi
498 may be delayed an indeterminate amount of time before execution.
499 If queueing delays cannot be tolerated then a private taskqueue should
500 be created with a dedicated processing thread.
501 .Sh SEE ALSO
502 .Xr ithread 9 ,
503 .Xr kthread 9 ,
504 .Xr swi 9
505 .Xr timeout 9
506 .Sh HISTORY
507 This interface first appeared in
508 .Fx 5.0 .
509 There is a similar facility called work_queue in the Linux kernel.
510 .Sh AUTHORS
511 This manual page was written by
512 .An Doug Rabson .