diff options
Diffstat (limited to 'kernel/workqueue.c')
-rw-r--r-- | kernel/workqueue.c | 21 |
1 files changed, 9 insertions, 12 deletions
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 6b186750e9be..db49886bfae1 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c | |||
@@ -85,22 +85,19 @@ static inline int is_single_threaded(struct workqueue_struct *wq) | |||
85 | return list_empty(&wq->list); | 85 | return list_empty(&wq->list); |
86 | } | 86 | } |
87 | 87 | ||
88 | /* | ||
89 | * Set the workqueue on which a work item is to be run | ||
90 | * - Must *only* be called if the pending flag is set | ||
91 | */ | ||
88 | static inline void set_wq_data(struct work_struct *work, void *wq) | 92 | static inline void set_wq_data(struct work_struct *work, void *wq) |
89 | { | 93 | { |
90 | unsigned long new, old, res; | 94 | unsigned long new; |
95 | |||
96 | BUG_ON(!work_pending(work)); | ||
91 | 97 | ||
92 | /* assume the pending flag is already set and that the task has already | ||
93 | * been queued on this workqueue */ | ||
94 | new = (unsigned long) wq | (1UL << WORK_STRUCT_PENDING); | 98 | new = (unsigned long) wq | (1UL << WORK_STRUCT_PENDING); |
95 | res = work->management; | 99 | new |= work->management & WORK_STRUCT_FLAG_MASK; |
96 | if (res != new) { | 100 | work->management = new; |
97 | do { | ||
98 | old = res; | ||
99 | new = (unsigned long) wq; | ||
100 | new |= (old & WORK_STRUCT_FLAG_MASK); | ||
101 | res = cmpxchg(&work->management, old, new); | ||
102 | } while (res != old); | ||
103 | } | ||
104 | } | 101 | } |
105 | 102 | ||
106 | static inline void *get_wq_data(struct work_struct *work) | 103 | static inline void *get_wq_data(struct work_struct *work) |