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.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 5eeeadd9f66a..2c46f697e8ff 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -53,6 +53,7 @@ struct pglist_data *pgdat_list __read_mostly;
53unsigned long totalram_pages __read_mostly; 53unsigned long totalram_pages __read_mostly;
54unsigned long totalhigh_pages __read_mostly; 54unsigned long totalhigh_pages __read_mostly;
55long nr_swap_pages; 55long nr_swap_pages;
56int percpu_pagelist_fraction;
56 57
57static void fastcall free_hot_cold_page(struct page *page, int cold); 58static void fastcall free_hot_cold_page(struct page *page, int cold);
58 59
@@ -1831,6 +1832,24 @@ inline void setup_pageset(struct per_cpu_pageset *p, unsigned long batch)
1831 INIT_LIST_HEAD(&pcp->list); 1832 INIT_LIST_HEAD(&pcp->list);
1832} 1833}
1833 1834
1835/*
1836 * setup_pagelist_highmark() sets the high water mark for hot per_cpu_pagelist
1837 * to the value high for the pageset p.
1838 */
1839
1840static void setup_pagelist_highmark(struct per_cpu_pageset *p,
1841 unsigned long high)
1842{
1843 struct per_cpu_pages *pcp;
1844
1845 pcp = &p->pcp[0]; /* hot list */
1846 pcp->high = high;
1847 pcp->batch = max(1UL, high/4);
1848 if ((high/4) > (PAGE_SHIFT * 8))
1849 pcp->batch = PAGE_SHIFT * 8;
1850}
1851
1852
1834#ifdef CONFIG_NUMA 1853#ifdef CONFIG_NUMA
1835/* 1854/*
1836 * Boot pageset table. One per cpu which is going to be used for all 1855 * Boot pageset table. One per cpu which is going to be used for all
@@ -1868,6 +1887,10 @@ static int __devinit process_zones(int cpu)
1868 goto bad; 1887 goto bad;
1869 1888
1870 setup_pageset(zone->pageset[cpu], zone_batchsize(zone)); 1889 setup_pageset(zone->pageset[cpu], zone_batchsize(zone));
1890
1891 if (percpu_pagelist_fraction)
1892 setup_pagelist_highmark(zone_pcp(zone, cpu),
1893 (zone->present_pages / percpu_pagelist_fraction));
1871 } 1894 }
1872 1895
1873 return 0; 1896 return 0;
@@ -2567,6 +2590,32 @@ int lowmem_reserve_ratio_sysctl_handler(ctl_table *table, int write,
2567 return 0; 2590 return 0;
2568} 2591}
2569 2592
2593/*
2594 * percpu_pagelist_fraction - changes the pcp->high for each zone on each
2595 * cpu. It is the fraction of total pages in each zone that a hot per cpu pagelist
2596 * can have before it gets flushed back to buddy allocator.
2597 */
2598
2599int percpu_pagelist_fraction_sysctl_handler(ctl_table *table, int write,
2600 struct file *file, void __user *buffer, size_t *length, loff_t *ppos)
2601{
2602 struct zone *zone;
2603 unsigned int cpu;
2604 int ret;
2605
2606 ret = proc_dointvec_minmax(table, write, file, buffer, length, ppos);
2607 if (!write || (ret == -EINVAL))
2608 return ret;
2609 for_each_zone(zone) {
2610 for_each_online_cpu(cpu) {
2611 unsigned long high;
2612 high = zone->present_pages / percpu_pagelist_fraction;
2613 setup_pagelist_highmark(zone_pcp(zone, cpu), high);
2614 }
2615 }
2616 return 0;
2617}
2618
2570__initdata int hashdist = HASHDIST_DEFAULT; 2619__initdata int hashdist = HASHDIST_DEFAULT;
2571 2620
2572#ifdef CONFIG_NUMA 2621#ifdef CONFIG_NUMA