From: Rusty Russell <rusty@rustcorp.com.au>

Hotplug CPU needs to drain pages on a downed CPU (usually it's the current
cpu).  Make it an argument, and expose it if CONFIG_HOTPLUG_CPU as well as
CONFIG_PM.



---

 25-akpm/include/linux/suspend.h |    2 +-
 25-akpm/kernel/power/pmdisk.c   |    4 ++--
 25-akpm/kernel/power/swsusp.c   |    4 ++--
 25-akpm/mm/page_alloc.c         |    8 +++++---
 4 files changed, 10 insertions(+), 8 deletions(-)

diff -puN include/linux/suspend.h~cpuhotplug-02-drain_local_pages include/linux/suspend.h
--- 25/include/linux/suspend.h~cpuhotplug-02-drain_local_pages	Wed Feb  4 12:49:48 2004
+++ 25-akpm/include/linux/suspend.h	Wed Feb  4 12:49:48 2004
@@ -40,7 +40,7 @@ struct suspend_header {
 extern int shrink_mem(void);
 
 /* mm/page_alloc.c */
-extern void drain_local_pages(void);
+extern void drain_local_pages(unsigned int cpu);
 
 /* kernel/power/swsusp.c */
 extern int software_suspend(void);
diff -puN kernel/power/pmdisk.c~cpuhotplug-02-drain_local_pages kernel/power/pmdisk.c
--- 25/kernel/power/pmdisk.c~cpuhotplug-02-drain_local_pages	Wed Feb  4 12:49:48 2004
+++ 25-akpm/kernel/power/pmdisk.c	Wed Feb  4 12:49:48 2004
@@ -628,7 +628,7 @@ int pmdisk_suspend(void)
 	if ((error = read_swapfiles()))
 		return error;
 
-	drain_local_pages();
+	drain_local_pages(smp_processor_id());
 
 	pm_pagedir_nosave = NULL;
 	pr_debug("pmdisk: Counting pages to copy.\n" );
@@ -659,7 +659,7 @@ int pmdisk_suspend(void)
 	/* During allocating of suspend pagedir, new cold pages may appear. 
 	 * Kill them 
 	 */
-	drain_local_pages();
+	drain_local_pages(smp_processor_id());
 
 	/* copy */
 	copy_pages();
diff -puN kernel/power/swsusp.c~cpuhotplug-02-drain_local_pages kernel/power/swsusp.c
--- 25/kernel/power/swsusp.c~cpuhotplug-02-drain_local_pages	Wed Feb  4 12:49:48 2004
+++ 25-akpm/kernel/power/swsusp.c	Wed Feb  4 12:49:48 2004
@@ -495,7 +495,7 @@ static int suspend_prepare_image(void)
 	struct sysinfo i;
 	unsigned int nr_needed_pages = 0;
 
-	drain_local_pages();
+	drain_local_pages(smp_processor_id());
 
 	pagedir_nosave = NULL;
 	printk( "/critical section: Counting pages to copy" );
@@ -528,7 +528,7 @@ static int suspend_prepare_image(void)
 	nr_copy_pages_check = nr_copy_pages;
 	pagedir_order_check = pagedir_order;
 
-	drain_local_pages();	/* During allocating of suspend pagedir, new cold pages may appear. Kill them */
+	drain_local_pages(smp_processor_id());	/* During allocating of suspend pagedir, new cold pages may appear. Kill them */
 	if (nr_copy_pages != count_and_copy_data_pages(pagedir_nosave))	/* copy */
 		BUG();
 
diff -puN mm/page_alloc.c~cpuhotplug-02-drain_local_pages mm/page_alloc.c
--- 25/mm/page_alloc.c~cpuhotplug-02-drain_local_pages	Wed Feb  4 12:49:48 2004
+++ 25-akpm/mm/page_alloc.c	Wed Feb  4 12:49:48 2004
@@ -412,11 +412,13 @@ int is_head_of_free_region(struct page *
 	spin_unlock_irqrestore(&zone->lock, flags);
         return 0;
 }
+#endif /* CONFIG_PM */
 
+#if defined(CONFIG_PM) || defined(CONFIG_HOTPLUG_CPU)
 /*
  * Spill all of this CPU's per-cpu pages back into the buddy allocator.
  */
-void drain_local_pages(void)
+void drain_local_pages(unsigned int cpu)
 {
 	unsigned long flags;
 	struct zone *zone;
@@ -426,7 +428,7 @@ void drain_local_pages(void)
 	for_each_zone(zone) {
 		struct per_cpu_pageset *pset;
 
-		pset = &zone->pageset[smp_processor_id()];
+		pset = &zone->pageset[cpu];
 		for (i = 0; i < ARRAY_SIZE(pset->pcp); i++) {
 			struct per_cpu_pages *pcp;
 
@@ -437,7 +439,7 @@ void drain_local_pages(void)
 	}
 	local_irq_restore(flags);	
 }
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM || CONFIG_HOTPLUG_CPU */
 
 /*
  * Free a 0-order page

_