From: Andrew Morton This code was trying to assign a value to (&(__z)->pageset[(__cpu)]) and was then kfreeing it. Seems rather wrong. Fix that up and collaterally clean up a few other things. Cc: Christoph Lameter Signed-off-by: Andrew Morton --- mm/page_alloc.c | 37 +++++++++++++++++++++---------------- 1 files changed, 21 insertions(+), 16 deletions(-) diff -puN mm/page_alloc.c~node-local-per-cpu-pages-tidy-2-fix mm/page_alloc.c --- 25/mm/page_alloc.c~node-local-per-cpu-pages-tidy-2-fix 2005-06-07 01:30:18.000000000 -0700 +++ 25-akpm/mm/page_alloc.c 2005-06-07 01:30:59.000000000 -0700 @@ -1766,40 +1766,45 @@ bad: return -ENOMEM; } +static inline void free_zone_pagesets(int cpu) +{ +#ifdef CONFIG_NUMA + struct zone *zone; + + for_each_zone(zone) { + struct per_cpu_pageset *pset = zone_pcp(zone, cpu); + + zone_pcp(zone, cpu) = NULL; + kfree(pset); + } +#endif +} + static int __devinit pageset_cpuup_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { int cpu = (long)hcpu; + int ret = NOTIFY_OK; switch (action) { case CPU_UP_PREPARE: if (process_zones(cpu)) - goto bad; + ret = NOTIFY_BAD; break; #ifdef CONFIG_HOTPLUG_CPU case CPU_DEAD: - { - struct zone *zone; - for_each_zone(zone) { - struct per_cpu_pageset *pset; - - pset = zone_pcp(zone, cpu); - zone_pcp(zone, cpu) = NULL; - - kfree(pset); - } - } + free_zone_pagesets(cpu); break; #endif default: break; } - return NOTIFY_OK; -bad: - return NOTIFY_BAD; + return ret; } -struct notifier_block pageset_notifier = { &pageset_cpuup_callback, NULL, 0 }; + +static struct notifier_block pageset_notifier = + { &pageset_cpuup_callback, NULL, 0 }; void __init setup_per_cpu_pageset() { _