1'\" 2.\" Copyright (c) 2005, Sun Microsystems, Inc. All Rights Reserved. 3.\" Copyright 1989 AT&T 4.\" Copyright 2024 Oxide Computer Company 5.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License. 6.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License. 7.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner] 8.Dd September 15, 2024 9.Dt TASKQ 9F 10.Os 11.Sh NAME 12.Nm taskq , 13.Nm ddi_taskq_create , 14.Nm ddi_taskq_destroy , 15.Nm ddi_taskq_dispatch , 16.Nm ddi_taskq_wait , 17.Nm ddi_taskq_suspend , 18.Nm ddi_taskq_suspended , 19.Nm ddi_taskq_resume 20.Nd Kernel task queue operations 21.Sh SYNOPSIS 22.In sys/sunddi.h 23.Ft "ddi_taskq_t *" 24.Fo ddi_taskq_create 25.Fa "dev_info_t *dip" 26.Fa "const char *name 27.Fa "int nthreads" 28.Fa "pri_t pri" 29.Fa "uint_t cflags" 30.Fc 31.Ft void 32.Fo ddi_taskq_destroy 33.Fa "ddi_taskq_t *tq" 34.Fc 35.Ft int 36.Fo ddi_taskq_dispatch 37.Fa "ddi_taskq_t *tq" 38.Fa "void (*func)(void *)" 39.Fa "void *arg" 40.Fa "uint_t dflags" 41.Fc 42.Ft void 43.Fo ddi_taskq_wait 44.Fa "ddi_taskq_t *tq" 45.Fc 46.Ft void 47.Fo ddi_taskq_suspend 48.Fa "ddi_taskq_t *tq" 49.Fc 50.Ft boolean_t 51.Fo ddi_taskq_suspended 52.Fa "ddi_taskq_t *tq" 53.Fc 54.Ft void 55.Fo ddi_taskq_resume 56.Fa "ddi_taskq_t *tq" 57.Fc 58.Sh INTERFACE LEVEL 59illumos DDI specific (illumos DDI) 60.Bl -tag -width Fa 61.It Fa dip 62Pointer to the device's dev_info structure. 63May be 64.Dv NULL 65for kernel modules that do not have an associated 66.Ft dev_info_t 67structure. 68.It Fa name 69Descriptive string. 70Only alphanumeric characters can be used in 71.Fa name 72and spaces are not allowed. 73The name should be unique. 74If the created task queue is per-device driver instance then the 75instance number should be included to aid in identification and 76uniqueness. 77.It Fa nthreads 78Number of threads servicing the task queue. 79Note that the request ordering is guaranteed 80.Pq tasks are processed in the order scheduled 81if the taskq is created with a single servicing thread. 82.It Fa pri 83Priority of threads servicing the task queue. 84Drivers and modules should specify 85.Dv TASKQ_DEFAULTPRI . 86.It Fa cflags 87Must be 0. 88.It Fa func 89Callback function to call. 90.It Fa arg 91Argument to the callback function. 92.It dflags 93Possible 94.Fa dflags 95are: 96.Bl -tag -width Ds 97.It Dv DDI_SLEEP 98Allow sleeping 99.Pq blocking 100until memory is available. 101.It Dv DDI_NOSLEEP 102Return 103.Dv DDI_FAILURE 104immediately if memory is not available. 105.El 106.It tq 107Pointer to a task queue 108.Pq Ft ddi_taskq_t * . 109.El 110.Sh DESCRIPTION 111A kernel task queue is a mechanism for general-purpose asynchronous task 112scheduling that enables tasks to be performed at a later time by another 113thread. 114There are several reasons why you may utilize asynchronous task scheduling: 115.Bl -enum 116.It 117You have a task that isn't time-critical, but a current code path that is. 118.It 119You have a task that may require grabbing locks that a thread already holds. 120.It 121You have a task that needs to block 122Pq for example, to wait for memory , 123but you have a thread that cannot block in its current context. 124.It 125You have a code path that can't complete because of a specific condition, 126but also can't sleep or fail. 127In this case, the task is immediately queued and then is executed after the 128condition disappears. 129.It 130A task queue is just a simple way to launch multiple tasks in parallel. 131.El 132.Pp 133A task queue consists of a list of tasks, together with one or more threads to 134service the list. 135If a task queue has a single service thread, all tasks are guaranteed to execute 136in the order they were dispatched. 137Otherwise they can be executed in any order. 138Note that since tasks are placed on a list, execution of one task should not 139depend on the execution of another task or a deadlock may occur. 140.Pp 141The 142.Fn ddi_taskq_create 143function creates a task queue instance. 144.Pp 145The 146.Fn ddi_taskq_dispatch 147function places 148.Fa func 149on the list for later execution. 150The 151.Fa dflag 152argument specifies whether it is allowed to sleep waiting for memory. 153.Dv DDI_SLEEP 154dispatches can sleep and are guaranteed to succeed. 155.Dv DDI_NOSLEEP 156dispatches are guaranteed not to sleep but may fail 157.Po 158return 159.Dv DDI_FAILURE 160.Pc 161if resources are not available. 162.Pp 163The 164.Fn ddi_taskq_destroy 165function waits for any scheduled tasks to complete, then destroys the taskq 166.Fa tq . 167The caller should guarantee that no new tasks are scheduled for the closing 168taskq. 169.Pp 170The 171.Fn ddi_taskq_wait 172function waits for all previously scheduled tasks to complete. 173Note that this function does not stop any new task dispatches. 174.Pp 175The 176.Fn ddi_taskq_suspend 177function suspends all task execution until 178.Fn ddi_taskq_resume 179is called. 180Although 181.Fn ddi_taskq_suspend 182attempts to suspend pending tasks, there are no guarantees that they will be 183suspended. 184The only guarantee is that all tasks dispatched after 185.Fn ddi_taskq_suspend 186will not be executed. 187Because it will trigger a deadlock, the 188.Fn ddi_taskq_suspend 189function should never be called by a task executing on a taskq. 190.Pp 191The 192.Fn ddi_taskq_suspended 193function returns 194.Dv B_TRUE 195if the taskq 196.Fa tq 197is suspended, and 198.Dv B_FALSE 199otherwise. 200It is intended to ASSERT that the task queue is suspended. 201.Pp 202The 203.Fn ddi_taskq_resume 204function resumes task queue execution. 205.Sh CONTEXT 206All functions may be called from the user or kernel contexts. 207.Pp 208Additionally, the 209.Fn ddi_taskq_dispatch 210function may be called from the interrupt context only if the 211.Dv DDI_NOSLEEP 212flag is set. 213.Sh RETURN VALUES 214The 215.Fn ddi_taskq_create 216function creates an opaque handle that is used for all other taskq operations. 217It returns a 218.Ft "ddi_taskq_t *" 219pointer on success and 220.Dv NULL 221on failure. 222.Pp 223The 224.Fn ddi_taskq_dispatch 225function returns 226.Dv DDI_FAILURE 227if it can't dispatch a task and returns 228.Dv DDI_SUCCESS 229if dispatch succeeded. 230.Pp 231The 232.Fn ddi_taskq_suspended 233function returns 234.Dv B_TRUE 235if 236.Fa tq 237is suspended. 238Otherwise 239.Dv B_FALSE 240is returned. 241