<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux/kernel/workqueue.c, branch v5.17</title>
<subtitle>Mirror of https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/
</subtitle>
<id>https://git.shady.money/linux/atom?h=v5.17</id>
<link rel='self' href='https://git.shady.money/linux/atom?h=v5.17'/>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/'/>
<updated>2022-01-10T17:54:04Z</updated>
<entry>
<title>Merge branch 'workqueue/for-5.16-fixes' into workqueue/for-5.17</title>
<updated>2022-01-10T17:54:04Z</updated>
<author>
<name>Tejun Heo</name>
<email>tj@kernel.org</email>
</author>
<published>2022-01-10T17:54:04Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=2a8ab0fbd110dec25795a98aaa232ede36f6c855'/>
<id>urn:sha1:2a8ab0fbd110dec25795a98aaa232ede36f6c855</id>
<content type='text'>
for-5.16-fixes contains two subtle race conditions which were introduced by
scheduler side code cleanups. The branch didn't get pushed out, so merge
into for-5.17.
</content>
</entry>
<entry>
<title>workqueue: Remove the cacheline_aligned for nr_running</title>
<updated>2021-12-09T22:26:54Z</updated>
<author>
<name>Lai Jiangshan</name>
<email>laijs@linux.alibaba.com</email>
</author>
<published>2021-12-07T07:35:42Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=84f91c62d675480ffd3d870ee44c07965cbd8b21'/>
<id>urn:sha1:84f91c62d675480ffd3d870ee44c07965cbd8b21</id>
<content type='text'>
nr_running is never modified remotely after the schedule callback in
wakeup path is removed.

Rather nr_running is often accessed with other fields in the pool
together, so the cacheline_aligned for nr_running isn't needed.

Signed-off-by: Lai Jiangshan &lt;laijs@linux.alibaba.com&gt;
Signed-off-by: Tejun Heo &lt;tj@kernel.org&gt;
</content>
</entry>
<entry>
<title>workqueue: Move the code of waking a worker up in unbind_workers()</title>
<updated>2021-12-09T22:23:15Z</updated>
<author>
<name>Lai Jiangshan</name>
<email>laijs@linux.alibaba.com</email>
</author>
<published>2021-12-07T07:35:41Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=989442d73757868118a73b92732b549a73c9ce35'/>
<id>urn:sha1:989442d73757868118a73b92732b549a73c9ce35</id>
<content type='text'>
In unbind_workers(), there are two pool-&gt;lock held sections separated
by the code of zapping nr_running.  wake_up_worker() needs to be in
pool-&gt;lock held section and after zapping nr_running.  And zapping
nr_running had to be after schedule() when the local wake up
functionality was in use.  Now, the call to schedule() has been removed
along with the local wake up functionality, so the code can be merged
into the same pool-&gt;lock held section.

The diffstat shows that it is other code moved down because the diff
tools can not know the meaning of merging lock sections by swapping
two code blocks.

