Loading Documentation/sysctl/vm.txt +16 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ Currently, these files are in /proc/sys/vm: - dirty_writeback_centisecs - drop_caches - extfrag_threshold - extra_free_kbytes - hugepages_treat_as_movable - hugetlb_shm_group - laptop_mode Loading Loading @@ -240,6 +241,21 @@ fragmentation index is <= extfrag_threshold. The default value is 500. ============================================================== extra_free_kbytes This parameter tells the VM to keep extra free memory between the threshold where background reclaim (kswapd) kicks in, and the threshold where direct reclaim (by allocating processes) kicks in. This is useful for workloads that require low latency memory allocations and have a bounded burstiness in memory allocations, for example a realtime application that receives and transmits network traffic (causing in-kernel memory allocations) with a maximum total message burst size of 200MB may need 200MB of extra free memory to avoid direct reclaim related latencies. ============================================================== hugepages_treat_as_movable This parameter controls whether we can allocate hugepages from ZONE_MOVABLE Loading include/linux/mm.h +1 −0 Original line number Diff line number Diff line Loading @@ -1901,6 +1901,7 @@ extern void zone_pcp_reset(struct zone *zone); /* page_alloc.c */ extern int min_free_kbytes; extern int watermark_scale_factor; extern int extra_free_kbytes; /* nommu.c */ extern atomic_long_t mmap_pages_allocated; Loading kernel/sysctl.c +12 −2 Original line number Diff line number Diff line Loading @@ -127,7 +127,9 @@ static int __maybe_unused three = 3; static int __maybe_unused four = 4; static unsigned long one_ul = 1; static int one_hundred = 100; #ifdef CONFIG_PERF_EVENTS static int one_thousand = 1000; #endif #ifdef CONFIG_PRINTK static int ten_thousand = 10000; #endif Loading Loading @@ -1572,8 +1574,16 @@ static struct ctl_table vm_table[] = { .maxlen = sizeof(watermark_scale_factor), .mode = 0644, .proc_handler = watermark_scale_factor_sysctl_handler, .extra1 = &one, .extra2 = &one_thousand, .extra1 = &zero, .extra2 = &zero, }, { .procname = "extra_free_kbytes", .data = &extra_free_kbytes, .maxlen = sizeof(extra_free_kbytes), .mode = 0644, .proc_handler = min_free_kbytes_sysctl_handler, .extra1 = &zero, }, { .procname = "percpu_pagelist_fraction", Loading mm/page_alloc.c +26 −9 Original line number Diff line number Diff line Loading @@ -254,9 +254,21 @@ compound_page_dtor * const compound_page_dtors[] = { #endif }; /* * Try to keep at least this much lowmem free. Do not allow normal * allocations below this point, only high priority ones. Automatically * tuned according to the amount of memory in the system. */ int min_free_kbytes = 1024; int user_min_free_kbytes = -1; int watermark_scale_factor = 10; int watermark_scale_factor; /* * Extra memory for the system to try freeing. Used to temporarily * free memory, to make space for new workloads. Anyone can allocate * down to the min watermarks controlled by min_free_kbytes above. */ int extra_free_kbytes; static unsigned long __meminitdata nr_kernel_pages; static unsigned long __meminitdata nr_all_pages; Loading Loading @@ -6742,6 +6754,7 @@ static void setup_per_zone_lowmem_reserve(void) static void __setup_per_zone_wmarks(void) { unsigned long pages_min = min_free_kbytes >> (PAGE_SHIFT - 10); unsigned long pages_low = extra_free_kbytes >> (PAGE_SHIFT - 10); unsigned long lowmem_pages = 0; struct zone *zone; unsigned long flags; Loading @@ -6753,11 +6766,14 @@ static void __setup_per_zone_wmarks(void) } for_each_zone(zone) { u64 tmp; u64 min, low; spin_lock_irqsave(&zone->lock, flags); tmp = (u64)pages_min * zone->managed_pages; do_div(tmp, lowmem_pages); min = (u64)pages_min * zone->managed_pages; do_div(min, lowmem_pages); low = (u64)pages_low * zone->managed_pages; do_div(low, vm_total_pages); if (is_highmem(zone)) { /* * __GFP_HIGH and PF_MEMALLOC allocations usually don't Loading @@ -6778,7 +6794,7 @@ static void __setup_per_zone_wmarks(void) * If it's a lowmem zone, reserve a number of pages * proportionate to the zone's size. */ zone->watermark[WMARK_MIN] = tmp; zone->watermark[WMARK_MIN] = min; } /* Loading @@ -6786,12 +6802,13 @@ static void __setup_per_zone_wmarks(void) * scale factor in proportion to available memory, but * ensure a minimum size on small systems. */ tmp = max_t(u64, tmp >> 2, min = max_t(u64, min >> 2, mult_frac(zone->managed_pages, watermark_scale_factor, 10000)); zone->watermark[WMARK_LOW] = min_wmark_pages(zone) + tmp; zone->watermark[WMARK_HIGH] = min_wmark_pages(zone) + tmp * 2; zone->watermark[WMARK_LOW] = min_wmark_pages(zone) + low + min; zone->watermark[WMARK_HIGH] = min_wmark_pages(zone) + low + min * 2; spin_unlock_irqrestore(&zone->lock, flags); } Loading Loading @@ -6872,7 +6889,7 @@ core_initcall(init_per_zone_wmark_min) /* * min_free_kbytes_sysctl_handler - just a wrapper around proc_dointvec() so * that we can call two helper functions whenever min_free_kbytes * changes. * or extra_free_kbytes changes. */ int min_free_kbytes_sysctl_handler(struct ctl_table *table, int write, void __user *buffer, size_t *length, loff_t *ppos) Loading Loading
Documentation/sysctl/vm.txt +16 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ Currently, these files are in /proc/sys/vm: - dirty_writeback_centisecs - drop_caches - extfrag_threshold - extra_free_kbytes - hugepages_treat_as_movable - hugetlb_shm_group - laptop_mode Loading Loading @@ -240,6 +241,21 @@ fragmentation index is <= extfrag_threshold. The default value is 500. ============================================================== extra_free_kbytes This parameter tells the VM to keep extra free memory between the threshold where background reclaim (kswapd) kicks in, and the threshold where direct reclaim (by allocating processes) kicks in. This is useful for workloads that require low latency memory allocations and have a bounded burstiness in memory allocations, for example a realtime application that receives and transmits network traffic (causing in-kernel memory allocations) with a maximum total message burst size of 200MB may need 200MB of extra free memory to avoid direct reclaim related latencies. ============================================================== hugepages_treat_as_movable This parameter controls whether we can allocate hugepages from ZONE_MOVABLE Loading
include/linux/mm.h +1 −0 Original line number Diff line number Diff line Loading @@ -1901,6 +1901,7 @@ extern void zone_pcp_reset(struct zone *zone); /* page_alloc.c */ extern int min_free_kbytes; extern int watermark_scale_factor; extern int extra_free_kbytes; /* nommu.c */ extern atomic_long_t mmap_pages_allocated; Loading
kernel/sysctl.c +12 −2 Original line number Diff line number Diff line Loading @@ -127,7 +127,9 @@ static int __maybe_unused three = 3; static int __maybe_unused four = 4; static unsigned long one_ul = 1; static int one_hundred = 100; #ifdef CONFIG_PERF_EVENTS static int one_thousand = 1000; #endif #ifdef CONFIG_PRINTK static int ten_thousand = 10000; #endif Loading Loading @@ -1572,8 +1574,16 @@ static struct ctl_table vm_table[] = { .maxlen = sizeof(watermark_scale_factor), .mode = 0644, .proc_handler = watermark_scale_factor_sysctl_handler, .extra1 = &one, .extra2 = &one_thousand, .extra1 = &zero, .extra2 = &zero, }, { .procname = "extra_free_kbytes", .data = &extra_free_kbytes, .maxlen = sizeof(extra_free_kbytes), .mode = 0644, .proc_handler = min_free_kbytes_sysctl_handler, .extra1 = &zero, }, { .procname = "percpu_pagelist_fraction", Loading
mm/page_alloc.c +26 −9 Original line number Diff line number Diff line Loading @@ -254,9 +254,21 @@ compound_page_dtor * const compound_page_dtors[] = { #endif }; /* * Try to keep at least this much lowmem free. Do not allow normal * allocations below this point, only high priority ones. Automatically * tuned according to the amount of memory in the system. */ int min_free_kbytes = 1024; int user_min_free_kbytes = -1; int watermark_scale_factor = 10; int watermark_scale_factor; /* * Extra memory for the system to try freeing. Used to temporarily * free memory, to make space for new workloads. Anyone can allocate * down to the min watermarks controlled by min_free_kbytes above. */ int extra_free_kbytes; static unsigned long __meminitdata nr_kernel_pages; static unsigned long __meminitdata nr_all_pages; Loading Loading @@ -6742,6 +6754,7 @@ static void setup_per_zone_lowmem_reserve(void) static void __setup_per_zone_wmarks(void) { unsigned long pages_min = min_free_kbytes >> (PAGE_SHIFT - 10); unsigned long pages_low = extra_free_kbytes >> (PAGE_SHIFT - 10); unsigned long lowmem_pages = 0; struct zone *zone; unsigned long flags; Loading @@ -6753,11 +6766,14 @@ static void __setup_per_zone_wmarks(void) } for_each_zone(zone) { u64 tmp; u64 min, low; spin_lock_irqsave(&zone->lock, flags); tmp = (u64)pages_min * zone->managed_pages; do_div(tmp, lowmem_pages); min = (u64)pages_min * zone->managed_pages; do_div(min, lowmem_pages); low = (u64)pages_low * zone->managed_pages; do_div(low, vm_total_pages); if (is_highmem(zone)) { /* * __GFP_HIGH and PF_MEMALLOC allocations usually don't Loading @@ -6778,7 +6794,7 @@ static void __setup_per_zone_wmarks(void) * If it's a lowmem zone, reserve a number of pages * proportionate to the zone's size. */ zone->watermark[WMARK_MIN] = tmp; zone->watermark[WMARK_MIN] = min; } /* Loading @@ -6786,12 +6802,13 @@ static void __setup_per_zone_wmarks(void) * scale factor in proportion to available memory, but * ensure a minimum size on small systems. */ tmp = max_t(u64, tmp >> 2, min = max_t(u64, min >> 2, mult_frac(zone->managed_pages, watermark_scale_factor, 10000)); zone->watermark[WMARK_LOW] = min_wmark_pages(zone) + tmp; zone->watermark[WMARK_HIGH] = min_wmark_pages(zone) + tmp * 2; zone->watermark[WMARK_LOW] = min_wmark_pages(zone) + low + min; zone->watermark[WMARK_HIGH] = min_wmark_pages(zone) + low + min * 2; spin_unlock_irqrestore(&zone->lock, flags); } Loading Loading @@ -6872,7 +6889,7 @@ core_initcall(init_per_zone_wmark_min) /* * min_free_kbytes_sysctl_handler - just a wrapper around proc_dointvec() so * that we can call two helper functions whenever min_free_kbytes * changes. * or extra_free_kbytes changes. */ int min_free_kbytes_sysctl_handler(struct ctl_table *table, int write, void __user *buffer, size_t *length, loff_t *ppos) Loading