diff options
-rw-r--r-- | include/linux/workqueue.h | 29 | ||||
-rw-r--r-- | kernel/workqueue.c | 12 |
2 files changed, 27 insertions, 14 deletions
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index d89cfc143b1a..d60c5701ab45 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h | |||
@@ -22,12 +22,25 @@ typedef void (*work_func_t)(struct work_struct *work); | |||
22 | */ | 22 | */ |
23 | #define work_data_bits(work) ((unsigned long *)(&(work)->data)) | 23 | #define work_data_bits(work) ((unsigned long *)(&(work)->data)) |
24 | 24 | ||
25 | enum { | ||
26 | WORK_STRUCT_PENDING_BIT = 0, /* work item is pending execution */ | ||
27 | #ifdef CONFIG_DEBUG_OBJECTS_WORK | ||
28 | WORK_STRUCT_STATIC_BIT = 1, /* static initializer (debugobjects) */ | ||
29 | #endif | ||
30 | |||
31 | WORK_STRUCT_PENDING = 1 << WORK_STRUCT_PENDING_BIT, | ||
32 | #ifdef CONFIG_DEBUG_OBJECTS_WORK | ||
33 | WORK_STRUCT_STATIC = 1 << WORK_STRUCT_STATIC_BIT, | ||
34 | #else | ||
35 | WORK_STRUCT_STATIC = 0, | ||
36 | #endif | ||
37 | |||
38 | WORK_STRUCT_FLAG_MASK = 3UL, | ||
39 | WORK_STRUCT_WQ_DATA_MASK = ~WORK_STRUCT_FLAG_MASK, | ||
40 | }; | ||
41 | |||
25 | struct work_struct { | 42 | struct work_struct { |
26 | atomic_long_t data; | 43 | atomic_long_t data; |
27 | #define WORK_STRUCT_PENDING 0 /* T if work item pending execution */ | ||
28 | #define WORK_STRUCT_STATIC 1 /* static initializer (debugobjects) */ | ||
29 | #define WORK_STRUCT_FLAG_MASK (3UL) | ||
30 | #define WORK_STRUCT_WQ_DATA_MASK (~WORK_STRUCT_FLAG_MASK) | ||
31 | struct list_head entry; | 44 | struct list_head entry; |
32 | work_func_t func; | 45 | work_func_t func; |
33 | #ifdef CONFIG_LOCKDEP | 46 | #ifdef CONFIG_LOCKDEP |
@@ -36,7 +49,7 @@ struct work_struct { | |||
36 | }; | 49 | }; |
37 | 50 | ||
38 | #define WORK_DATA_INIT() ATOMIC_LONG_INIT(0) | 51 | #define WORK_DATA_INIT() ATOMIC_LONG_INIT(0) |
39 | #define WORK_DATA_STATIC_INIT() ATOMIC_LONG_INIT(2) | 52 | #define WORK_DATA_STATIC_INIT() ATOMIC_LONG_INIT(WORK_STRUCT_STATIC) |
40 | 53 | ||
41 | struct delayed_work { | 54 | struct delayed_work { |
42 | struct work_struct work; | 55 | struct work_struct work; |
@@ -98,7 +111,7 @@ extern void __init_work(struct work_struct *work, int onstack); | |||
98 | extern void destroy_work_on_stack(struct work_struct *work); | 111 | extern void destroy_work_on_stack(struct work_struct *work); |
99 | static inline unsigned int work_static(struct work_struct *work) | 112 | static inline unsigned int work_static(struct work_struct *work) |
100 | { | 113 | { |
101 | return *work_data_bits(work) & (1 << WORK_STRUCT_STATIC); | 114 | return *work_data_bits(work) & WORK_STRUCT_STATIC; |
102 | } | 115 | } |
103 | #else | 116 | #else |
104 | static inline void __init_work(struct work_struct *work, int onstack) { } | 117 | static inline void __init_work(struct work_struct *work, int onstack) { } |
@@ -167,7 +180,7 @@ static inline unsigned int work_static(struct work_struct *work) { return 0; } | |||
167 | * @work: The work item in question | 180 | * @work: The work item in question |
168 | */ | 181 | */ |
169 | #define work_pending(work) \ | 182 | #define work_pending(work) \ |
170 | test_bit(WORK_STRUCT_PENDING, work_data_bits(work)) | 183 | test_bit(WORK_STRUCT_PENDING_BIT, work_data_bits(work)) |
171 | 184 | ||
172 | /** | 185 | /** |
173 | * delayed_work_pending - Find out whether a delayable work item is currently | 186 | * delayed_work_pending - Find out whether a delayable work item is currently |
@@ -182,7 +195,7 @@ static inline unsigned int work_static(struct work_struct *work) { return 0; } | |||
182 | * @work: The work item in question | 195 | * @work: The work item in question |
183 | */ | 196 | */ |
184 | #define work_clear_pending(work) \ | 197 | #define work_clear_pending(work) \ |
185 | clear_bit(WORK_STRUCT_PENDING, work_data_bits(work)) | 198 | clear_bit(WORK_STRUCT_PENDING_BIT, work_data_bits(work)) |
186 | 199 | ||
187 | enum { | 200 | enum { |
188 | WQ_FREEZEABLE = 1 << 0, /* freeze during suspend */ | 201 | WQ_FREEZEABLE = 1 << 0, /* freeze during suspend */ |
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 68e4dd808ec0..5c49d762293b 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c | |||
@@ -115,7 +115,7 @@ static int work_fixup_activate(void *addr, enum debug_obj_state state) | |||
115 | * statically initialized. We just make sure that it | 115 | * statically initialized. We just make sure that it |
116 | * is tracked in the object tracker. | 116 | * is tracked in the object tracker. |
117 | */ | 117 | */ |
118 | if (test_bit(WORK_STRUCT_STATIC, work_data_bits(work))) { | 118 | if (test_bit(WORK_STRUCT_STATIC_BIT, work_data_bits(work))) { |
119 | debug_object_init(work, &work_debug_descr); | 119 | debug_object_init(work, &work_debug_descr); |
120 | debug_object_activate(work, &work_debug_descr); | 120 | debug_object_activate(work, &work_debug_descr); |
121 | return 0; | 121 | return 0; |
@@ -232,7 +232,7 @@ static inline void set_wq_data(struct work_struct *work, | |||
232 | BUG_ON(!work_pending(work)); | 232 | BUG_ON(!work_pending(work)); |
233 | 233 | ||
234 | atomic_long_set(&work->data, (unsigned long)cwq | work_static(work) | | 234 | atomic_long_set(&work->data, (unsigned long)cwq | work_static(work) | |
235 | (1UL << WORK_STRUCT_PENDING) | extra_flags); | 235 | WORK_STRUCT_PENDING | extra_flags); |
236 | } | 236 | } |
237 | 237 | ||
238 | /* | 238 | /* |
@@ -330,7 +330,7 @@ queue_work_on(int cpu, struct workqueue_struct *wq, struct work_struct *work) | |||
330 | { | 330 | { |
331 | int ret = 0; | 331 | int ret = 0; |
332 | 332 | ||
333 | if (!test_and_set_bit(WORK_STRUCT_PENDING, work_data_bits(work))) { | 333 | if (!test_and_set_bit(WORK_STRUCT_PENDING_BIT, work_data_bits(work))) { |
334 | __queue_work(cpu, wq, work); | 334 | __queue_work(cpu, wq, work); |
335 | ret = 1; | 335 | ret = 1; |
336 | } | 336 | } |
@@ -380,7 +380,7 @@ int queue_delayed_work_on(int cpu, struct workqueue_struct *wq, | |||
380 | struct timer_list *timer = &dwork->timer; | 380 | struct timer_list *timer = &dwork->timer; |
381 | struct work_struct *work = &dwork->work; | 381 | struct work_struct *work = &dwork->work; |
382 | 382 | ||
383 | if (!test_and_set_bit(WORK_STRUCT_PENDING, work_data_bits(work))) { | 383 | if (!test_and_set_bit(WORK_STRUCT_PENDING_BIT, work_data_bits(work))) { |
384 | BUG_ON(timer_pending(timer)); | 384 | BUG_ON(timer_pending(timer)); |
385 | BUG_ON(!list_empty(&work->entry)); | 385 | BUG_ON(!list_empty(&work->entry)); |
386 | 386 | ||
@@ -516,7 +516,7 @@ static void insert_wq_barrier(struct cpu_workqueue_struct *cwq, | |||
516 | * might deadlock. | 516 | * might deadlock. |
517 | */ | 517 | */ |
518 | INIT_WORK_ON_STACK(&barr->work, wq_barrier_func); | 518 | INIT_WORK_ON_STACK(&barr->work, wq_barrier_func); |
519 | __set_bit(WORK_STRUCT_PENDING, work_data_bits(&barr->work)); | 519 | __set_bit(WORK_STRUCT_PENDING_BIT, work_data_bits(&barr->work)); |
520 | init_completion(&barr->done); | 520 | init_completion(&barr->done); |
521 | 521 | ||
522 | debug_work_activate(&barr->work); | 522 | debug_work_activate(&barr->work); |
@@ -628,7 +628,7 @@ static int try_to_grab_pending(struct work_struct *work) | |||
628 | struct cpu_workqueue_struct *cwq; | 628 | struct cpu_workqueue_struct *cwq; |
629 | int ret = -1; | 629 | int ret = -1; |
630 | 630 | ||
631 | if (!test_and_set_bit(WORK_STRUCT_PENDING, work_data_bits(work))) | 631 | if (!test_and_set_bit(WORK_STRUCT_PENDING_BIT, work_data_bits(work))) |
632 | return 0; | 632 | return 0; |
633 | 633 | ||
634 | /* | 634 | /* |