aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/workqueue.c21
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 */
88static inline void set_wq_data(struct work_struct *work, void *wq) 92static 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
106static inline void *get_wq_data(struct work_struct *work) 103static inline void *get_wq_data(struct work_struct *work)