Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+14 -4
+14 -4
kernel/workqueue.c
··· 1364 1364 BUG_ON(timer_pending(timer)); 1365 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 1378 timer_stats_timer_set_start_info(&dwork->timer); 1368 1379 1369 1380 /* ··· 1427 1416 struct work_struct *work = &dwork->work; 1428 1417 bool ret = false; 1429 1418 unsigned long flags; 1430 - 1431 - if (!delay) 1432 - return queue_work_on(cpu, wq, &dwork->work); 1433 1419 1434 1420 /* read the comment in __queue_work() */ 1435 1421 local_irq_save(flags); ··· 2415 2407 repeat: 2416 2408 set_current_state(TASK_INTERRUPTIBLE); 2417 2409 2418 - if (kthread_should_stop()) 2410 + if (kthread_should_stop()) { 2411 + __set_current_state(TASK_RUNNING); 2419 2412 return 0; 2413 + } 2420 2414 2421 2415 /* 2422 2416 * See whether any cpu is asking for help. Unbounded