: Making high and batch sizes of per_cpu_pagelists configurable
Subsystems (6)
PATCH 1/1 : Making high and batch sizes of per_cpu_pagelists configurable
As recently there has been lot of traffic on the right values for batch and high water marks for per_cpu_pagelists. This patch makes these two variables configurable through /proc interface.
A new tunable /proc/sys/vm/percpu_pagelist_fraction is added. This entry controls the fraction of pages at most in each zone that are allocated for each per cpu page list. The min value for this is 8. It means that we don't allow more than 1/8th of pages in each zone to be allocated in any single per_cpu_pagelist.
The batch value of each per cpu pagelist is also updated as a result. It is set to pcp->high/4. The upper limit of batch is (PAGE_SHIFT * 8)
Thanks to Andrew for providing early feedback.
Documentation/sysctl/vm.txt +20 -0
@@ -27,6 +27,7 @@ - laptop_mode - block_dump - swap_prefetch +- percpu_pagelist_fraction ==============================================================
@@ -114,3 +115,22 @@ Setting it to 0 disables prefetching entirely. The default value is dependant on ramsize. + +============================================================== + +percpu_pagelist_fraction + +This is fraction of pages at most (high mark pcp->high) in each zone +that are allocated for each per cpu page list. The min value for this +is 8. It means that we don't allow more than 1/8th of pages in each zone +to be allocated in any single per_cpu_pagelist. This entry only +changes the value of hot per cpu pagelists. User can specify a number +like 100 to allocate 1/100th of each zone to each per cpu page list. + +The batch value of each per cpu pagelist is also updated as a +result. It is set to pcp->high/4. The upper limit of batch +is (PAGE_SHIFT * 8) + +The initial value is zero. Kernel does not use this value at boot time +to set the high water marks for each per cpu page list. +
include/linux/mmzone.h +2 -0
@@ -437,6 +437,8 @@extern int sysctl_lowmem_reserve_ratio[MAX_NR_ZONES -1 ];int lowmem_reserve_ratio_sysctl_handler (struct ctl_table *,int ,struct file *,void __user *,size_t *,loff_t *); +int percpu_pagelist_fraction_sysctl_handler (struct ctl_table *,int ,struct file *, +void __user *,size_t *,loff_t *);#include <linux/topology.h> /* Returns the number of the current Node. */
include/linux/sysctl.h +1 -0
@@ -183,6 +183,7 @@VM_SWAP_TOKEN_TIMEOUT =28 ,/* default time for token time out */ VM_DROP_PAGECACHE =29 ,/* int: nuke lots of pagecache */ VM_SWAP_PREFETCH =30 ,/* int: amount to swap prefetch */ + VM_PERCPU_PAGELIST_FRACTION=31,/* int: fraction of pages in each percpu_pagelist */ };
kernel/sysctl.c +12 -0
@@ -68,6 +68,7 @@extern int printk_ratelimit_jiffies;extern int printk_ratelimit_burst;extern int pid_max_min, pid_max_max; +extern int percpu_pagelist_fraction;#if defined(CONFIG_X86_LOCAL_APIC ) && defined(CONFIG_X86 )int unknown_nmi_panic;
@@ -78,6 +79,7 @@/* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */ static int maxolduid =65535 ;static int minolduid; +static int min_percpu_pagelist_fract =8 ;static int ngroups_max =NGROUPS_MAX ;
@@ -801,6 +803,16 @@ .strategy = &sysctl_intvec, .extra1 = &zero, }, + { + .ctl_name = VM_PERCPU_PAGELIST_FRACTION, + .procname = "percpu_pagelist_fraction", + .data = &percpu_pagelist_fraction, + .maxlen = sizeof(percpu_pagelist_fraction), + .mode = 0644, + .proc_handler = &percpu_pagelist_fraction_sysctl_handler, + .strategy = &sysctl_intvec, + .extra1 = &min_percpu_pagelist_fract, + }, #ifdef CONFIG_MMU { .ctl_name = VM_MAX_MAP_COUNT,
mm/page_alloc.c +43 -0
49 lines not on this page · raw message
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Review
Quoted 3 lines · Rohit Seth
(quoted diff) +1
-0+ if ((high/4) > (PAGE_SHIFT * 8)) + pcp->batch = PAGE_SHIFT * 8;
hm. What relationship is there between log2(PAGE_SIZE) and the batch quantity? I'd have thought that if anything, we'd want to make the batch sizes smaller for larger PAGE_SIZE. Or something.
Quoted 15 lines
+}
+
+/*
+ *percpu_pagelist_fraction- changes thepcp->highfor 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,
+ struct file *file, void__user*buffer,size_t*length,loff_t*ppos)
+{
+ struct zone *zone;
+ unsigned int cpu;
+ int ret;
+
Quoted 8 lines
+ ret =
proc_dointvec_minmax(table, write, file, buffer, length, ppos);
+ if (!write || (ret ==-EINVAL))
+ return ret;
+for_each_zone(zone){
+for_each_online_cpu(cpu){
+ unsigned long high;
+ high =zone->present_pages/percpu_pagelist_fraction;
+setup_pagelist_highmark(zone_pcp(zone, cpu), high);
What happens if a CPU comes online afterwards?
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 9 lines · Andrew Morton
Quoted 3 lines · Rohit Seth
+ if ((high/4) > (
PAGE_SHIFT* 8))
+pcp->batch=PAGE_SHIFT* 8;hm. What relationship is there between
log2(PAGE_SIZE)and the batch quantity? I'd have thought that if anything, we'd want to make the batch sizes smaller for largerPAGE_SIZE. Or something.
There is really no relationship between batch with either log2(PAGE_SIZE) or PAGE_SIZE. Larger page size machines typically go with larger memory configs so it is okay to have bigger batch count for those. But this can be worked either way. It is just a number of pages that will get pulled (and in some cases pushed back) from buddy allocator at any time. My initial attempts to make this some function of power of 2 and such have not gone anywhere.
Quoted 11 lines
Quoted 4 lines
+
for_each_zone(zone){
+for_each_online_cpu(cpu){
+ unsigned long high;
+ high =zone->present_pages/
percpu_pagelist_fraction;Quoted 1 line
+ setup_pagelist_highmark(zone_pcp(zone, cpu),
high);
What happens if a CPU comes online afterwards?
Good point. Right now the new cpu will use the original boot settings for the pagelist. I will send you a smaller patch to correct that. Basically check at the setup time if the percpu_pagelist_fraction is set or not and build the pagelist accordingly.
Thanks,
-rohit