diff --git a/include/linux/mm.h b/include/linux/mm.h index d29087c2fe2d711d353611e5411117ae8abb42da..e09f994c61b0c1ac1c3677e42a16d0fe6c0f347b 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -2613,6 +2613,7 @@ extern void memmap_init_zone(unsigned long, int, unsigned long, struct vmem_altmap *, int migratetype); extern void setup_per_zone_wmarks(void); extern int __meminit init_per_zone_wmark_min(void); +extern int __meminit init_min_cache_kbytes(void); extern void mem_init(void); extern void __init mmap_init(void); extern void show_mem(unsigned int flags, nodemask_t *nodemask); diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index 382293ca51c03c0d8bca70709afaf2ac98195e5e..9f2bc27d7f18103efbaec6ddaff5467740e50316 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -1122,6 +1122,7 @@ int __ref online_pages(unsigned long pfn, unsigned long nr_pages, shuffle_zone(zone); init_per_zone_wmark_min(); + init_min_cache_kbytes(); kswapd_run(nid); kcompactd_run(nid); @@ -1897,6 +1898,7 @@ int __ref offline_pages(unsigned long start_pfn, unsigned long nr_pages, adjust_present_page_count(pfn_to_page(start_pfn), group, -nr_pages); init_per_zone_wmark_min(); + init_min_cache_kbytes(); if (!populated_zone(zone)) { zone_pcp_reset(zone); diff --git a/mm/page_alloc.c b/mm/page_alloc.c index c9df8967dca155f4b3fe422a1312f2111a67e571..f4233ca7252e6606dfa93c0e8c94add40a006922 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -8817,6 +8817,40 @@ static void setup_min_cache_kbytes(void) } } +/* + * Initialise min_cache_kbytes. + * + * 0 < total memory <= 4G, min_cache_kbytes: 150M + * 4G < total memory <= 8G, min_cache_kbytes: 300M + * 8G < total memory <= 16G, min_cache_kbytes: 400M + * 16G < total memory <= 128G, min_cache_kbytes: 500M + * total memory > 128G, min_cache_kbytes: 1024M + */ + +int __meminit init_min_cache_kbytes(void) +{ + unsigned long total_ram_bytes = totalram_pages() << PAGE_SHIFT; + + if (total_ram_bytes <= 4UL * SZ_1G) + /* limit min_cache_kbytes to 1/2 of total memory at most */ + if (total_ram_bytes / 2 < 150 * SZ_1M) + sysctl_min_cache_kbytes = total_ram_bytes / 2 / SZ_1K; + else + sysctl_min_cache_kbytes = 150 * SZ_1K; + else if (total_ram_bytes <= 8UL * SZ_1G) + sysctl_min_cache_kbytes = 300 * SZ_1K; + else if (total_ram_bytes <= 16UL * SZ_1G) + sysctl_min_cache_kbytes = 400 * SZ_1K; + else if (total_ram_bytes <= 128UL * SZ_1G) + sysctl_min_cache_kbytes = 500 * SZ_1K; + else + sysctl_min_cache_kbytes = 1024 * SZ_1K; + + setup_min_cache_kbytes(); + + return 0; +} +postcore_initcall(init_min_cache_kbytes) int sysctl_min_cache_kbytes_sysctl_handler(struct ctl_table *table, int write, void __user *buffer, size_t *length, loff_t *ppos)