Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e42986de authored by Joonsoo Kim's avatar Joonsoo Kim Committed by Tejun Heo
Browse files

workqueue: change value of lcpu in __queue_delayed_work_on()



We assign cpu id into work struct's data field in __queue_delayed_work_on().
In current implementation, when work is come in first time,
current running cpu id is assigned.
If we do __queue_delayed_work_on() with CPU A on CPU B,
__queue_work() invoked in delayed_work_timer_fn() go into
the following sub-optimal path in case of WQ_NON_REENTRANT.

	gcwq = get_gcwq(cpu);
	if (wq->flags & WQ_NON_REENTRANT &&
		(last_gcwq = get_work_gcwq(work)) && last_gcwq != gcwq) {

Change lcpu to @cpu and rechange lcpu to local cpu if lcpu is WORK_CPU_UNBOUND.
It is sufficient to prevent to go into sub-optimal path.

tj: Slightly rephrased the comment.

Signed-off-by: default avatarJoonsoo Kim <js1304@gmail.com>
Signed-off-by: default avatarTejun Heo <tj@kernel.org>
parent b75cac93
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -1356,9 +1356,15 @@ static void __queue_delayed_work(int cpu, struct workqueue_struct *wq,
	if (!(wq->flags & WQ_UNBOUND)) {
		struct global_cwq *gcwq = get_work_gcwq(work);

		if (gcwq && gcwq->cpu != WORK_CPU_UNBOUND)
		/*
		 * If we cannot get the last gcwq from @work directly,
		 * select the last CPU such that it avoids unnecessarily
		 * triggering non-reentrancy check in __queue_work().
		 */
		lcpu = cpu;
		if (gcwq)
			lcpu = gcwq->cpu;
		else
		if (lcpu == WORK_CPU_UNBOUND)
			lcpu = raw_smp_processor_id();
	} else {
		lcpu = WORK_CPU_UNBOUND;