]> git.hungrycats.org Git - linux/commitdiff
[PATCH] add drain_local_pages() for CONFIG_SOFTWARE_SUSPEND
authorAndrew Morton <akpm@digeo.com>
Mon, 30 Dec 2002 05:40:31 +0000 (21:40 -0800)
committerLinus Torvalds <torvalds@home.transmeta.com>
Mon, 30 Dec 2002 05:40:31 +0000 (21:40 -0800)
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.

include/linux/suspend.h
mm/page_alloc.c

index a481f80034fa1ef94ee99c04b9c8ab8bfee8d158..80b4a657b49cb98f4628e5ec8cd06d412726a6e7 100644 (file)
@@ -46,6 +46,9 @@ struct suspend_header {
 /* 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);
index 7de787fd57d90835cecb968c927ee93761fc8378..1c8015736d614e3495d7c901a785baac538660a3 100644 (file)
@@ -350,6 +350,31 @@ int is_head_of_free_region(struct page *page)
        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 */
 
 /*