]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
pdflush: handle resume wakeups
authorPavel Machek <pavel@suse.cz>
Tue, 8 Aug 2006 09:58:01 +0000 (11:58 +0200)
committerAdrian Bunk <bunk@stusta.de>
Tue, 8 Aug 2006 09:58:01 +0000 (11:58 +0200)
2.6.16 needs this. It was merged into 2.6.18-rc1.

pdflush is carefully designed to ensure that all wakeups have some
corresponding work to do - if a woken-up pdflush thread discovers that
it hasn't been given any work to do then this is considered an error.

That all broke when swsusp came along - because a timer-delivered
wakeup to a frozen pdflush thread will just get lost.  This causes the
pdflush thread to get lost as well: the writeback timer is supposed to
be re-armed by pdflush in process context, but pdflush doesn't execute
the callout which does this.

Fix that up by ignoring the return value from try_to_freeze(): jsut
proceed, see if we have any work pending and only go back to sleep if
that is not the case.

Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Pavel Machek <pavel@suse.cz>
Signed-off-by: Adrian Bunk <bunk@stusta.de>
mm/pdflush.c

index c4b6d0afd73605cdc446a1cd9fc75aca8afb3693..4842716d128cff36503d3f0ae36d851f1d508360 100644 (file)
@@ -104,21 +104,20 @@ static int __pdflush(struct pdflush_work *my_work)
                list_move(&my_work->list, &pdflush_list);
                my_work->when_i_went_to_sleep = jiffies;
                spin_unlock_irq(&pdflush_lock);
-
                schedule();
-               if (try_to_freeze()) {
-                       spin_lock_irq(&pdflush_lock);
-                       continue;
-               }
-
+               try_to_freeze();
                spin_lock_irq(&pdflush_lock);
                if (!list_empty(&my_work->list)) {
-                       printk("pdflush: bogus wakeup!\n");
+                       /*
+                        * Someone woke us up, but without removing our control
+                        * structure from the global list.  swsusp will do this
+                        * in try_to_freeze()->refrigerator().  Handle it.
+                        */
                        my_work->fn = NULL;
                        continue;
                }
                if (my_work->fn == NULL) {
-                       printk("pdflush: NULL work function\n");
+                       printk("pdflush: bogus wakeup\n");
                        continue;
                }
                spin_unlock_irq(&pdflush_lock);