X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=mm%2Fpdflush.c;h=1c96cfc9e0400cf0e6b3c4cf41cdccc03bff17c0;hb=e9b62693ae0a1e13ccc97a6792d9a7770c8d1b5b;hp=d6781951267eb654a522529658aaa06199d1772f;hpb=3e1d1d28d99dabe63c64f7f40f1ca1d646de1f73;p=safe%2Fjmp%2Flinux-2.6 diff --git a/mm/pdflush.c b/mm/pdflush.c index d678195..1c96cfc 100644 --- a/mm/pdflush.c +++ b/mm/pdflush.c @@ -17,9 +17,11 @@ #include #include #include -#include // Needed by writeback.h -#include // Prototypes pdflush_operation() +#include /* Needed by writeback.h */ +#include /* Prototypes pdflush_operation() */ #include +#include +#include /* @@ -89,7 +91,8 @@ struct pdflush_work { static int __pdflush(struct pdflush_work *my_work) { - current->flags |= PF_FLUSHER; + current->flags |= PF_FLUSHER | PF_SWAPWRITE; + set_freezable(); my_work->fn = NULL; my_work->who = current; INIT_LIST_HEAD(&my_work->list); @@ -103,21 +106,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); @@ -170,12 +172,24 @@ static int __pdflush(struct pdflush_work *my_work) static int pdflush(void *dummy) { struct pdflush_work my_work; + cpumask_t cpus_allowed; /* * pdflush can spend a lot of time doing encryption via dm-crypt. We * don't want to do that at keventd's priority. */ set_user_nice(current, 0); + + /* + * Some configs put our parent kthread in a limited cpuset, + * which kthread() overrides, forcing cpus_allowed == CPU_MASK_ALL. + * Our needs are more modest - cut back to our cpusets cpus_allowed. + * This is needed as pdflush's are dynamically created and destroyed. + * The boottime pdflush's are easily placed w/o these 2 lines. + */ + cpuset_cpus_allowed(current, &cpus_allowed); + set_cpus_allowed_ptr(current, &cpus_allowed); + return __pdflush(&my_work); } @@ -189,8 +203,7 @@ int pdflush_operation(void (*fn)(unsigned long), unsigned long arg0) unsigned long flags; int ret = 0; - if (fn == NULL) - BUG(); /* Hard to diagnose if it's deferred */ + BUG_ON(fn == NULL); /* Hard to diagnose if it's deferred */ spin_lock_irqsave(&pdflush_lock, flags); if (list_empty(&pdflush_list)) {