mm: fix handling of pagesets for downed cpus

After downing/upping a cpu, an attempt to set
/proc/sys/vm/percpu_pagelist_fraction results in an oops in
percpu_pagelist_fraction_sysctl_handler().

If a processor is downed then we need to set the pageset pointer back to
the boot pageset.

Updates of the high water marks should not access pagesets of unpopulated
zones (those pointer go to the boot pagesets which would be no longer
functional if their size would be increased beyond zero).

Signed-off-by: Dimitri Sivanich <sivanich@sgi.com>
Signed-off-by: Christoph Lameter <cl@linux-foundation.org>
Reviewed-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Cc: Nick Piggin <nickpiggin@yahoo.com.au>
Cc: Mel Gorman <mel@csn.ul.ie>
Cc: <stable@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by Dimitri Sivanich and committed by Linus Torvalds 364df0eb 01ff53f4

+3 -3
+3 -3
mm/page_alloc.c
··· 3026 3026 if (dzone == zone) 3027 3027 break; 3028 3028 kfree(zone_pcp(dzone, cpu)); 3029 - zone_pcp(dzone, cpu) = NULL; 3029 + zone_pcp(dzone, cpu) = &boot_pageset[cpu]; 3030 3030 } 3031 3031 return -ENOMEM; 3032 3032 } ··· 3041 3041 /* Free per_cpu_pageset if it is slab allocated */ 3042 3042 if (pset != &boot_pageset[cpu]) 3043 3043 kfree(pset); 3044 - zone_pcp(zone, cpu) = NULL; 3044 + zone_pcp(zone, cpu) = &boot_pageset[cpu]; 3045 3045 } 3046 3046 } 3047 3047 ··· 4659 4659 ret = proc_dointvec_minmax(table, write, file, buffer, length, ppos); 4660 4660 if (!write || (ret == -EINVAL)) 4661 4661 return ret; 4662 - for_each_zone(zone) { 4662 + for_each_populated_zone(zone) { 4663 4663 for_each_online_cpu(cpu) { 4664 4664 unsigned long high; 4665 4665 high = zone->present_pages / percpu_pagelist_fraction;