aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/workqueue.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/workqueue.c')
-rw-r--r--kernel/workqueue.c73
1 files changed, 0 insertions, 73 deletions
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index a981add58fb9..ea422254f8bf 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -98,79 +98,6 @@ static inline void *get_wq_data(struct work_struct *work)
98 return (void *) (atomic_long_read(&work->data) & WORK_STRUCT_WQ_DATA_MASK); 98 return (void *) (atomic_long_read(&work->data) & WORK_STRUCT_WQ_DATA_MASK);
99} 99}
100 100
101static int __run_work(struct cpu_workqueue_struct *cwq, struct work_struct *work)
102{
103 int ret = 0;
104 unsigned long flags;
105
106 spin_lock_irqsave(&cwq->lock, flags);
107 /*
108 * We need to re-validate the work info after we've gotten
109 * the cpu_workqueue lock. We can run the work now iff:
110 *
111 * - the wq_data still matches the cpu_workqueue_struct
112 * - AND the work is still marked pending
113 * - AND the work is still on a list (which will be this
114 * workqueue_struct list)
115 *
116 * All these conditions are important, because we
117 * need to protect against the work being run right
118 * now on another CPU (all but the last one might be
119 * true if it's currently running and has not been
120 * released yet, for example).
121 */
122 if (get_wq_data(work) == cwq
123 && work_pending(work)
124 && !list_empty(&work->entry)) {
125 work_func_t f = work->func;
126 cwq->current_work = work;
127 list_del_init(&work->entry);
128 spin_unlock_irqrestore(&cwq->lock, flags);
129
130 if (!test_bit(WORK_STRUCT_NOAUTOREL, work_data_bits(work)))
131 work_release(work);
132 f(work);
133
134 spin_lock_irqsave(&cwq->lock, flags);
135 cwq->current_work = NULL;
136 ret = 1;
137 }
138 spin_unlock_irqrestore(&cwq->lock, flags);
139 return ret;
140}
141
142/**
143 * run_scheduled_work - run scheduled work synchronously
144 * @work: work to run
145 *
146 * This checks if the work was pending, and runs it
147 * synchronously if so. It returns a boolean to indicate
148 * whether it had any scheduled work to run or not.
149 *
150 * NOTE! This _only_ works for normal work_structs. You
151 * CANNOT use this for delayed work, because the wq data
152 * for delayed work will not point properly to the per-
153 * CPU workqueue struct, but will change!
154 */
155int fastcall run_scheduled_work(struct work_struct *work)
156{
157 for (;;) {
158 struct cpu_workqueue_struct *cwq;
159
160 if (!work_pending(work))
161 return 0;
162 if (list_empty(&work->entry))
163 return 0;
164 /* NOTE! This depends intimately on __queue_work! */
165 cwq = get_wq_data(work);
166 if (!cwq)
167 return 0;
168 if (__run_work(cwq, work))
169 return 1;
170 }
171}
172EXPORT_SYMBOL(run_scheduled_work);
173
174static void insert_work(struct cpu_workqueue_struct *cwq, 101static void insert_work(struct cpu_workqueue_struct *cwq,
175 struct work_struct *work, int tail) 102 struct work_struct *work, int tail)
176{ 103{