<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux/kernel/workqueue.c, branch v3.6</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=v3.6</id>
<link rel='self' href='https://git.shady.money/linux/atom?h=v3.6'/>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/'/>
<updated>2012-09-19T17:13:12Z</updated>
<entry>
<title>workqueue: reimplement work_on_cpu() using system_wq</title>
<updated>2012-09-19T17:13:12Z</updated>
<author>
<name>Tejun Heo</name>
<email>tj@kernel.org</email>
</author>
<published>2012-09-18T19:48:43Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=ed48ece27cd3d5ee0354c32bbaec0f3e1d4715c3'/>
<id>urn:sha1:ed48ece27cd3d5ee0354c32bbaec0f3e1d4715c3</id>
<content type='text'>
The existing work_on_cpu() implementation is hugely inefficient.  It
creates a new kthread, execute that single function and then let the
kthread die on each invocation.

Now that system_wq can handle concurrent executions, there's no
advantage of doing this.  Reimplement work_on_cpu() using system_wq
which makes it simpler and way more efficient.

stable: While this isn't a fix in itself, it's needed to fix a
        workqueue related bug in cpufreq/powernow-k8.  AFAICS, this
        shouldn't break other existing users.

Signed-off-by: Tejun Heo &lt;tj@kernel.org&gt;
Acked-by: Jiri Kosina &lt;jkosina@suse.cz&gt;
Cc: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
Cc: Bjorn Helgaas &lt;bhelgaas@google.com&gt;
Cc: Len Brown &lt;lenb@kernel.org&gt;
Cc: Rafael J. Wysocki &lt;rjw@sisk.pl&gt;
Cc: stable@vger.kernel.org
</content>
</entry>
<entry>
<title>workqueue: always clear WORKER_REBIND in busy_worker_rebind_fn()</title>
<updated>2012-09-17T22:42:31Z</updated>
<author>
<name>Lai Jiangshan</name>
<email>laijs@cn.fujitsu.com</email>
</author>
<published>2012-09-17T22:42:31Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=960bd11bf2daf669d0d910428fd9ef5a15c3d7cb'/>
<id>urn:sha1:960bd11bf2daf669d0d910428fd9ef5a15c3d7cb</id>
<content type='text'>
busy_worker_rebind_fn() didn't clear WORKER_REBIND if rebinding failed
(CPU is down again).  This used to be okay because the flag wasn't
used for anything else.

However, after 25511a477 "workqueue: reimplement CPU online rebinding
to handle idle workers", WORKER_REBIND is also used to command idle
workers to rebind.  If not cleared, the worker may confuse the next
CPU_UP cycle by having REBIND spuriously set or oops / get stuck by
prematurely calling idle_worker_rebind().

  WARNING: at /work/os/wq/kernel/workqueue.c:1323 worker_thread+0x4cd/0x5
 00()
  Hardware name: Bochs
  Modules linked in: test_wq(O-)
  Pid: 33, comm: kworker/1:1 Tainted: G           O 3.6.0-rc1-work+ #3
  Call Trace:
   [&lt;ffffffff8109039f&gt;] warn_slowpath_common+0x7f/0xc0
   [&lt;ffffffff810903fa&gt;] warn_slowpath_null+0x1a/0x20
   [&lt;ffffffff810b3f1d&gt;] worker_thread+0x4cd/0x500
   [&lt;ffffffff810bc16e&gt;] kthread+0xbe/0xd0
   [&lt;ffffffff81bd2664&gt;] kernel_thread_helper+0x4/0x10
  ---[ end trace e977cf20f4661968 ]---
  BUG: unable to handle kernel NULL pointer dereference at           (null)
  IP: [&lt;ffffffff810b3db0&gt;] worker_thread+0x360/0x500
  PGD 0
  Oops: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC
  Modules linked in: test_wq(O-)
  CPU 0
  Pid: 33, comm: kworker/1:1 Tainted: G        W  O 3.6.0-rc1-work+ #3 Bochs Bochs
  RIP: 0010:[&lt;ffffffff810b3db0&gt;]  [&lt;ffffffff810b3db0&gt;] worker_thread+0x360/0x500
  RSP: 0018:ffff88001e1c9de0  EFLAGS: 00010086
  RAX: 0000000000000000 RBX: ffff88001e633e00 RCX: 0000000000004140
  RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000009
  RBP: ffff88001e1c9ea0 R08: 0000000000000000 R09: 0000000000000001
  R10: 0000000000000002 R11: 0000000000000000 R12: ffff88001fc8d580
  R13: ffff88001fc8d590 R14: ffff88001e633e20 R15: ffff88001e1c6900
  FS:  0000000000000000(0000) GS:ffff88001fc00000(0000) knlGS:0000000000000000
  CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
  CR2: 0000000000000000 CR3: 00000000130e8000 CR4: 00000000000006f0
  DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
  DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
  Process kworker/1:1 (pid: 33, threadinfo ffff88001e1c8000, task ffff88001e1c6900)
  Stack:
   ffff880000000000 ffff88001e1c9e40 0000000000000001 ffff88001e1c8010
   ffff88001e519c78 ffff88001e1c9e58 ffff88001e1c6900 ffff88001e1c6900
   ffff88001e1c6900 ffff88001e1c6900 ffff88001fc8d340 ffff88001fc8d340
  Call Trace:
   [&lt;ffffffff810bc16e&gt;] kthread+0xbe/0xd0
   [&lt;ffffffff81bd2664&gt;] kernel_thread_helper+0x4/0x10
  Code: b1 00 f6 43 48 02 0f 85 91 01 00 00 48 8b 43 38 48 89 df 48 8b 00 48 89 45 90 e8 ac f0 ff ff 3c 01 0f 85 60 01 00 00 48 8b 53 50 &lt;8b&gt; 02 83 e8 01 85 c0 89 02 0f 84 3b 01 00 00 48 8b 43 38 48 8b
  RIP  [&lt;ffffffff810b3db0&gt;] worker_thread+0x360/0x500
   RSP &lt;ffff88001e1c9de0&gt;
  CR2: 0000000000000000

