aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2013-02-13 22:29:10 -0500
committerTejun Heo <tj@kernel.org>2013-02-13 22:29:10 -0500
commit8d03ecfe471802d6afe97da97722b6924533aa82 (patch)
tree1178cacfdd36358665f9a4c6325329346b221dd0
parent1dd638149f1f9d7d7dbb32591d5c7c2a0ea36264 (diff)
workqueue: reimplement is_chained_work() using current_wq_worker()
is_chained_work() was added before current_wq_worker() and implemented its own ham-fisted way of finding out whether %current is a workqueue worker - it iterates through all possible workers. Drop the custom implementation and reimplement using current_wq_worker(). Signed-off-by: Tejun Heo <tj@kernel.org>
-rw-r--r--kernel/workqueue.c33
1 files changed, 8 insertions, 25 deletions
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 0d26ab3aee59..ea7f696f1060 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -1159,35 +1159,18 @@ static void insert_work(struct cpu_workqueue_struct *cwq,
1159 1159
1160/* 1160/*
1161 * Test whether @work is being queued from another work executing on the 1161 * Test whether @work is being queued from another work executing on the
1162 * same workqueue. This is rather expensive and should only be used from 1162 * same workqueue.
1163 * cold paths.
1164 */ 1163 */
1165static bool is_chained_work(struct workqueue_struct *wq) 1164static bool is_chained_work(struct workqueue_struct *wq)
1166{ 1165{
1167 unsigned long flags; 1166 struct worker *worker;
1168 unsigned int cpu;
1169
1170 for_each_cwq_cpu(cpu, wq) {
1171 struct cpu_workqueue_struct *cwq = get_cwq(cpu, wq);
1172 struct worker_pool *pool = cwq->pool;
1173 struct worker *worker;
1174 struct hlist_node *pos;
1175 int i;
1176 1167
1177 spin_lock_irqsave(&pool->lock, flags); 1168 worker = current_wq_worker();
1178 for_each_busy_worker(worker, i, pos, pool) { 1169 /*
1179 if (worker->task != current) 1170 * Return %true iff I'm a worker execuing a work item on @wq. If
1180 continue; 1171 * I'm @worker, it's safe to dereference it without locking.
1181 spin_unlock_irqrestore(&pool->lock, flags); 1172 */
1182 /* 1173 return worker && worker->current_cwq->wq == wq;
1183 * I'm @worker, no locking necessary. See if @work
1184 * is headed to the same workqueue.
1185 */
1186 return worker->current_cwq->wq == wq;
1187 }
1188 spin_unlock_irqrestore(&pool->lock, flags);
1189 }
1190 return false;
1191} 1174}
1192 1175
1193static void __queue_work(unsigned int cpu, struct workqueue_struct *wq, 1176static void __queue_work(unsigned int cpu, struct workqueue_struct *wq,