xref: /dragonfly/sys/dev/drm/include/linux/workqueue.h (revision c9c5aa9e)
1 /*
2  * Copyright (c) 2010 Isilon Systems, Inc.
3  * Copyright (c) 2010 iX Systems, Inc.
4  * Copyright (c) 2010 Panasas, Inc.
5  * Copyright (c) 2013, 2014 Mellanox Technologies, Ltd.
6  * Copyright (c) 2014-2020 François Tigeot <ftigeot@wolfpond.org>
7  * All rights reserved.
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 unmodified, this list of conditions, and the following
14  *    disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 #ifndef	_LINUX_WORKQUEUE_H_
31 #define	_LINUX_WORKQUEUE_H_
32 
33 #include <linux/timer.h>
34 #include <linux/bitops.h>
35 #include <linux/lockdep.h>
36 #include <linux/atomic.h>
37 #include <linux/cpumask.h>
38 
39 #define WQ_HIGHPRI	1
40 #define WQ_UNBOUND	2
41 
42 struct workqueue_worker;
43 
44 struct work_struct {
45 	STAILQ_ENTRY(work_struct) ws_entries;
46 	void	(*func)(struct work_struct *);
47 	struct workqueue_worker *worker;
48 	bool	on_queue;
49 	bool	running;
50 	bool	canceled;
51 };
52 
53 struct workqueue_worker {
54 	STAILQ_HEAD(ws_list, work_struct) ws_list_head;
55 	struct thread *worker_thread;
56 	struct lock worker_lock;
57 };
58 
59 struct workqueue_struct {
60 	bool	is_draining;
61 	int	num_workers;
62 	struct	workqueue_worker (*workers)[];
63 };
64 
65 struct delayed_work {
66 	struct work_struct	work;
67 	struct callout		timer;
68 };
69 
70 static inline struct delayed_work *
71 to_delayed_work(struct work_struct *work)
72 {
73 
74 	return container_of(work, struct delayed_work, work);
75 }
76 
77 #define INIT_WORK(work, _func) 		 	\
78 do {						\
79 	(work)->ws_entries.stqe_next = NULL;	\
80 	(work)->func = (_func);			\
81 	(work)->on_queue = false;		\
82 	(work)->running = false;		\
83 	(work)->canceled = false;		\
84 } while (0)
85 
86 #define INIT_WORK_ONSTACK(work, _func)	INIT_WORK(work, _func)
87 
88 #define INIT_DELAYED_WORK(_work, _func)					\
89 do {									\
90 	INIT_WORK(&(_work)->work, _func);				\
91 	callout_init_mp(&(_work)->timer);				\
92 } while (0)
93 
94 #define INIT_DELAYED_WORK_ONSTACK(work, _func)	INIT_DELAYED_WORK(work, _func)
95 
96 /* System-wide workqueues */
97 extern struct workqueue_struct *system_wq;
98 extern struct workqueue_struct *system_highpri_wq;
99 extern struct workqueue_struct *system_long_wq;
100 extern struct workqueue_struct *system_unbound_wq;
101 extern struct workqueue_struct *system_power_efficient_wq;
102 
103 #define alloc_ordered_workqueue(name, flags) \
104 	_create_workqueue_common(name, (flags) | WQ_UNBOUND)
105 
106 #define alloc_workqueue(name, flags, max_active) \
107 	_create_workqueue_common(name, flags)
108 
109 #define create_singlethread_workqueue(name) \
110 	_create_workqueue_common(name, WQ_UNBOUND)
111 
112 struct workqueue_struct *_create_workqueue_common(const char *name, int flags);
113 
114 int queue_work(struct workqueue_struct *wq, struct work_struct *work);
115 int queue_delayed_work(struct workqueue_struct *wq, struct delayed_work *work,
116     unsigned long delay);
117 
118 static inline bool
119 schedule_work(struct work_struct *work)
120 {
121 	return queue_work(system_wq, work);
122 }
123 
124 static inline bool schedule_delayed_work(struct delayed_work *dwork,
125                                          unsigned long delay)
126 {
127         return queue_delayed_work(system_wq, dwork, delay);
128 }
129 
130 bool cancel_work_sync(struct work_struct *work);
131 bool cancel_delayed_work(struct delayed_work *dwork);
132 bool cancel_delayed_work_sync(struct delayed_work *dwork);
133 
134 /* XXX: Return value not used in drm code */
135 static inline bool
136 mod_delayed_work(struct workqueue_struct *wq,
137 		 struct delayed_work *dwork, unsigned long delay)
138 {
139 	cancel_delayed_work(dwork);
140 	queue_delayed_work(wq, dwork, delay);
141 	return false;
142 }
143 
144 void drain_workqueue(struct workqueue_struct *wq);
145 void flush_workqueue(struct workqueue_struct *wq);
146 
147 bool flush_work(struct work_struct *work);
148 bool flush_delayed_work(struct delayed_work *dwork);
149 
150 static inline void
151 flush_scheduled_work(void)
152 {
153 	flush_workqueue(system_wq);
154 }
155 
156 unsigned int work_busy(struct work_struct *work);
157 bool work_pending(struct work_struct *work);
158 
159 bool delayed_work_pending(struct delayed_work *dw);
160 
161 void destroy_workqueue(struct workqueue_struct *wq);
162 
163 void destroy_work_on_stack(struct work_struct *work);
164 
165 void destroy_delayed_work_on_stack(struct delayed_work *work);
166 
167 #endif	/* _LINUX_WORKQUEUE_H_ */
168