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