Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

Tejun Heo 8d03ecfe 1dd63814

+8 -25
+8 -25
kernel/workqueue.c
··· 1159 1159 1160 1160 /* 1161 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 1163 - * cold paths. 1162 + * same workqueue. 1164 1163 */ 1165 1164 static bool is_chained_work(struct workqueue_struct *wq) 1166 1165 { 1167 - unsigned long flags; 1168 - unsigned int cpu; 1166 + struct worker *worker; 1169 1167 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 - 1177 - spin_lock_irqsave(&pool->lock, flags); 1178 - for_each_busy_worker(worker, i, pos, pool) { 1179 - if (worker->task != current) 1180 - continue; 1181 - spin_unlock_irqrestore(&pool->lock, flags); 1182 - /* 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; 1168 + worker = current_wq_worker(); 1169 + /* 1170 + * Return %true iff I'm a worker execuing a work item on @wq. If 1171 + * I'm @worker, it's safe to dereference it without locking. 1172 + */ 1173 + return worker && worker->current_cwq->wq == wq; 1191 1174 } 1192 1175 1193 1176 static void __queue_work(unsigned int cpu, struct workqueue_struct *wq,