There was no reason to keep WORKER_REBIND on failure in the first
place - WORKER_UNBOUND is guaranteed to be set in such cases
preventing incorrectly activating concurrency management.  Always
clear WORKER_REBIND.

tj: Updated comment and description.

Signed-off-by: Lai Jiangshan &lt;laijs@cn.fujitsu.com&gt;
Signed-off-by: Tejun Heo &lt;tj@kernel.org&gt;
</content>
</entry>
<entry>
<title>workqueue: fix possible idle worker depletion across CPU hotplug</title>
<updated>2012-09-10T17:05:54Z</updated>
<author>
<name>Lai Jiangshan</name>
<email>laijs@cn.fujitsu.com</email>
</author>
<published>2012-09-10T17:03:44Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=ee378aa49b594da9bda6a2c768cc5b2ad585f911'/>
<id>urn:sha1:ee378aa49b594da9bda6a2c768cc5b2ad585f911</id>
<content type='text'>
To simplify both normal and CPU hotplug paths, worker management is
prevented while CPU hoplug is in progress.  This is achieved by CPU
hotplug holding the same exclusion mechanism used by workers to ensure
there's only one manager per pool.

If someone else seems to be performing the manager role, workers
proceed to execute work items.  CPU hotplug using the same mechanism
can lead to idle worker depletion because all workers could proceed to
execute work items while CPU hotplug is in progress and CPU hotplug
itself wouldn't actually perform the worker management duty - it
doesn't guarantee that there's an idle worker left when it releases
management.

This idle worker depletion, under extreme circumstances, can break
forward-progress guarantee and thus lead to deadlock.

This patch fixes the bug by using separate mechanisms for manager
exclusion among workers and hotplug exclusion.  For manager exclusion,
POOL_MANAGING_WORKERS which was restored by the previous patch is
used.  pool-&gt;manager_mutex is now only used for exclusion between the
elected manager and CPU hotplug.  The elected manager won't proceed
without holding pool-&gt;manager_mutex.

This ensures that the worker which won the manager position can't skip
managing while CPU hotplug is in progress.  It will block on
manager_mutex and perform management after CPU hotplug is complete.

Note that hotplug may happen while waiting for manager_mutex.  A
manager isn't either on idle or busy list and thus the hoplug code
can't unbind/rebind it.  Make the manager handle its own un/rebinding.

tj: Updated comment and description.

Signed-off-by: Lai Jiangshan &lt;laijs@cn.fujitsu.com&gt;
Signed-off-by: Tejun Heo &lt;tj@kernel.org&gt;
</content>
</entry>
<entry>
<title>workqueue: restore POOL_MANAGING_WORKERS</title>
<updated>2012-09-10T17:04:54Z</updated>
<author>
<name>Lai Jiangshan</name>
<email>laijs@cn.fujitsu.com</email>
</author>
<published>2012-09-10T17:03:33Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=552a37e9360a293cd20e7f8ff1fb326a244c5f1e'/>
<id>urn:sha1:552a37e9360a293cd20e7f8ff1fb326a244c5f1e</id>
<content type='text'>
This patch restores POOL_MANAGING_WORKERS which was replaced by
pool-&gt;manager_mutex by 6037315269 "workqueue: use mutex for global_cwq
manager exclusion".

