In free_hot_cold_page(), we rely on pcp->batch remaining stable. Updating it without being on the cpu owning the percpu pageset potentially destroys this stability.
Change for_each_cpu() to on_each_cpu() to fix. Signed-off-by: Cody P Schafer <c...@linux.vnet.ibm.com> --- mm/page_alloc.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 48f2faa..507db31 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -5475,30 +5475,31 @@ int lowmem_reserve_ratio_sysctl_handler(ctl_table *table, int write, return 0; } +static void _zone_set_pageset_highmark(void *data) +{ + struct zone *zone = data; + unsigned long high; + high = zone->managed_pages / percpu_pagelist_fraction; + setup_pagelist_highmark( + per_cpu_ptr(zone->pageset, smp_processor_id()), high); +} + /* * percpu_pagelist_fraction - changes the pcp->high for each zone on each * cpu. It is the fraction of total pages in each zone that a hot per cpu pagelist * can have before it gets flushed back to buddy allocator. */ - int percpu_pagelist_fraction_sysctl_handler(ctl_table *table, int write, void __user *buffer, size_t *length, loff_t *ppos) { struct zone *zone; - unsigned int cpu; int ret; ret = proc_dointvec_minmax(table, write, buffer, length, ppos); if (!write || (ret < 0)) return ret; - for_each_populated_zone(zone) { - for_each_possible_cpu(cpu) { - unsigned long high; - high = zone->managed_pages / percpu_pagelist_fraction; - setup_pagelist_highmark( - per_cpu_ptr(zone->pageset, cpu), high); - } - } + for_each_populated_zone(zone) + on_each_cpu(_zone_set_pageset_highmark, zone, true); return 0; } -- 1.8.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/