]> git.proxmox.com Git - mirror_zfs.git/blame - include/os/linux/spl/sys/taskq.h
Linux: Cleanup taskq threads spawn/exit
[mirror_zfs.git] / include / os / linux / spl / sys / taskq.h
CommitLineData
2c4332cf 1/*
716154c5
BB
2 * Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
3 * Copyright (C) 2007 The Regents of the University of California.
4 * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
5 * Written by Brian Behlendorf <behlendorf1@llnl.gov>.
715f6251
BB
6 * UCRL-CODE-235197
7 *
716154c5 8 * This file is part of the SPL, Solaris Porting Layer.
716154c5
BB
9 *
10 * The SPL is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
715f6251 14 *
716154c5 15 * The SPL is distributed in the hope that it will be useful, but WITHOUT
715f6251
BB
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 * for more details.
19 *
20 * You should have received a copy of the GNU General Public License along
716154c5 21 * with the SPL. If not, see <http://www.gnu.org/licenses/>.
2c4332cf 22 */
715f6251 23
09b414e8 24#ifndef _SPL_TASKQ_H
2c4332cf 25#define _SPL_TASKQ_H
f1ca4da6 26
f1b59d26 27#include <linux/module.h>
f1ca4da6
BB
28#include <linux/gfp.h>
29#include <linux/slab.h>
30#include <linux/interrupt.h>
bcd68186 31#include <linux/kthread.h>
f4b37741 32#include <sys/types.h>
925ca8cc 33#include <sys/thread.h>
200366f2 34#include <sys/rwlock.h>
a9125891 35#include <sys/wait.h>
f1ca4da6 36
2c4332cf 37#define TASKQ_NAMELEN 31
f1ca4da6 38
2c4332cf
BB
39#define TASKQ_PREPOPULATE 0x00000001
40#define TASKQ_CPR_SAFE 0x00000002
41#define TASKQ_DYNAMIC 0x00000004
42#define TASKQ_THREADS_CPU_PCT 0x00000008
43#define TASKQ_DC_BATCH 0x00000010
44#define TASKQ_ACTIVE 0x80000000
f1ca4da6 45
f1ca4da6
BB
46/*
47 * Flags for taskq_dispatch. TQ_SLEEP/TQ_NOSLEEP should be same as
bcd68186
BB
48 * KM_SLEEP/KM_NOSLEEP. TQ_NOQUEUE/TQ_NOALLOC are set particularly
49 * large so as not to conflict with already used GFP_* defines.
f1ca4da6 50 */
2c4332cf
BB
51#define TQ_SLEEP 0x00000000
52#define TQ_NOSLEEP 0x00000001
53#define TQ_PUSHPAGE 0x00000002
54#define TQ_NOQUEUE 0x01000000
55#define TQ_NOALLOC 0x02000000
56#define TQ_NEW 0x04000000
57#define TQ_FRONT 0x08000000
58
cbba7146
BB
59/*
60 * Reserved taskqid values.
61 */
62#define TASKQID_INVALID ((taskqid_t)0)
63#define TASKQID_INITIAL ((taskqid_t)1)
64
2c4332cf
BB
65/*
66 * spin_lock(lock) and spin_lock_nested(lock,0) are equivalent,
326172d8
OF
67 * so TQ_LOCK_DYNAMIC must not evaluate to 0
68 */
69typedef enum tq_lock_role {
70 TQ_LOCK_GENERAL = 0,
71 TQ_LOCK_DYNAMIC = 1,
72} tq_lock_role_t;
73
d9acd930
BB
74typedef unsigned long taskqid_t;
75typedef void (task_func_t)(void *);
76
bcd68186 77typedef struct taskq {
2c4332cf
BB
78 spinlock_t tq_lock; /* protects taskq_t */
79 char *tq_name; /* taskq name */
200366f2 80 int tq_instance; /* instance of tq_name */
2c4332cf
BB
81 struct list_head tq_thread_list; /* list of all threads */
82 struct list_head tq_active_list; /* list of active threads */
83 int tq_nactive; /* # of active threads */
84 int tq_nthreads; /* # of existing threads */
85 int tq_nspawn; /* # of threads being spawned */
86 int tq_maxthreads; /* # of threads maximum */
60a4c7d2
PD
87 /* If PERCPU flag is set, percent of NCPUs to have as threads */
88 int tq_cpu_pct;
2c4332cf 89 int tq_pri; /* priority */
200366f2
TC
90 int tq_minalloc; /* min taskq_ent_t pool size */
91 int tq_maxalloc; /* max taskq_ent_t pool size */
92 int tq_nalloc; /* cur taskq_ent_t pool size */
2c4332cf
BB
93 uint_t tq_flags; /* flags */
94 taskqid_t tq_next_id; /* next pend/work id */
95 taskqid_t tq_lowest_id; /* lowest pend/work id */
200366f2
TC
96 struct list_head tq_free_list; /* free taskq_ent_t's */
97 struct list_head tq_pend_list; /* pending taskq_ent_t's */
5461eefe 98 struct list_head tq_prio_list; /* priority taskq_ent_t's */
200366f2
TC
99 struct list_head tq_delay_list; /* delayed taskq_ent_t's */
100 struct list_head tq_taskqs; /* all taskq_t's */
94411751
BB
101 spl_wait_queue_head_t tq_work_waitq; /* new work waitq */
102 spl_wait_queue_head_t tq_wait_waitq; /* wait waitq */
2c4332cf 103 tq_lock_role_t tq_lock_class; /* class when taking tq_lock */
60a4c7d2
PD
104 /* list node for the cpu hotplug callback */
105 struct hlist_node tq_hp_cb_node;
106 boolean_t tq_hp_support;
e0bd8118 107 unsigned long lastspawnstop; /* when to purge dynamic */
bcd68186 108} taskq_t;
f1ca4da6 109
d9acd930
BB
110typedef struct taskq_ent {
111 spinlock_t tqent_lock;
94411751 112 spl_wait_queue_head_t tqent_waitq;
d9acd930
BB
113 struct timer_list tqent_timer;
114 struct list_head tqent_list;
115 taskqid_t tqent_id;
116 task_func_t *tqent_func;
117 void *tqent_arg;
118 taskq_t *tqent_taskq;
119 uintptr_t tqent_flags;
8f3b403a 120 unsigned long tqent_birth;
d9acd930
BB
121} taskq_ent_t;
122
2c4332cf
BB
123#define TQENT_FLAG_PREALLOC 0x1
124#define TQENT_FLAG_CANCEL 0x2
d9acd930 125
2c02b71b 126typedef struct taskq_thread {
472a34ca
BB
127 struct list_head tqt_thread_list;
128 struct list_head tqt_active_list;
129 struct task_struct *tqt_thread;
130 taskq_t *tqt_tq;
131 taskqid_t tqt_id;
d9acd930 132 taskq_ent_t *tqt_task;
472a34ca 133 uintptr_t tqt_flags;
2c02b71b
PS
134} taskq_thread_t;
135
e9cb2b4f
BB
136/* Global system-wide dynamic task queue available for all consumers */
137extern taskq_t *system_taskq;
f200b836
CC
138/* Global dynamic task queue for long delay */
139extern taskq_t *system_delay_taskq;
e9cb2b4f 140
200366f2
TC
141/* List of all taskqs */
142extern struct list_head tq_list;
143extern struct rw_semaphore tq_list_sem;
144
aed8671c 145extern taskqid_t taskq_dispatch(taskq_t *, task_func_t, void *, uint_t);
d9acd930
BB
146extern taskqid_t taskq_dispatch_delay(taskq_t *, task_func_t, void *,
147 uint_t, clock_t);
aed8671c
BB
148extern void taskq_dispatch_ent(taskq_t *, task_func_t, void *, uint_t,
149 taskq_ent_t *);
150extern int taskq_empty_ent(taskq_ent_t *);
151extern void taskq_init_ent(taskq_ent_t *);
152extern taskq_t *taskq_create(const char *, int, pri_t, int, int, uint_t);
3bd4df38
EN
153extern taskq_t *taskq_create_synced(const char *, int, pri_t, int, int, uint_t,
154 kthread_t ***);
aed8671c
BB
155extern void taskq_destroy(taskq_t *);
156extern void taskq_wait_id(taskq_t *, taskqid_t);
a876b030 157extern void taskq_wait_outstanding(taskq_t *, taskqid_t);
aed8671c 158extern void taskq_wait(taskq_t *);
d9acd930 159extern int taskq_cancel_id(taskq_t *, taskqid_t);
16522ac2 160extern int taskq_member(taskq_t *, kthread_t *);
b3212d2f 161extern taskq_t *taskq_of_curthread(void);
aed8671c 162
2c4332cf 163#define taskq_create_proc(name, nthreads, pri, min, max, proc, flags) \
aed8671c 164 taskq_create(name, nthreads, pri, min, max, flags)
2c4332cf 165#define taskq_create_sysdc(name, nthreads, min, max, proc, dc, flags) \
18168da7
AZ
166 ((void) sizeof (dc), \
167 taskq_create(name, nthreads, maxclsyspri, min, max, flags))
bcd68186 168
e9cb2b4f
BB
169int spl_taskq_init(void);
170void spl_taskq_fini(void);
171
09b414e8 172#endif /* _SPL_TASKQ_H */