There's a subtle idle worker depletion bug across CPU hotplug events
and we need to distinguish an actual manager and CPU hotplug
preventing management.  POOL_MANAGING_WORKERS will be used for the
former and manager_mutex the later.

This patch just lays POOL_MANAGING_WORKERS on top of the existing
manager_mutex and doesn't introduce any synchronization changes.  The
next patch will update it.

Note that this patch fixes a non-critical anomaly where
too_many_workers() may return %true spuriously while CPU hotplug is in
progress.  While the issue could schedule idle timer spuriously, it
didn't trigger any actual misbehavior.

tj: Rewrote patch description.

Signed-off-by: Lai Jiangshan &lt;laijs@cn.fujitsu.com&gt;
Signed-off-by: Tejun Heo &lt;tj@kernel.org&gt;
</content>
</entry>
<entry>
<title>workqueue: fix possible deadlock in idle worker rebinding</title>
<updated>2012-09-05T23:10:15Z</updated>
<author>
<name>Tejun Heo</name>
<email>tj@kernel.org</email>
</author>
<published>2012-09-05T06:16:32Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=ec58815ab0409a921a7c9744eb4ca44866b14d71'/>
<id>urn:sha1:ec58815ab0409a921a7c9744eb4ca44866b14d71</id>
<content type='text'>
Currently, rebind_workers() and idle_worker_rebind() are two-way
interlocked.  rebind_workers() waits for idle workers to finish
rebinding and rebound idle workers wait for rebind_workers() to finish
rebinding busy workers before proceeding.

Unfortunately, this isn't enough.  The second wait from idle workers
is implemented as follows.

	wait_event(gcwq-&gt;rebind_hold, !(worker-&gt;flags &amp; WORKER_REBIND));

rebind_workers() clears WORKER_REBIND, wakes up the idle workers and
then returns.  If CPU hotplug cycle happens again before one of the
idle workers finishes the above wait_event(), rebind_workers() will
repeat the first part of the handshake - set WORKER_REBIND again and
wait for the idle worker to finish rebinding - and this leads to
deadlock because the idle worker would be waiting for WORKER_REBIND to
clear.

This is fixed by adding another interlocking step at the end -
rebind_workers() now waits for all the idle workers to finish the
above WORKER_REBIND wait before returning.  This ensures that all
rebinding steps are complete on all idle workers before the next
hotplug cycle can happen.

This problem was diagnosed by Lai Jiangshan who also posted a patch to
fix the issue, upon which this patch is based.

This is the minimal fix and further patches are scheduled for the next
merge window to simplify the CPU hotplug path.

Signed-off-by: Tejun Heo &lt;tj@kernel.org&gt;
Original-patch-by: Lai Jiangshan &lt;laijs@cn.fujitsu.com&gt;
LKML-Reference: &lt;1346516916-1991-3-git-send-email-laijs@cn.fujitsu.com&gt;
</content>
</entry>
<entry>
<title>workqueue: move WORKER_REBIND clearing in rebind_workers() to the end of the function</title>
<updated>2012-09-05T23:10:14Z</updated>
<author>
<name>Tejun Heo</name>
<email>tj@kernel.org</email>
</author>
<published>2012-09-05T06:12:33Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=90beca5de591e12482a812f23a7f10690962ed4a'/>
<id>urn:sha1:90beca5de591e12482a812f23a7f10690962ed4a</id>
<content type='text'>
This doesn't make any functional difference and is purely to help the
next patch to be simpler.

Signed-off-by: Tejun Heo &lt;tj@kernel.org&gt;
Cc: Lai Jiangshan &lt;laijs@cn.fujitsu.com&gt;
</content>
</entry>
<entry>
<title>workqueue: UNBOUND -&gt; REBIND morphing in rebind_workers() should be atomic</title>
<updated>2012-09-05T00:04:45Z</updated>
<author>
<name>Lai Jiangshan</name>
<email>laijs@cn.fujitsu.com</email>
</author>
<published>2012-09-01T16:28:19Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=96e65306b81351b656835c15931d1d237b252f27'/>
<id>urn:sha1:96e65306b81351b656835c15931d1d237b252f27</id>
<content type='text'>
The compiler may compile the following code into TWO write/modify
instructions.

	worker-&gt;flags &amp;= ~WORKER_UNBOUND;
	worker-&gt;flags |= WORKER_REBIND;

