aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/workqueue.h25
-rw-r--r--kernel/workqueue.c17
2 files changed, 22 insertions, 20 deletions
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h
index e724dafc9e6d..d89cfc143b1a 100644
--- a/include/linux/workqueue.h
+++ b/include/linux/workqueue.h
@@ -184,13 +184,17 @@ static inline unsigned int work_static(struct work_struct *work) { return 0; }
184#define work_clear_pending(work) \ 184#define work_clear_pending(work) \
185 clear_bit(WORK_STRUCT_PENDING, work_data_bits(work)) 185 clear_bit(WORK_STRUCT_PENDING, work_data_bits(work))
186 186
187enum {
188 WQ_FREEZEABLE = 1 << 0, /* freeze during suspend */
189 WQ_SINGLE_THREAD = 1 << 1, /* no per-cpu worker */
190};
187 191
188extern struct workqueue_struct * 192extern struct workqueue_struct *
189__create_workqueue_key(const char *name, int singlethread, int freezeable, 193__create_workqueue_key(const char *name, unsigned int flags,
190 struct lock_class_key *key, const char *lock_name); 194 struct lock_class_key *key, const char *lock_name);
191 195
192#ifdef CONFIG_LOCKDEP 196#ifdef CONFIG_LOCKDEP
193#define __create_workqueue(name, singlethread, freezeable) \ 197#define __create_workqueue(name, flags) \
194({ \ 198({ \
195 static struct lock_class_key __key; \ 199 static struct lock_class_key __key; \
196 const char *__lock_name; \ 200 const char *__lock_name; \
@@ -200,19 +204,20 @@ __create_workqueue_key(const char *name, int singlethread, int freezeable,
200 else \ 204 else \
201 __lock_name = #name; \ 205 __lock_name = #name; \
202 \ 206 \
203 __create_workqueue_key((name), (singlethread), \ 207 __create_workqueue_key((name), (flags), &__key, \
204 (freezeable), &__key, \
205 __lock_name); \ 208 __lock_name); \
206}) 209})
207#else 210#else
208#define __create_workqueue(name, singlethread, freezeable) \ 211#define __create_workqueue(name, flags) \
209 __create_workqueue_key((name), (singlethread), (freezeable), \ 212 __create_workqueue_key((name), (flags), NULL, NULL)
210 NULL, NULL)
211#endif 213#endif
212 214
213#define create_workqueue(name) __create_workqueue((name), 0, 0) 215#define create_workqueue(name) \
214#define create_freezeable_workqueue(name) __create_workqueue((name), 1, 1) 216 __create_workqueue((name), 0)
215#define create_singlethread_workqueue(name) __create_workqueue((name), 1, 0) 217#define create_freezeable_workqueue(name) \
218 __create_workqueue((name), WQ_FREEZEABLE | WQ_SINGLE_THREAD)
219#define create_singlethread_workqueue(name) \
220 __create_workqueue((name), WQ_SINGLE_THREAD)
216 221
217extern void destroy_workqueue(struct workqueue_struct *wq); 222extern void destroy_workqueue(struct workqueue_struct *wq);
218 223
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index c56146a755e5..68e4dd808ec0 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -67,11 +67,10 @@ struct cpu_workqueue_struct {
67 * per-CPU workqueues: 67 * per-CPU workqueues:
68 */ 68 */
69struct workqueue_struct { 69struct workqueue_struct {
70 unsigned int flags; /* I: WQ_* flags */
70 struct cpu_workqueue_struct *cpu_wq; /* I: cwq's */ 71 struct cpu_workqueue_struct *cpu_wq; /* I: cwq's */
71 struct list_head list; /* W: list of all workqueues */ 72 struct list_head list; /* W: list of all workqueues */
72 const char *name; /* I: workqueue name */ 73 const char *name; /* I: workqueue name */
73 int singlethread;
74 int freezeable; /* Freeze threads during suspend */
75#ifdef CONFIG_LOCKDEP 74#ifdef CONFIG_LOCKDEP
76 struct lockdep_map lockdep_map; 75 struct lockdep_map lockdep_map;
77#endif 76#endif
@@ -203,9 +202,9 @@ static const struct cpumask *cpu_singlethread_map __read_mostly;
203static cpumask_var_t cpu_populated_map __read_mostly; 202static cpumask_var_t cpu_populated_map __read_mostly;
204 203
205/* If it's single threaded, it isn't in the list of workqueues. */ 204/* If it's single threaded, it isn't in the list of workqueues. */
206static inline int is_wq_single_threaded(struct workqueue_struct *wq) 205static inline bool is_wq_single_threaded(struct workqueue_struct *wq)
207{ 206{
208 return wq->singlethread; 207 return wq->flags & WQ_SINGLE_THREAD;
209} 208}
210 209
211static const struct cpumask *wq_cpu_map(struct workqueue_struct *wq) 210static const struct cpumask *wq_cpu_map(struct workqueue_struct *wq)
@@ -463,7 +462,7 @@ static int worker_thread(void *__cwq)
463 struct cpu_workqueue_struct *cwq = __cwq; 462 struct cpu_workqueue_struct *cwq = __cwq;
464 DEFINE_WAIT(wait); 463 DEFINE_WAIT(wait);
465 464
466 if (cwq->wq->freezeable) 465 if (cwq->wq->flags & WQ_FREEZEABLE)
467 set_freezable(); 466 set_freezable();
468 467
469 for (;;) { 468 for (;;) {
@@ -1013,8 +1012,7 @@ static void start_workqueue_thread(struct cpu_workqueue_struct *cwq, int cpu)
1013} 1012}
1014 1013
1015struct workqueue_struct *__create_workqueue_key(const char *name, 1014struct workqueue_struct *__create_workqueue_key(const char *name,
1016 int singlethread, 1015 unsigned int flags,
1017 int freezeable,
1018 struct lock_class_key *key, 1016 struct lock_class_key *key,
1019 const char *lock_name) 1017 const char *lock_name)
1020{ 1018{
@@ -1030,13 +1028,12 @@ struct workqueue_struct *__create_workqueue_key(const char *name,
1030 if (!wq->cpu_wq) 1028 if (!wq->cpu_wq)
1031 goto err; 1029 goto err;
1032 1030
1031 wq->flags = flags;
1033 wq->name = name; 1032 wq->name = name;
1034 lockdep_init_map(&wq->lockdep_map, lock_name, key, 0); 1033 lockdep_init_map(&wq->lockdep_map, lock_name, key, 0);
1035 wq->singlethread = singlethread;
1036 wq->freezeable = freezeable;
1037 INIT_LIST_HEAD(&wq->list); 1034 INIT_LIST_HEAD(&wq->list);
1038 1035
1039 if (singlethread) { 1036 if (flags & WQ_SINGLE_THREAD) {
1040 cwq = init_cpu_workqueue(wq, singlethread_cpu); 1037 cwq = init_cpu_workqueue(wq, singlethread_cpu);
1041 err = create_workqueue_thread(cwq, singlethread_cpu); 1038 err = create_workqueue_thread(cwq, singlethread_cpu);
1042 start_workqueue_thread(cwq, -1); 1039 start_workqueue_thread(cwq, -1);