aboutsummaryrefslogtreecommitdiffstats
path: root/mm/page_alloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/page_alloc.c')
-rw-r--r--mm/page_alloc.c56
1 files changed, 42 insertions, 14 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 4f59fa29eda8..0ea758b898fd 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -69,6 +69,7 @@
69 69
70/* prevent >1 _updater_ of zone percpu pageset ->high and ->batch fields */ 70/* prevent >1 _updater_ of zone percpu pageset ->high and ->batch fields */
71static DEFINE_MUTEX(pcp_batch_high_lock); 71static DEFINE_MUTEX(pcp_batch_high_lock);
72#define MIN_PERCPU_PAGELIST_FRACTION (8)
72 73
73#ifdef CONFIG_USE_PERCPU_NUMA_NODE_ID 74#ifdef CONFIG_USE_PERCPU_NUMA_NODE_ID
74DEFINE_PER_CPU(int, numa_node); 75DEFINE_PER_CPU(int, numa_node);
@@ -815,9 +816,21 @@ void __init init_cma_reserved_pageblock(struct page *page)
815 set_page_count(p, 0); 816 set_page_count(p, 0);
816 } while (++p, --i); 817 } while (++p, --i);
817 818
818 set_page_refcounted(page);
819 set_pageblock_migratetype(page, MIGRATE_CMA); 819 set_pageblock_migratetype(page, MIGRATE_CMA);
820 __free_pages(page, pageblock_order); 820
821 if (pageblock_order >= MAX_ORDER) {
822 i = pageblock_nr_pages;
823 p = page;
824 do {
825 set_page_refcounted(p);
826 __free_pages(p, MAX_ORDER - 1);
827 p += MAX_ORDER_NR_PAGES;
828 } while (i -= MAX_ORDER_NR_PAGES);
829 } else {
830 set_page_refcounted(page);
831 __free_pages(page, pageblock_order);
832 }
833
821 adjust_managed_page_count(page, pageblock_nr_pages); 834 adjust_managed_page_count(page, pageblock_nr_pages);
822} 835}
823#endif 836#endif
@@ -4145,7 +4158,7 @@ static void __meminit zone_init_free_lists(struct zone *zone)
4145 memmap_init_zone((size), (nid), (zone), (start_pfn), MEMMAP_EARLY) 4158 memmap_init_zone((size), (nid), (zone), (start_pfn), MEMMAP_EARLY)
4146#endif 4159#endif
4147 4160
4148static int __meminit zone_batchsize(struct zone *zone) 4161static int zone_batchsize(struct zone *zone)
4149{ 4162{
4150#ifdef CONFIG_MMU 4163#ifdef CONFIG_MMU
4151 int batch; 4164 int batch;
@@ -4261,8 +4274,8 @@ static void pageset_set_high(struct per_cpu_pageset *p,
4261 pageset_update(&p->pcp, high, batch); 4274 pageset_update(&p->pcp, high, batch);
4262} 4275}
4263 4276
4264static void __meminit pageset_set_high_and_batch(struct zone *zone, 4277static void pageset_set_high_and_batch(struct zone *zone,
4265 struct per_cpu_pageset *pcp) 4278 struct per_cpu_pageset *pcp)
4266{ 4279{
4267 if (percpu_pagelist_fraction) 4280 if (percpu_pagelist_fraction)
4268 pageset_set_high(pcp, 4281 pageset_set_high(pcp,
@@ -5881,23 +5894,38 @@ int percpu_pagelist_fraction_sysctl_handler(struct ctl_table *table, int write,
5881 void __user *buffer, size_t *length, loff_t *ppos) 5894 void __user *buffer, size_t *length, loff_t *ppos)
5882{ 5895{
5883 struct zone *zone; 5896 struct zone *zone;
5884 unsigned int cpu; 5897 int old_percpu_pagelist_fraction;
5885 int ret; 5898 int ret;
5886 5899
5900 mutex_lock(&pcp_batch_high_lock);
5901 old_percpu_pagelist_fraction = percpu_pagelist_fraction;
5902
5887 ret = proc_dointvec_minmax(table, write, buffer, length, ppos); 5903 ret = proc_dointvec_minmax(table, write, buffer, length, ppos);
5888 if (!write || (ret < 0)) 5904 if (!write || ret < 0)
5889 return ret; 5905 goto out;
5906
5907 /* Sanity checking to avoid pcp imbalance */
5908 if (percpu_pagelist_fraction &&
5909 percpu_pagelist_fraction < MIN_PERCPU_PAGELIST_FRACTION) {
5910 percpu_pagelist_fraction = old_percpu_pagelist_fraction;
5911 ret = -EINVAL;
5912 goto out;
5913 }
5914
5915 /* No change? */
5916 if (percpu_pagelist_fraction == old_percpu_pagelist_fraction)
5917 goto out;
5890 5918
5891 mutex_lock(&pcp_batch_high_lock);
5892 for_each_populated_zone(zone) { 5919 for_each_populated_zone(zone) {
5893 unsigned long high; 5920 unsigned int cpu;
5894 high = zone->managed_pages / percpu_pagelist_fraction; 5921
5895 for_each_possible_cpu(cpu) 5922 for_each_possible_cpu(cpu)
5896 pageset_set_high(per_cpu_ptr(zone->pageset, cpu), 5923 pageset_set_high_and_batch(zone,
5897 high); 5924 per_cpu_ptr(zone->pageset, cpu));
5898 } 5925 }
5926out:
5899 mutex_unlock(&pcp_batch_high_lock); 5927 mutex_unlock(&pcp_batch_high_lock);
5900 return 0; 5928 return ret;
5901} 5929}
5902 5930
5903int hashdist = HASHDIST_DEFAULT; 5931int hashdist = HASHDIST_DEFAULT;