aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDimitri Sivanich <sivanich@sgi.com>2009-06-23 15:37:04 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-23 15:50:05 -0400
commit364df0ebfbbb1330bfc6ca159f4d6020efc15a12 (patch)
tree80c79bf145d8388ad96a0f7c47a4d25642e403a1
parent01ff53f416757da416413bc32229770a8448b6ef (diff)
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>
-rw-r--r--mm/page_alloc.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 30d5093a099d..aecc9cdfdfce 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -3026,7 +3026,7 @@ bad:
3026 if (dzone == zone) 3026 if (dzone == zone)
3027 break; 3027 break;
3028 kfree(zone_pcp(dzone, cpu)); 3028 kfree(zone_pcp(dzone, cpu));
3029 zone_pcp(dzone, cpu) = NULL; 3029 zone_pcp(dzone, cpu) = &boot_pageset[cpu];
3030 } 3030 }
3031 return -ENOMEM; 3031 return -ENOMEM;
3032} 3032}
@@ -3041,7 +3041,7 @@ static inline void free_zone_pagesets(int cpu)
3041 /* Free per_cpu_pageset if it is slab allocated */ 3041 /* Free per_cpu_pageset if it is slab allocated */
3042 if (pset != &boot_pageset[cpu]) 3042 if (pset != &boot_pageset[cpu])
3043 kfree(pset); 3043 kfree(pset);
3044 zone_pcp(zone, cpu) = NULL; 3044 zone_pcp(zone, cpu) = &boot_pageset[cpu];
3045 } 3045 }
3046} 3046}
3047 3047
@@ -4659,7 +4659,7 @@ int percpu_pagelist_fraction_sysctl_handler(ctl_table *table, int write,
4659 ret = proc_dointvec_minmax(table, write, file, buffer, length, ppos); 4659 ret = proc_dointvec_minmax(table, write, file, buffer, length, ppos);
4660 if (!write || (ret == -EINVAL)) 4660 if (!write || (ret == -EINVAL))
4661 return ret; 4661 return ret;
4662 for_each_zone(zone) { 4662 for_each_populated_zone(zone) {
4663 for_each_online_cpu(cpu) { 4663 for_each_online_cpu(cpu) {
4664 unsigned long high; 4664 unsigned long high;
4665 high = zone->present_pages / percpu_pagelist_fraction; 4665 high = zone->present_pages / percpu_pagelist_fraction;