diff options
Diffstat (limited to 'patches/boot_time_opt/0154-sysctl-vm-Fine-grained-cache-shrinking.patch')
-rw-r--r-- | patches/boot_time_opt/0154-sysctl-vm-Fine-grained-cache-shrinking.patch | 137 |
1 files changed, 0 insertions, 137 deletions
diff --git a/patches/boot_time_opt/0154-sysctl-vm-Fine-grained-cache-shrinking.patch b/patches/boot_time_opt/0154-sysctl-vm-Fine-grained-cache-shrinking.patch deleted file mode 100644 index 64021c6..0000000 --- a/patches/boot_time_opt/0154-sysctl-vm-Fine-grained-cache-shrinking.patch +++ /dev/null | |||
@@ -1,137 +0,0 @@ | |||
1 | From 130d5d976b920aec243e0fa63273f3143660054b Mon Sep 17 00:00:00 2001 | ||
2 | From: Sebastien Boeuf <sebastien.boeuf@intel.com> | ||
3 | Date: Mon, 23 Jan 2017 15:32:39 -0800 | ||
4 | Subject: [PATCH 154/154] sysctl: vm: Fine-grained cache shrinking | ||
5 | |||
6 | Lots of virtual machines are let in idle state for days until they | ||
7 | are terminated, and they can keep a large amount of memory in their | ||
8 | cache, meaning this memory cannot be used by other processes. | ||
9 | |||
10 | We tried to release this memory using existing drop_caches sysctl, | ||
11 | but it led to the complete cache loss while it could have been used | ||
12 | whether the idle process wakes up. Indeed, the process can't find any | ||
13 | available cached data and it directly affects performances to rebuild | ||
14 | it from scratch. | ||
15 | |||
16 | Instead, the solution we want is based on shrinking gradually system | ||
17 | cache over time. This patch adds a new sysctl shrink_caches_mb so as | ||
18 | to allow userspace applications indicating the kernel it should shrink | ||
19 | system cache up to the amount (in MiB) specified. | ||
20 | |||
21 | There is an application called "memshrinker" which uses this new | ||
22 | mechanism. It runs in the background and periodically releases a | ||
23 | specified amount of cache. This amount is based on the remaining | ||
24 | cache on the system, and period is computed to follow a shrinking | ||
25 | model. It results in saving a lot of memory for other processes | ||
26 | running on the system. | ||
27 | |||
28 | Suggested-by: Arjan van de Ven <arjan.van.de.ven@intel.com> | ||
29 | Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com> | ||
30 | --- | ||
31 | fs/drop_caches.c | 25 +++++++++++++++++++++++++ | ||
32 | include/linux/mm.h | 4 ++++ | ||
33 | kernel/sysctl.c | 8 ++++++++ | ||
34 | mm/vmscan.c | 2 -- | ||
35 | 4 files changed, 37 insertions(+), 2 deletions(-) | ||
36 | |||
37 | diff --git a/fs/drop_caches.c b/fs/drop_caches.c | ||
38 | index 82377017130f..f8de1383498b 100644 | ||
39 | --- a/fs/drop_caches.c | ||
40 | +++ b/fs/drop_caches.c | ||
41 | @@ -9,10 +9,12 @@ | ||
42 | #include <linux/writeback.h> | ||
43 | #include <linux/sysctl.h> | ||
44 | #include <linux/gfp.h> | ||
45 | +#include <linux/swap.h> | ||
46 | #include "internal.h" | ||
47 | |||
48 | /* A global variable is a bit ugly, but it keeps the code simple */ | ||
49 | int sysctl_drop_caches; | ||
50 | +int sysctl_shrink_caches_mb; | ||
51 | |||
52 | static void drop_pagecache_sb(struct super_block *sb, void *unused) | ||
53 | { | ||
54 | @@ -68,3 +70,26 @@ int drop_caches_sysctl_handler(struct ctl_table *table, int write, | ||
55 | } | ||
56 | return 0; | ||
57 | } | ||
58 | + | ||
59 | +int shrink_caches_sysctl_handler(struct ctl_table *table, int write, | ||
60 | + void __user *buffer, size_t *length, loff_t *ppos) | ||
61 | +{ | ||
62 | + int ret; | ||
63 | + unsigned long nr_to_reclaim, page_reclaimed; | ||
64 | + | ||
65 | + ret = proc_dointvec_minmax(table, write, buffer, length, ppos); | ||
66 | + if (ret) | ||
67 | + return ret; | ||
68 | + | ||
69 | + nr_to_reclaim = sysctl_shrink_caches_mb * (1 << 20) / PAGE_SIZE; | ||
70 | + if (write) { | ||
71 | + page_reclaimed = shrink_all_memory(nr_to_reclaim); | ||
72 | + if (page_reclaimed > 0) | ||
73 | + lru_add_drain_all(); | ||
74 | + | ||
75 | + if (page_reclaimed != nr_to_reclaim) | ||
76 | + return page_reclaimed; | ||
77 | + } | ||
78 | + | ||
79 | + return 0; | ||
80 | +} | ||
81 | diff --git a/include/linux/mm.h b/include/linux/mm.h | ||
82 | index 15e02bf3a6b3..9f9b967ad2c9 100644 | ||
83 | --- a/include/linux/mm.h | ||
84 | +++ b/include/linux/mm.h | ||
85 | @@ -2457,6 +2457,10 @@ extern int kvm_ret_mem_advice; | ||
86 | int kvm_madv_instant_free_sysctl_handler(struct ctl_table *table, int write, | ||
87 | void __user *buffer, size_t *length, | ||
88 | loff_t *ppos); | ||
89 | +extern int sysctl_shrink_caches_mb; | ||
90 | +int shrink_caches_sysctl_handler(struct ctl_table *table, int write, | ||
91 | + void __user *buffer, size_t *length, | ||
92 | + loff_t *ppos); | ||
93 | #endif | ||
94 | |||
95 | void drop_slab(void); | ||
96 | diff --git a/kernel/sysctl.c b/kernel/sysctl.c | ||
97 | index 9a1611f92a2a..9b74b4f0251d 100644 | ||
98 | --- a/kernel/sysctl.c | ||
99 | +++ b/kernel/sysctl.c | ||
100 | @@ -1417,6 +1417,14 @@ static struct ctl_table vm_table[] = { | ||
101 | .mode = 0644, | ||
102 | .proc_handler = kvm_madv_instant_free_sysctl_handler, | ||
103 | }, | ||
104 | + { | ||
105 | + .procname = "shrink_caches_mb", | ||
106 | + .data = &sysctl_shrink_caches_mb, | ||
107 | + .maxlen = sizeof(int), | ||
108 | + .mode = 0644, | ||
109 | + .proc_handler = shrink_caches_sysctl_handler, | ||
110 | + .extra1 = &one, | ||
111 | + }, | ||
112 | #ifdef CONFIG_COMPACTION | ||
113 | { | ||
114 | .procname = "compact_memory", | ||
115 | diff --git a/mm/vmscan.c b/mm/vmscan.c | ||
116 | index eb2f0315b8c0..b16f327b0211 100644 | ||
117 | --- a/mm/vmscan.c | ||
118 | +++ b/mm/vmscan.c | ||
119 | @@ -3646,7 +3646,6 @@ void wakeup_kswapd(struct zone *zone, int order, enum zone_type classzone_idx) | ||
120 | wake_up_interruptible(&pgdat->kswapd_wait); | ||
121 | } | ||
122 | |||
123 | -#ifdef CONFIG_HIBERNATION | ||
124 | /* | ||
125 | * Try to free `nr_to_reclaim' of memory, system-wide, and return the number of | ||
126 | * freed pages. | ||
127 | @@ -3686,7 +3685,6 @@ unsigned long shrink_all_memory(unsigned long nr_to_reclaim) | ||
128 | |||
129 | return nr_reclaimed; | ||
130 | } | ||
131 | -#endif /* CONFIG_HIBERNATION */ | ||
132 | |||
133 | /* It's optimal to keep kswapds on the same CPUs as their memory, but | ||
134 | not required for correctness. So if the last cpu in a node goes | ||
135 | -- | ||
136 | 2.15.0 | ||
137 | |||