-
Notifications
You must be signed in to change notification settings - Fork 0
/
my_shrink_memory_changes_SBPA.patch
executable file
·329 lines (308 loc) · 9.81 KB
/
my_shrink_memory_changes_SBPA.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
diff --git a/drivers/gpu/ion/ion_system_heap.c b/drivers/gpu/ion/ion_system_heap.c
index 96565bb..57f3d5a 100644
--- a/drivers/gpu/ion/ion_system_heap.c
+++ b/drivers/gpu/ion/ion_system_heap.c
@@ -26,6 +26,12 @@
#include <linux/vmalloc.h>
#include <linux/list_sort.h>
#include "ion_priv.h"
+#ifdef CONFIG_SHRINK_MEMORY
+#include <linux/swap.h>
+#include <linux/interrupt.h>
+#include <linux/compaction.h>
+#include <linux/delay.h>
+#endif
static unsigned int high_order_gfp_flags = (GFP_HIGHUSER | __GFP_ZERO |
__GFP_NOWARN | __GFP_NORETRY |
@@ -155,6 +161,28 @@ static struct page_info *alloc_deferred_page(struct ion_system_heap *heap,
return found;
}
+#ifdef CONFIG_SHRINK_MEMORY
+static DEFINE_SPINLOCK(shrink_lock);
+static struct work_struct shrink_memory_work;
+//static struct tasklet_struct shrink_memory_work;
+static void shrink_memory_handler(struct work_struct *work)
+//static void ion_shrink_memory_tasklet_handler(unsigned long data)
+{
+ unsigned long int nr_pages = 0;
+ unsigned long flags;
+ int i;
+ spin_lock_irqsave(&shrink_lock, flags);
+ for (i=0; i<5; i++) {
+ nr_pages += shrink_all_memory(totalram_pages/2);
+ compact_nodes();
+ ssleep(1);
+ }
+ spin_unlock_irqrestore(&shrink_lock, flags);
+ pr_info("[shrink_memory_handler]: Total pages shrinked: %lu\n", nr_pages);
+}
+//static DECLARE_TASKLET(ion_tasklet_shrink_memory, ion_shrink_memory_tasklet_handler, 0);
+#endif
+
static struct page_info *alloc_largest_available(struct ion_system_heap *heap,
struct ion_buffer *buffer,
unsigned long size,
@@ -178,8 +206,15 @@ static struct page_info *alloc_largest_available(struct ion_system_heap *heap,
orders[i]);
if (!info) {
page = alloc_buffer_page(heap, buffer, orders[i]);
- if (!page)
+ if (!page) {
+ #if 0
+ if (IS_ENABLED(CONFIG_SHRINK_MEMORY) && (orders[i] == 4)) {
+ schedule_work(&shrink_memory_work);
+ //tasklet_schedule(&ion_tasklet_shrink_memory);
+ }
+ #endif
continue;
+ }
info = kmalloc(sizeof(struct page_info), GFP_KERNEL);
/*
@@ -231,12 +266,18 @@ static int ion_system_heap_allocate(struct ion_heap *heap,
int i = 0;
long size_remaining = PAGE_ALIGN(size);
unsigned int max_order = orders[0];
+ struct timeval val_start;
+ struct timeval val_end;
+ uint64_t time_start;
+ uint64_t time_end;
priv = kmalloc(sizeof(struct ion_system_buffer_info), GFP_KERNEL);
if (!priv)
return -ENOMEM;
INIT_LIST_HEAD(&priv->pages);
+ do_gettimeofday(&val_start);
+ time_start = val_start.tv_sec * 1000000 + val_start.tv_usec;
while (size_remaining > 0) {
info = alloc_largest_available(sys_heap, buffer, size_remaining, max_order);
if (!info)
@@ -246,6 +287,15 @@ static int ion_system_heap_allocate(struct ion_heap *heap,
max_order = info->order;
i++;
}
+ do_gettimeofday(&val_end);
+ time_end = val_end.tv_sec * 1000000 + val_end.tv_usec;
+ pr_info("%s, size:%8ld, time:%8lld us\n", __func__, size,
+ (time_end - time_start));
+
+ if ( (time_end - time_start) > 2000) {
+ if (IS_ENABLED(CONFIG_SHRINK_MEMORY))
+ schedule_work(&shrink_memory_work);
+ }
ret = sg_alloc_table(&priv->table, i, GFP_KERNEL);
if (ret)
@@ -542,6 +592,10 @@ struct ion_heap *ion_system_heap_create(struct ion_platform_heap *unused)
heap->heap.shrinker.batch = 0;
register_shrinker(&heap->heap.shrinker);
heap->heap.debug_show = ion_system_heap_debug_show;
+ #if 1
+ if (IS_ENABLED(CONFIG_SHRINK_MEMORY))
+ INIT_WORK(&shrink_memory_work, shrink_memory_handler);
+ #endif
return &heap->heap;
err_create_pool:
for (i = 0; i < num_orders; i++)
diff --git a/include/linux/compaction.h b/include/linux/compaction.h
index 091d72e..443e94b 100644
--- a/include/linux/compaction.h
+++ b/include/linux/compaction.h
@@ -26,6 +26,7 @@ extern unsigned long try_to_compact_pages(struct zonelist *zonelist,
extern void compact_pgdat(pg_data_t *pgdat, int order);
extern void reset_isolation_suitable(pg_data_t *pgdat);
extern unsigned long compaction_suitable(struct zone *zone, int order);
+extern void compact_nodes(void);
/* Do not skip compaction more than 64 times */
#define COMPACT_MAX_DEFER_SHIFT 6
diff --git a/include/linux/vm_event_item.h b/include/linux/vm_event_item.h
index bd6cf61..68412c3 100644
--- a/include/linux/vm_event_item.h
+++ b/include/linux/vm_event_item.h
@@ -36,7 +36,7 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT,
#endif
PGINODESTEAL, SLABS_SCANNED, KSWAPD_INODESTEAL,
KSWAPD_LOW_WMARK_HIT_QUICKLY, KSWAPD_HIGH_WMARK_HIT_QUICKLY,
- PAGEOUTRUN, ALLOCSTALL, PGROTATED,
+ PAGEOUTRUN, ALLOCSTALL, SLOWPATH_ENTERED, PGROTATED,
#ifdef CONFIG_NUMA_BALANCING
NUMA_PTE_UPDATES,
NUMA_HINT_FAULTS,
diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
index 6b8171c..0085b26 100755
--- a/kernel/power/suspend.c
+++ b/kernel/power/suspend.c
@@ -27,6 +27,9 @@
#include <linux/ftrace.h>
#include <linux/rtc.h>
#include <trace/events/power.h>
+#ifdef CONFIG_SHRINK_MEMORY
+#include <linux/swap.h>
+#endif
#if defined (CONFIG_SEC_GPIO_DVS)
#include <linux/secgpio_dvs.h>
@@ -125,6 +128,8 @@ static int suspend_test(int level)
static int suspend_prepare(void)
{
int error;
+ int i;
+ unsigned long nr_pages = 0;
if (!suspend_ops || !suspend_ops->enter)
return -EPERM;
@@ -138,8 +143,15 @@ static int suspend_prepare(void)
goto Finish;
error = suspend_freeze_processes();
- if (!error)
+ if (!error) {
+#if 0
+ for (i=0; i<10; i++) {
+ nr_pages += shrink_all_memory(totalram_pages);
+ }
+ pr_info("[suspend_prepare]: Total pages freed: %lu\n", nr_pages);
+#endif
return 0;
+ }
suspend_stats.failed_freeze++;
dpm_save_failed_step(SUSPEND_FREEZE);
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 238cbd1..07bced5 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -274,6 +274,11 @@ static int min_extfrag_threshold;
static int max_extfrag_threshold = 1000;
#endif
+#ifdef CONFIG_SHRINK_MEMORY
+static int min_shrink_memory = 1;
+static int max_shrink_memory = 1;
+#endif
+
static struct ctl_table kern_table[] = {
{
.procname = "sched_child_runs_first",
@@ -1266,6 +1271,8 @@ static struct ctl_table vm_table[] = {
.maxlen = sizeof(int),
.mode = 0222,
.proc_handler = sysctl_shrinkmem_handler,
+ .extra1 = &min_shrink_memory,
+ .extra2 = &max_shrink_memory,
},
#endif
{
diff --git a/mm/compaction.c b/mm/compaction.c
index 9a75d4e..1413835 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -1156,7 +1156,7 @@ static void compact_node(int nid)
}
/* Compact all nodes in the system */
-static void compact_nodes(void)
+void compact_nodes(void)
{
int nid;
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 50180d6..f8191c8 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -4984,6 +4984,10 @@ static int mem_cgroup_force_reclaim(struct cgroup *cont, struct cftype *cft, u64
unsigned long nr_to_reclaim = val;
unsigned long total = 0;
int loop;
+ //unsigned long nr_pages = 0;
+
+ //nr_pages = shrink_all_memory(totalram_pages);
+ //pr_info("%s: Total pages shrinked: %lu\n", __func__, nr_pages);
for (loop = 0; loop < MEM_CGROUP_MAX_RECLAIM_LOOPS; loop++) {
total += try_to_free_mem_cgroup_pages(memcg, GFP_KERNEL, false);
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 7aa1f9f..4fa4f11 100755
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -896,7 +896,7 @@ static int prep_new_page(struct page *page, int order, gfp_t gfp_flags)
return 0;
}
-#define CONFIG_BUDDY_HIGH_ORDER_RESERVE
+//#define CONFIG_BUDDY_HIGH_ORDER_RESERVE
#ifdef CONFIG_BUDDY_HIGH_ORDER_RESERVE
static unsigned int high_order_reserve_pages = 256; //40 * 4;
@@ -2584,7 +2584,7 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,
if (IS_ENABLED(CONFIG_NUMA) &&
(gfp_mask & GFP_THISNODE) == GFP_THISNODE)
goto nopage;
-
+ count_vm_event(SLOWPATH_ENTERED);
restart:
if (!(gfp_mask & __GFP_NO_KSWAPD))
wake_all_kswapd(order, zonelist, high_zoneidx,
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 9800462..5cb79aa 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -56,6 +56,10 @@
#define CREATE_TRACE_POINTS
#include <trace/events/vmscan.h>
+#ifdef CONFIG_SHRINK_MEMORY
+#include <linux/suspend.h>
+#endif
+
struct scan_control {
/* Incremented by the number of inactive pages that were scanned */
unsigned long nr_scanned;
@@ -3188,20 +3192,11 @@ unsigned long shrink_all_memory(unsigned long nr_to_reclaim)
{
struct reclaim_state reclaim_state;
struct scan_control sc = {
-#ifdef CONFIG_SHRINK_MEMORY
- .gfp_mask = (GFP_HIGHUSER_MOVABLE | GFP_RECLAIM_MASK),
-#else
.gfp_mask = GFP_HIGHUSER_MOVABLE,
-#endif
.may_swap = 1,
.may_unmap = 1,
.may_writepage = 1,
.nr_to_reclaim = nr_to_reclaim,
-#ifdef CONFIG_SHRINK_MEMORY
- .hibernation_mode = 0,
-#else
- .hibernation_mode = 1,
-#endif
.order = 0,
.priority = DEF_PRIORITY,
};
@@ -3212,6 +3207,11 @@ unsigned long shrink_all_memory(unsigned long nr_to_reclaim)
struct task_struct *p = current;
unsigned long nr_reclaimed;
+ if (system_entering_hibernation()) {
+ sc.hibernation_mode = 1;
+ } else {
+ sc.hibernation_mode = 0;
+ }
p->flags |= PF_MEMALLOC;
lockdep_set_current_reclaim_state(sc.gfp_mask);
reclaim_state.reclaimed_slab = 0;
@@ -3234,8 +3234,16 @@ via /proc/sys/vm/shrink_memory */
int sysctl_shrinkmem_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *length, loff_t *ppos)
{
- if (write)
- shrink_all_memory(totalram_pages);
+ int ret;
+
+ ret = proc_dointvec_minmax(table, write, buffer, length, ppos);
+ if (ret)
+ return ret;
+
+ if (write) {
+ if (sysctl_shrink_memory & 1)
+ shrink_all_memory(totalram_pages);
+ }
return 0;
}
diff --git a/mm/vmstat.c b/mm/vmstat.c
index 7ec647f..0834f0a 100644
--- a/mm/vmstat.c
+++ b/mm/vmstat.c
@@ -777,7 +777,7 @@ const char * const vmstat_text[] = {
"kswapd_high_wmark_hit_quickly",
"pageoutrun",
"allocstall",
-
+ "slowpath_entered",
"pgrotated",
#ifdef CONFIG_NUMA_BALANCING