workqueue: lock cwq access in drain_workqueue
authorThomas Tuttle <ttuttle@chromium.org>
Wed, 14 Sep 2011 23:22:28 +0000 (16:22 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Mon, 3 Oct 2011 18:40:31 +0000 (11:40 -0700)
commitd5b1a08d0d0a73c716766275eb0c5648e143ca85
tree2f62c1aa34c268658ca29b6776fdb73b71fcc7e9
parentc780713f786ee22532839502ed35f1bd1cb0fd1d
workqueue: lock cwq access in drain_workqueue

commit fa2563e41c3d6d6e8af437643981ed28ae0cb56d upstream.

Take cwq->gcwq->lock to avoid racing between drain_workqueue checking to
make sure the workqueues are empty and cwq_dec_nr_in_flight decrementing
and then incrementing nr_active when it activates a delayed work.

We discovered this when a corner case in one of our drivers resulted in
us trying to destroy a workqueue in which the remaining work would
always requeue itself again in the same workqueue.  We would hit this
race condition and trip the BUG_ON on workqueue.c:3080.

Signed-off-by: Thomas Tuttle <ttuttle@chromium.org>
Acked-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
kernel/workqueue.c