so the other CPU may temporarily see worker-&gt;flags which doesn't have
either WORKER_UNBOUND or WORKER_REBIND set and perform local wakeup
prematurely.

Fix it by using single explicit assignment via ACCESS_ONCE().

Because idle workers have another WORKER_NOT_RUNNING flag, this bug
doesn't exist for them; however, update it to use the same pattern for
consistency.

tj: Applied the change to idle workers too and updated comments and
    patch description a bit.

Signed-off-by: Lai Jiangshan &lt;laijs@cn.fujitsu.com&gt;
Signed-off-by: Tejun Heo &lt;tj@kernel.org&gt;
Cc: stable@vger.kernel.org
</content>
</entry>
<entry>
<title>workqueue: fix spurious CPU locality WARN from process_one_work()</title>
<updated>2012-07-22T17:16:34Z</updated>
<author>
<name>Tejun Heo</name>
<email>tj@kernel.org</email>
</author>
<published>2012-07-22T17:16:34Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=6fec10a1a5866dda3cd6a825a521fc7c2f226ba5'/>
<id>urn:sha1:6fec10a1a5866dda3cd6a825a521fc7c2f226ba5</id>
<content type='text'>
25511a4776 "workqueue: reimplement CPU online rebinding to handle idle
workers" added CPU locality sanity check in process_one_work().  It
triggers if a worker is executing on a different CPU without UNBOUND
or REBIND set.

This works for all normal workers but rescuers can trigger this
spuriously when they're serving the unbound or a disassociated
global_cwq - rescuers don't have either flag set and thus its
gcwq-&gt;cpu can be a different value including %WORK_CPU_UNBOUND.

Fix it by additionally testing %GCWQ_DISASSOCIATED.

Signed-off-by: Tejun Heo &lt;tj@kernel.org&gt;
Reported-by: "Paul E. McKenney" &lt;paulmck@linux.vnet.ibm.com&gt;
LKML-Refence: &lt;20120721213656.GA7783@linux.vnet.ibm.com&gt;
</content>
</entry>
<entry>
<title>workqueue: simplify CPU hotplug code</title>
<updated>2012-07-17T19:39:28Z</updated>
<author>
<name>Tejun Heo</name>
<email>tj@kernel.org</email>
</author>
<published>2012-07-17T19:39:28Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=8db25e7891a47e03db6f04344a9c92be16e391bb'/>
<id>urn:sha1:8db25e7891a47e03db6f04344a9c92be16e391bb</id>
<content type='text'>
With trustee gone, CPU hotplug code can be simplified.

* gcwq_claim/release_management() now grab and release gcwq lock too
  respectively and gained _and_lock and _and_unlock postfixes.

* All CPU hotplug logic was implemented in workqueue_cpu_callback()
  which was called by workqueue_cpu_up/down_callback() for the correct
  priority.  This was because up and down paths shared a lot of logic,
  which is no longer true.  Remove workqueue_cpu_callback() and move
  all hotplug logic into the two actual callbacks.

This patch doesn't make any functional changes.

Signed-off-by: Tejun Heo &lt;tj@kernel.org&gt;
Acked-by: "Rafael J. Wysocki" &lt;rjw@sisk.pl&gt;
</content>
</entry>
<entry>
<title>workqueue: remove CPU offline trustee</title>
<updated>2012-07-17T19:39:27Z</updated>
<author>
<name>Tejun Heo</name>
<email>tj@kernel.org</email>
</author>
<published>2012-07-17T19:39:27Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=628c78e7ea19d5b70d2b6a59030362168cdbe1ad'/>
<id>urn:sha1:628c78e7ea19d5b70d2b6a59030362168cdbe1ad</id>
<content type='text'>
With the previous changes, a disassociated global_cwq now can run as
an unbound one on its own - it can create workers as necessary to
drain remaining works after the CPU has been brought down and manage
the number of workers using the usual idle timer mechanism making
trustee completely redundant except for the actual unbinding
operation.

This patch removes the trustee and let a disassociated global_cwq
manage itself.  Unbinding is moved to a work item (for CPU affinity)
which is scheduled and flushed from CPU_DONW_PREPARE.

This patch moves nr_running clearing outside gcwq and manager locks to
simplify the code.  As nr_running is unused at the point, this is
safe.

Signed-off-by: Tejun Heo &lt;tj@kernel.org&gt;
Acked-by: "Rafael J. Wysocki" &lt;rjw@sisk.pl&gt;
</content>
</entry>
</feed>
