aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-12-01 20:55:13 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-01 20:55:13 -0500
commit3c46f3d6406b1d0c53575774b2d1fd013cd7f76f (patch)
tree577ba6a2d1a3ced1ac270152f33ae675c7e61306
parent331fee3cd31c3ec3641062ca01a71b79dbf58b40 (diff)
parent8852aac25e79e38cc6529f20298eed154f60b574 (diff)
Merge branch 'for-3.7-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq
Pull late workqueue fixes from Tejun Heo: "Unfortunately, I have two really late fixes. One was for a long-standing bug and queued for 3.8 but I found out about a regression introduced during 3.7-rc1 two days ago, so I'm sending out the two fixes together. The first (long-standing) one is rescuer_thread() entering exit path w/ TASK_INTERRUPTIBLE. It only triggers on workqueue destructions which isn't very frequent and the exit path can usually survive being called with TASK_INTERRUPT, so it was hidden pretty well. Apparently, if you're reiserfs, this could lead to the exiting kthread sleeping indefinitely holding a mutex, which is never good. The fix is simple - restoring TASK_RUNNING before returning from the kthread function. The second one is introduced by the new mod_delayed_work(). mod_delayed_work() was missing special case handling for 0 delay. Instead of queueing the work item immediately, it queued the timer which expires on the closest next tick. Some users of the new function converted from "[__]cancel_delayed_work() + queue_delayed_work()" combination became unhappy with the extra delay. Block unplugging led to noticeably higher number of context switches and intel 6250 wireless failed to associate with WPA-Enterprise network. The fix, again, is fairly simple. The 0 delay special case logic from queue_delayed_work_on() should be moved to __queue_delayed_work() which is shared by both queue_delayed_work_on() and mod_delayed_work_on(). The first one is difficult to trigger and the failure mode for the latter isn't completely catastrophic, so missing these two for 3.7 wouldn't make it a disastrous release, but both bugs are nasty and the fixes are fairly safe" * 'for-3.7-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq: workqueue: mod_delayed_work_on() shouldn't queue timer on 0 delay workqueue: exit rescuer_thread() as TASK_RUNNING
-rw-r--r--kernel/workqueue.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 042d221d33cc..084aa47bac82 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -1364,6 +1364,17 @@ static void __queue_delayed_work(int cpu, struct workqueue_struct *wq,
1364 BUG_ON(timer_pending(timer)); 1364 BUG_ON(timer_pending(timer));
1365 BUG_ON(!list_empty(&work->entry)); 1365 BUG_ON(!list_empty(&work->entry));
1366 1366
1367 /*
1368 * If @delay is 0, queue @dwork->work immediately. This is for
1369 * both optimization and correctness. The earliest @timer can
1370 * expire is on the closest next tick and delayed_work users depend
1371 * on that there's no such delay when @delay is 0.
1372 */
1373 if (!delay) {
1374 __queue_work(cpu, wq, &dwork->work);
1375 return;
1376 }
1377
1367 timer_stats_timer_set_start_info(&dwork->timer); 1378 timer_stats_timer_set_start_info(&dwork->timer);
1368 1379
1369 /* 1380 /*
@@ -1417,9 +1428,6 @@ bool queue_delayed_work_on(int cpu, struct workqueue_struct *wq,
1417 bool ret = false; 1428 bool ret = false;
1418 unsigned long flags; 1429 unsigned long flags;
1419 1430
1420 if (!delay)
1421 return queue_work_on(cpu, wq, &dwork->work);
1422
1423 /* read the comment in __queue_work() */ 1431 /* read the comment in __queue_work() */
1424 local_irq_save(flags); 1432 local_irq_save(flags);
1425 1433
@@ -2407,8 +2415,10 @@ static int rescuer_thread(void *__wq)
2407repeat: 2415repeat:
2408 set_current_state(TASK_INTERRUPTIBLE); 2416 set_current_state(TASK_INTERRUPTIBLE);
2409 2417
2410 if (kthread_should_stop()) 2418 if (kthread_should_stop()) {
2419 __set_current_state(TASK_RUNNING);
2411 return 0; 2420 return 0;
2421 }
2412 2422
2413 /* 2423 /*
2414 * See whether any cpu is asking for help. Unbounded 2424 * See whether any cpu is asking for help. Unbounded