diff options
-rw-r--r-- | include/linux/workqueue.h | 25 | ||||
-rw-r--r-- | kernel/workqueue.c | 17 |
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 | ||
187 | enum { | ||
188 | WQ_FREEZEABLE = 1 << 0, /* freeze during suspend */ | ||
189 | WQ_SINGLE_THREAD = 1 << 1, /* no per-cpu worker */ | ||
190 | }; | ||
187 | 191 | ||
188 | extern struct workqueue_struct * | 192 | extern 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 | ||
217 | extern void destroy_workqueue(struct workqueue_struct *wq); | 222 | extern 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 | */ |
69 | struct workqueue_struct { | 69 | struct 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; | |||
203 | static cpumask_var_t cpu_populated_map __read_mostly; | 202 | static 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. */ |
206 | static inline int is_wq_single_threaded(struct workqueue_struct *wq) | 205 | static 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 | ||
211 | static const struct cpumask *wq_cpu_map(struct workqueue_struct *wq) | 210 | static 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 | ||
1015 | struct workqueue_struct *__create_workqueue_key(const char *name, | 1014 | struct 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); |