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

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



---

 mm/page_alloc.c |   38 +++++++++++++++++++++++---------------
 1 files changed, 23 insertions(+), 15 deletions(-)

diff -puN mm/page_alloc.c~hotplugcpu-core-drain_local_pages-fix mm/page_alloc.c
--- 25/mm/page_alloc.c~hotplugcpu-core-drain_local_pages-fix	2004-02-16 23:39:37.000000000 -0800
+++ 25-akpm/mm/page_alloc.c	2004-02-16 23:39:37.000000000 -0800
@@ -390,6 +390,27 @@ static int rmqueue_bulk(struct zone *zon
 	return allocated;
 }
 
+#if defined(CONFIG_PM) || defined(CONFIG_HOTPLUG_CPU)
+static void __drain_pages(unsigned int cpu)
+{
+	struct zone *zone;
+	int i;
+
+	for_each_zone(zone) {
+		struct per_cpu_pageset *pset;
+
+		pset = &zone->pageset[cpu];
+		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);
+		}
+	}
+}
+#endif /* CONFIG_PM || CONFIG_HOTPLUG_CPU */
+
 #ifdef CONFIG_PM
 int is_head_of_free_region(struct page *page)
 {
@@ -419,22 +440,9 @@ int is_head_of_free_region(struct page *
 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);
-		}
-	}
+	__drain_pages(smp_processor_id());
 	local_irq_restore(flags);	
 }
 #endif /* CONFIG_PM */
@@ -1548,7 +1556,7 @@ static int page_alloc_cpu_notify(struct 
 		count = &per_cpu(nr_pagecache_local, cpu);
 		atomic_add(*count, &nr_pagecache);
 		*count = 0;
-		drain_local_pages(cpu);
+		__drain_pages(cpu);
 	}
 	return NOTIFY_OK;
 }

_
