On Mon, May 31, 2010 at 11:25:52AM +0300, Artem Bityutskiy wrote: > On Fri, 2010-05-28 at 01:44 +1000, Nick Piggin wrote: > > > if (supers_dirty) > > > bdi_arm_supers_timer(); > > > set_current_state(TASK_INTERRUPTIBLE); > > > schedule(); > > > But we cannot do the above, because again the timer might go off > > before we set current state. We'd lose the wakeup and never wake > > up again. > > > > Putting it inside set_current_state() should be OK. I suppose. > > Hmm, but it looks like we cannot do that either. If we do > > set_current_state(TASK_INTERRUPTIBLE); > if (supers_dirty) > bdi_arm_supers_timer(); > schedule(); > > and the kernel is preemptive, is it possible that we get preempted > before we run 'bdi_arm_supers_timer()', but after we do > 'set_current_state(TASK_INTERRUPTIBLE)'. And we will never wake up if > the timer armed in mark_sb_dirty() went off. > > So it looks like this is the way to go: > > /* > * Disable preemption for a while to make sure we are not > * preempted before the timer is armed. > */ > preempt_disable(); > set_current_state(TASK_INTERRUPTIBLE); > if (supers_dirty) > bdi_arm_supers_timer(); > preempt_enable(); > schedule(); This should not be required because preempt is transparent to these task sleep/schedule APIs. The preempt event will not clear TASK_INTERRUPTIBLE, and so the timer wakeup will set it to TASK_RUNNING (whether or not it has called schedule() yet and whether or not it is currently preempted). -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html