diff options
-rw-r--r-- | Documentation/sysctl/vm.txt | 15 | ||||
-rw-r--r-- | include/linux/compaction.h | 3 | ||||
-rw-r--r-- | kernel/sysctl.c | 15 | ||||
-rw-r--r-- | mm/compaction.c | 12 |
4 files changed, 44 insertions, 1 deletions
diff --git a/Documentation/sysctl/vm.txt b/Documentation/sysctl/vm.txt index 56dd29b97a91..5fdbb612aeb8 100644 --- a/Documentation/sysctl/vm.txt +++ b/Documentation/sysctl/vm.txt | |||
@@ -27,6 +27,7 @@ Currently, these files are in /proc/sys/vm: | |||
27 | - dirty_ratio | 27 | - dirty_ratio |
28 | - dirty_writeback_centisecs | 28 | - dirty_writeback_centisecs |
29 | - drop_caches | 29 | - drop_caches |
30 | - extfrag_threshold | ||
30 | - hugepages_treat_as_movable | 31 | - hugepages_treat_as_movable |
31 | - hugetlb_shm_group | 32 | - hugetlb_shm_group |
32 | - laptop_mode | 33 | - laptop_mode |
@@ -149,6 +150,20 @@ user should run `sync' first. | |||
149 | 150 | ||
150 | ============================================================== | 151 | ============================================================== |
151 | 152 | ||
153 | extfrag_threshold | ||
154 | |||
155 | This parameter affects whether the kernel will compact memory or direct | ||
156 | reclaim to satisfy a high-order allocation. /proc/extfrag_index shows what | ||
157 | the fragmentation index for each order is in each zone in the system. Values | ||
158 | tending towards 0 imply allocations would fail due to lack of memory, | ||
159 | values towards 1000 imply failures are due to fragmentation and -1 implies | ||
160 | that the allocation will succeed as long as watermarks are met. | ||
161 | |||
162 | The kernel will not compact memory in a zone if the | ||
163 | fragmentation index is <= extfrag_threshold. The default value is 500. | ||
164 | |||
165 | ============================================================== | ||
166 | |||
152 | hugepages_treat_as_movable | 167 | hugepages_treat_as_movable |
153 | 168 | ||
154 | This parameter is only useful when kernelcore= is specified at boot time to | 169 | This parameter is only useful when kernelcore= is specified at boot time to |
diff --git a/include/linux/compaction.h b/include/linux/compaction.h index eed40ec4280b..3719325c6091 100644 --- a/include/linux/compaction.h +++ b/include/linux/compaction.h | |||
@@ -15,6 +15,9 @@ | |||
15 | extern int sysctl_compact_memory; | 15 | extern int sysctl_compact_memory; |
16 | extern int sysctl_compaction_handler(struct ctl_table *table, int write, | 16 | extern int sysctl_compaction_handler(struct ctl_table *table, int write, |
17 | void __user *buffer, size_t *length, loff_t *ppos); | 17 | void __user *buffer, size_t *length, loff_t *ppos); |
18 | extern int sysctl_extfrag_threshold; | ||
19 | extern int sysctl_extfrag_handler(struct ctl_table *table, int write, | ||
20 | void __user *buffer, size_t *length, loff_t *ppos); | ||
18 | 21 | ||
19 | extern int fragmentation_index(struct zone *zone, unsigned int order); | 22 | extern int fragmentation_index(struct zone *zone, unsigned int order); |
20 | extern unsigned long try_to_compact_pages(struct zonelist *zonelist, | 23 | extern unsigned long try_to_compact_pages(struct zonelist *zonelist, |
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 284f330d6a01..84ff5e75c084 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
@@ -263,6 +263,11 @@ static int min_sched_shares_ratelimit = 100000; /* 100 usec */ | |||
263 | static int max_sched_shares_ratelimit = NSEC_PER_SEC; /* 1 second */ | 263 | static int max_sched_shares_ratelimit = NSEC_PER_SEC; /* 1 second */ |
264 | #endif | 264 | #endif |
265 | 265 | ||
266 | #ifdef CONFIG_COMPACTION | ||
267 | static int min_extfrag_threshold; | ||
268 | static int max_extfrag_threshold = 1000; | ||
269 | #endif | ||
270 | |||
266 | static struct ctl_table kern_table[] = { | 271 | static struct ctl_table kern_table[] = { |
267 | { | 272 | { |
268 | .procname = "sched_child_runs_first", | 273 | .procname = "sched_child_runs_first", |
@@ -1130,6 +1135,16 @@ static struct ctl_table vm_table[] = { | |||
1130 | .mode = 0200, | 1135 | .mode = 0200, |
1131 | .proc_handler = sysctl_compaction_handler, | 1136 | .proc_handler = sysctl_compaction_handler, |
1132 | }, | 1137 | }, |
1138 | { | ||
1139 | .procname = "extfrag_threshold", | ||
1140 | .data = &sysctl_extfrag_threshold, | ||
1141 | .maxlen = sizeof(int), | ||
1142 | .mode = 0644, | ||
1143 | .proc_handler = sysctl_extfrag_handler, | ||
1144 | .extra1 = &min_extfrag_threshold, | ||
1145 | .extra2 = &max_extfrag_threshold, | ||
1146 | }, | ||
1147 | |||
1133 | #endif /* CONFIG_COMPACTION */ | 1148 | #endif /* CONFIG_COMPACTION */ |
1134 | { | 1149 | { |
1135 | .procname = "min_free_kbytes", | 1150 | .procname = "min_free_kbytes", |
diff --git a/mm/compaction.c b/mm/compaction.c index 9583e193dc47..94cce51b0b35 100644 --- a/mm/compaction.c +++ b/mm/compaction.c | |||
@@ -433,6 +433,8 @@ static unsigned long compact_zone_order(struct zone *zone, | |||
433 | return compact_zone(zone, &cc); | 433 | return compact_zone(zone, &cc); |
434 | } | 434 | } |
435 | 435 | ||
436 | int sysctl_extfrag_threshold = 500; | ||
437 | |||
436 | /** | 438 | /** |
437 | * try_to_compact_pages - Direct compact to satisfy a high-order allocation | 439 | * try_to_compact_pages - Direct compact to satisfy a high-order allocation |
438 | * @zonelist: The zonelist used for the current allocation | 440 | * @zonelist: The zonelist used for the current allocation |
@@ -491,7 +493,7 @@ unsigned long try_to_compact_pages(struct zonelist *zonelist, | |||
491 | * Only compact if a failure would be due to fragmentation. | 493 | * Only compact if a failure would be due to fragmentation. |
492 | */ | 494 | */ |
493 | fragindex = fragmentation_index(zone, order); | 495 | fragindex = fragmentation_index(zone, order); |
494 | if (fragindex >= 0 && fragindex <= 500) | 496 | if (fragindex >= 0 && fragindex <= sysctl_extfrag_threshold) |
495 | continue; | 497 | continue; |
496 | 498 | ||
497 | if (fragindex == -1 && zone_watermark_ok(zone, order, watermark, 0, 0)) { | 499 | if (fragindex == -1 && zone_watermark_ok(zone, order, watermark, 0, 0)) { |
@@ -572,6 +574,14 @@ int sysctl_compaction_handler(struct ctl_table *table, int write, | |||
572 | return 0; | 574 | return 0; |
573 | } | 575 | } |
574 | 576 | ||
577 | int sysctl_extfrag_handler(struct ctl_table *table, int write, | ||
578 | void __user *buffer, size_t *length, loff_t *ppos) | ||
579 | { | ||
580 | proc_dointvec_minmax(table, write, buffer, length, ppos); | ||
581 | |||
582 | return 0; | ||
583 | } | ||
584 | |||
575 | #if defined(CONFIG_SYSFS) && defined(CONFIG_NUMA) | 585 | #if defined(CONFIG_SYSFS) && defined(CONFIG_NUMA) |
576 | ssize_t sysfs_compact_node(struct sys_device *dev, | 586 | ssize_t sysfs_compact_node(struct sys_device *dev, |
577 | struct sysdev_attribute *attr, | 587 | struct sysdev_attribute *attr, |