Signed-off-by: Lai Jiangshan &lt;laijs@linux.alibaba.com&gt;
Signed-off-by: Tejun Heo &lt;tj@kernel.org&gt;
</content>
</entry>
<entry>
<title>workqueue: Remove schedule() in unbind_workers()</title>
<updated>2021-12-09T22:20:24Z</updated>
<author>
<name>Lai Jiangshan</name>
<email>laijs@linux.alibaba.com</email>
</author>
<published>2021-12-07T07:35:40Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=b4ac9384ac057c5bf035fbe82fc162fa2f7b15a9'/>
<id>urn:sha1:b4ac9384ac057c5bf035fbe82fc162fa2f7b15a9</id>
<content type='text'>
The commit 6d25be5782e4 ("sched/core, workqueues: Distangle worker
accounting from rq lock") changed the schedule callbacks for workqueue
and moved the schedule callback from the wakeup code to at end of
schedule() in the worker's process context.

It means that the callback wq_worker_running() is guaranteed that
it sees the %WORKER_UNBOUND flag after scheduled since unbind_workers()
is running on the same CPU that all the pool's workers bound to.

Signed-off-by: Lai Jiangshan &lt;laijs@linux.alibaba.com&gt;
Signed-off-by: Tejun Heo &lt;tj@kernel.org&gt;
</content>
</entry>
<entry>
<title>workqueue: Remove outdated comment about exceptional workers in unbind_workers()</title>
<updated>2021-12-09T22:16:08Z</updated>
<author>
<name>Lai Jiangshan</name>
<email>laijs@linux.alibaba.com</email>
</author>
<published>2021-12-07T07:35:39Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=11b45b0bf402b53c94c86737a440363fc36f03cd'/>
<id>urn:sha1:11b45b0bf402b53c94c86737a440363fc36f03cd</id>
<content type='text'>
Long time before, workers are not ALL bound after CPU_ONLINE, they can
still be running in other CPUs before self rebinding.

But the commit a9ab775bcadf ("workqueue: directly restore CPU affinity
of workers from CPU_ONLINE") makes rebind_workers() bind them all.

So all workers are on the CPU before the CPU is down.

And the comment in unbind_workers() refers to the workers "which are
still executing works from before the last CPU down" is outdated.
Just removed it.

Signed-off-by: Lai Jiangshan &lt;laijs@linux.alibaba.com&gt;
Signed-off-by: Tejun Heo &lt;tj@kernel.org&gt;
</content>
</entry>
<entry>
<title>workqueue: Remove the advanced kicking of the idle workers in rebind_workers()</title>
<updated>2021-12-09T22:15:41Z</updated>
<author>
<name>Lai Jiangshan</name>
<email>laijs@linux.alibaba.com</email>
</author>
<published>2021-12-07T07:35:38Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=3e5f39ea33b1189ccaa4ae2a9de2bce07753d2e0'/>
<id>urn:sha1:3e5f39ea33b1189ccaa4ae2a9de2bce07753d2e0</id>
<content type='text'>
The commit 6d25be5782e4 ("sched/core, workqueues: Distangle worker
accounting from rq lock") changed the schedule callbacks for workqueue
and removed the local-wake-up functionality.

Now the wakingup of workers is done by normal fashion and workers not
yet migrated to the specific CPU in concurrency managed pool can also
be woken up by workers that already bound to the specific cpu now.

So this advanced kicking of the idle workers to migrate them to the
associated CPU is unneeded now.

Signed-off-by: Lai Jiangshan &lt;laijs@linux.alibaba.com&gt;
Signed-off-by: Tejun Heo &lt;tj@kernel.org&gt;
</content>
</entry>
<entry>
<title>workqueue: Remove the outdated comment before wq_worker_sleeping()</title>
<updated>2021-12-09T22:15:15Z</updated>
<author>
<name>Lai Jiangshan</name>
<email>laijs@linux.alibaba.com</email>
</author>
<published>2021-12-07T07:35:37Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=ccf45156fd167a234baf038c11c1f367c7ccabd4'/>
<id>urn:sha1:ccf45156fd167a234baf038c11c1f367c7ccabd4</id>
<content type='text'>
It isn't called with preempt disabled now.

Signed-off-by: Lai Jiangshan &lt;laijs@linux.alibaba.com&gt;
Signed-off-by: Tejun Heo &lt;tj@kernel.org&gt;
</content>
</entry>
<entry>
<title>workqueue: Fix unbind_workers() VS wq_worker_sleeping() race</title>
<updated>2021-12-02T23:00:59Z</updated>
<author>
<name>Frederic Weisbecker</name>
<email>frederic@kernel.org</email>
</author>
<published>2021-12-01T15:19:45Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=45c753f5f24d2d4717acb38ce35e604ff9abcb50'/>
<id>urn:sha1:45c753f5f24d2d4717acb38ce35e604ff9abcb50</id>
<content type='text'>
At CPU-hotplug time, unbind_workers() may preempt a worker while it is
going to sleep. In that case the following scenario can happen:

    unbind_workers()                     wq_worker_sleeping()
    --------------                      -------------------
                                      if (worker-&gt;flags &amp; WORKER_NOT_RUNNING)
                                          return;
                                      //PREEMPTED by unbind_workers
    worker-&gt;flags |= WORKER_UNBOUND;
    [...]
    atomic_set(&amp;pool-&gt;nr_running, 0);
    //resume to worker
                                       atomic_dec_and_test(&amp;pool-&gt;nr_running);

After unbind_worker() resets pool-&gt;nr_running, the value is expected to
remain 0 until the pool ever gets rebound in case cpu_up() is called on
the target CPU in the future. But here the race leaves pool-&gt;nr_running
with a value of -1, triggering the following warning when the worker goes
idle:

        WARNING: CPU: 3 PID: 34 at kernel/workqueue.c:1823 worker_enter_idle+0x95/0xc0
        Modules linked in:
        CPU: 3 PID: 34 Comm: kworker/3:0 Not tainted 5.16.0-rc1+ #34
        Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.12.0-59-gc9ba527-rebuilt.opensuse.org 04/01/2014
        Workqueue:  0x0 (rcu_par_gp)
        RIP: 0010:worker_enter_idle+0x95/0xc0
        Code: 04 85 f8 ff ff ff 39 c1 7f 09 48 8b 43 50 48 85 c0 74 1b 83 e2 04 75 99 8b 43 34 39 43 30 75 91 8b 83 00 03 00 00 85 c0 74 87 &lt;0f&gt; 0b 5b c3 48 8b 35 70 f1 37 01 48 8d 7b 48 48 81 c6 e0 93  0
        RSP: 0000:ffff9b7680277ed0 EFLAGS: 00010086
        RAX: 00000000ffffffff RBX: ffff93465eae9c00 RCX: 0000000000000000
        RDX: 0000000000000000 RSI: ffff9346418a0000 RDI: ffff934641057140
        RBP: ffff934641057170 R08: 0000000000000001 R09: ffff9346418a0080
        R10: ffff9b768027fdf0 R11: 0000000000002400 R12: ffff93465eae9c20
        R13: ffff93465eae9c20 R14: ffff93465eae9c70 R15: ffff934641057140
        FS:  0000000000000000(0000) GS:ffff93465eac0000(0000) knlGS:0000000000000000
        CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
        CR2: 0000000000000000 CR3: 000000001cc0c000 CR4: 00000000000006e0
        DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
        DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
        Call Trace:
          &lt;TASK&gt;
          worker_thread+0x89/0x3d0
          ? process_one_work+0x400/0x400
          kthread+0x162/0x190
          ? set_kthread_struct+0x40/0x40
          ret_from_fork+0x22/0x30
          &lt;/TASK&gt;

Also due to this incorrect "nr_running == -1", all sorts of hazards can
happen, starting with queued works being ignored because no workers are
awaken at insert_work() time.

Fix this with checking again the worker flags while pool-&gt;lock is locked.

Fixes: b945efcdd07d ("sched: Remove pointless preemption disable in sched_submit_work()")
Reviewed-by: Lai Jiangshan &lt;jiangshanlai@gmail.com&gt;
Tested-by: Paul E. McKenney &lt;paulmck@kernel.org&gt;
Acked-by: Peter Zijlstra (Intel) &lt;peterz@infradead.org&gt;
Signed-off-by: Frederic Weisbecker &lt;frederic@kernel.org&gt;
Cc: Thomas Gleixner &lt;tglx@linutronix.de&gt;
Cc: Ingo Molnar &lt;mingo@redhat.com&gt;
Cc: Paul E. McKenney &lt;paulmck@kernel.org&gt;
Cc: Sebastian Andrzej Siewior &lt;bigeasy@linutronix.de&gt;
Cc: Daniel Bristot de Oliveira &lt;bristot@redhat.com&gt;
Signed-off-by: Tejun Heo &lt;tj@kernel.org&gt;
</content>
</entry>
<entry>
<title>workqueue: Fix unbind_workers() VS wq_worker_running() race</title>
<updated>2021-12-02T22:59:58Z</updated>
<author>
<name>Frederic Weisbecker</name>
<email>frederic@kernel.org</email>
</author>
<published>2021-12-01T15:19:44Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=07edfece8bcb0580a1828d939e6f8d91a8603eb2'/>
<id>urn:sha1:07edfece8bcb0580a1828d939e6f8d91a8603eb2</id>
<content type='text'>
At CPU-hotplug time, unbind_worker() may preempt a worker while it is
waking up. In that case the following scenario can happen:

        unbind_workers()                     wq_worker_running()
        --------------                      -------------------
        	                      if (!(worker-&gt;flags &amp; WORKER_NOT_RUNNING))
        	                          //PREEMPTED by unbind_workers
        worker-&gt;flags |= WORKER_UNBOUND;
        [...]
        atomic_set(&amp;pool-&gt;nr_running, 0);
        //resume to worker
		                              atomic_inc(&amp;worker-&gt;pool-&gt;nr_running);

After unbind_worker() resets pool-&gt;nr_running, the value is expected to
remain 0 until the pool ever gets rebound in case cpu_up() is called on
the target CPU in the future. But here the race leaves pool-&gt;nr_running
with a value of 1, triggering the following warning when the worker goes
idle:

	WARNING: CPU: 3 PID: 34 at kernel/workqueue.c:1823 worker_enter_idle+0x95/0xc0
	Modules linked in:
	CPU: 3 PID: 34 Comm: kworker/3:0 Not tainted 5.16.0-rc1+ #34
	Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.12.0-59-gc9ba527-rebuilt.opensuse.org 04/01/2014
	Workqueue:  0x0 (rcu_par_gp)
	RIP: 0010:worker_enter_idle+0x95/0xc0
	Code: 04 85 f8 ff ff ff 39 c1 7f 09 48 8b 43 50 48 85 c0 74 1b 83 e2 04 75 99 8b 43 34 39 43 30 75 91 8b 83 00 03 00 00 85 c0 74 87 &lt;0f&gt; 0b 5b c3 48 8b 35 70 f1 37 01 48 8d 7b 48 48 81 c6 e0 93  0
	RSP: 0000:ffff9b7680277ed0 EFLAGS: 00010086
	RAX: 00000000ffffffff RBX: ffff93465eae9c00 RCX: 0000000000000000
	RDX: 0000000000000000 RSI: ffff9346418a0000 RDI: ffff934641057140
	RBP: ffff934641057170 R08: 0000000000000001 R09: ffff9346418a0080
	R10: ffff9b768027fdf0 R11: 0000000000002400 R12: ffff93465eae9c20
	R13: ffff93465eae9c20 R14: ffff93465eae9c70 R15: ffff934641057140
	FS:  0000000000000000(0000) GS:ffff93465eac0000(0000) knlGS:0000000000000000
	CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
	CR2: 0000000000000000 CR3: 000000001cc0c000 CR4: 00000000000006e0
	DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
	DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
	Call Trace:
	  &lt;TASK&gt;
	  worker_thread+0x89/0x3d0
	  ? process_one_work+0x400/0x400
	  kthread+0x162/0x190
	  ? set_kthread_struct+0x40/0x40
	  ret_from_fork+0x22/0x30
	  &lt;/TASK&gt;

Also due to this incorrect "nr_running == 1", further queued work may
end up not being served, because no worker is awaken at work insert time.
This raises rcutorture writer stalls for example.

Fix this with disabling preemption in the right place in
wq_worker_running().

It's worth noting that if the worker migrates and runs concurrently with
unbind_workers(), it is guaranteed to see the WORKER_UNBOUND flag update
due to set_cpus_allowed_ptr() acquiring/releasing rq-&gt;lock.

Fixes: 6d25be5782e4 ("sched/core, workqueues: Distangle worker accounting from rq lock")
Reviewed-by: Lai Jiangshan &lt;jiangshanlai@gmail.com&gt;
Tested-by: Paul E. McKenney &lt;paulmck@kernel.org&gt;
Acked-by: Peter Zijlstra (Intel) &lt;peterz@infradead.org&gt;
Signed-off-by: Frederic Weisbecker &lt;frederic@kernel.org&gt;
Cc: Thomas Gleixner &lt;tglx@linutronix.de&gt;
Cc: Ingo Molnar &lt;mingo@redhat.com&gt;
Cc: Sebastian Andrzej Siewior &lt;bigeasy@linutronix.de&gt;
Cc: Daniel Bristot de Oliveira &lt;bristot@redhat.com&gt;
Signed-off-by: Tejun Heo &lt;tj@kernel.org&gt;
</content>
</entry>
<entry>
<title>workqueue: Upgrade queue_work_on() comment</title>
<updated>2021-12-01T16:47:45Z</updated>
<author>
<name>Paul E. McKenney</name>
<email>paulmck@kernel.org</email>
</author>
<published>2021-12-01T01:00:30Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=443378f0664a78756c3e3aeaab92750fe1e05735'/>
<id>urn:sha1:443378f0664a78756c3e3aeaab92750fe1e05735</id>
<content type='text'>
The current queue_work_on() docbook comment says that the caller must
ensure that the specified CPU can't go away, but does not spell out the
consequences, which turn out to be quite mild.  Therefore expand this
comment to explicitly say that the penalty for failing to nail down the
specified CPU is that the workqueue handler might find itself executing
on some other CPU.

Cc: Tejun Heo &lt;tj@kernel.org&gt;
Cc: Lai Jiangshan &lt;jiangshanlai@gmail.com&gt;
Signed-off-by: Paul E. McKenney &lt;paulmck@kernel.org&gt;
Signed-off-by: Tejun Heo &lt;tj@kernel.org&gt;
</content>
</entry>
</feed>
