swsusp gets confused when pages which it freed do not appear in the
buddy lists. So provide a function which will drain the calling CPU's
per-cpu-pages into the buddy.
The patch has been tested by Pavel. Presence of the new code is
conditional on CONFIG_SOFTWARE_SUSPEND.
/* mm/vmscan.c */
extern int shrink_mem(void);
+/* mm/page_alloc.c */
+extern void drain_local_pages(void);
+
/* kernel/suspend.c */
extern void software_suspend(void);
extern void software_resume(void);
spin_unlock_irqrestore(&zone->lock, flags);
return 0;
}
+
+/*
+ * Spill all of this CPU's per-cpu pages back into the buddy allocator.
+ */
+void drain_local_pages(void)
+{
+ unsigned long flags;
+ struct zone *zone;
+ int i;
+
+ local_irq_save(flags);
+ for_each_zone(zone) {
+ struct per_cpu_pageset *pset;
+
+ pset = &zone->pageset[smp_processor_id()];
+ for (i = 0; i < ARRAY_SIZE(pset->pcp); i++) {
+ struct per_cpu_pages *pcp;
+
+ pcp = &pset->pcp[i];
+ pcp->count -= free_pages_bulk(zone, pcp->count,
+ &pcp->list, 0);
+ }
+ }
+ local_irq_restore(flags);
+}
#endif /* CONFIG_SOFTWARE_SUSPEND */
/*