aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
Diffstat (limited to 'mm')
-rw-r--r--mm/memcontrol.c16
-rw-r--r--mm/thrash.c87
-rw-r--r--mm/vmscan.c4
3 files changed, 77 insertions, 30 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index bd9052a5d3ad..e37c44d88d46 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -735,7 +735,7 @@ struct mem_cgroup *mem_cgroup_from_task(struct task_struct *p)
735 struct mem_cgroup, css); 735 struct mem_cgroup, css);
736} 736}
737 737
738static struct mem_cgroup *try_get_mem_cgroup_from_mm(struct mm_struct *mm) 738struct mem_cgroup *try_get_mem_cgroup_from_mm(struct mm_struct *mm)
739{ 739{
740 struct mem_cgroup *mem = NULL; 740 struct mem_cgroup *mem = NULL;
741 741
@@ -5414,18 +5414,16 @@ static void mem_cgroup_move_task(struct cgroup_subsys *ss,
5414 struct cgroup *old_cont, 5414 struct cgroup *old_cont,
5415 struct task_struct *p) 5415 struct task_struct *p)
5416{ 5416{
5417 struct mm_struct *mm; 5417 struct mm_struct *mm = get_task_mm(p);
5418 5418
5419 if (!mc.to)
5420 /* no need to move charge */
5421 return;
5422
5423 mm = get_task_mm(p);
5424 if (mm) { 5419 if (mm) {
5425 mem_cgroup_move_charge(mm); 5420 if (mc.to)
5421 mem_cgroup_move_charge(mm);
5422 put_swap_token(mm);
5426 mmput(mm); 5423 mmput(mm);
5427 } 5424 }
5428 mem_cgroup_clear_mc(); 5425 if (mc.to)
5426 mem_cgroup_clear_mc();
5429} 5427}
5430#else /* !CONFIG_MMU */ 5428#else /* !CONFIG_MMU */
5431static int mem_cgroup_can_attach(struct cgroup_subsys *ss, 5429static int mem_cgroup_can_attach(struct cgroup_subsys *ss,
diff --git a/mm/thrash.c b/mm/thrash.c
index 2372d4ed5dd8..6cdf86511385 100644
--- a/mm/thrash.c
+++ b/mm/thrash.c
@@ -21,11 +21,31 @@
21#include <linux/mm.h> 21#include <linux/mm.h>
22#include <linux/sched.h> 22#include <linux/sched.h>
23#include <linux/swap.h> 23#include <linux/swap.h>
24#include <linux/memcontrol.h>
24 25
25static DEFINE_SPINLOCK(swap_token_lock); 26static DEFINE_SPINLOCK(swap_token_lock);
26struct mm_struct *swap_token_mm; 27struct mm_struct *swap_token_mm;
28struct mem_cgroup *swap_token_memcg;
27static unsigned int global_faults; 29static unsigned int global_faults;
28 30
31#ifdef CONFIG_CGROUP_MEM_RES_CTLR
32static struct mem_cgroup *swap_token_memcg_from_mm(struct mm_struct *mm)
33{
34 struct mem_cgroup *memcg;
35
36 memcg = try_get_mem_cgroup_from_mm(mm);
37 if (memcg)
38 css_put(mem_cgroup_css(memcg));
39
40 return memcg;
41}
42#else
43static struct mem_cgroup *swap_token_memcg_from_mm(struct mm_struct *mm)
44{
45 return NULL;
46}
47#endif
48
29void grab_swap_token(struct mm_struct *mm) 49void grab_swap_token(struct mm_struct *mm)
30{ 50{
31 int current_interval; 51 int current_interval;
@@ -38,40 +58,69 @@ void grab_swap_token(struct mm_struct *mm)
38 return; 58 return;
39 59
40 /* First come first served */ 60 /* First come first served */
41 if (swap_token_mm == NULL) { 61 if (!swap_token_mm)
42 mm->token_priority = mm->token_priority + 2; 62 goto replace_token;
43 swap_token_mm = mm; 63
64 if (mm == swap_token_mm) {
65 mm->token_priority += 2;
44 goto out; 66 goto out;
45 } 67 }
46 68
47 if (mm != swap_token_mm) { 69 if (current_interval < mm->last_interval)
48 if (current_interval < mm->last_interval) 70 mm->token_priority++;
49 mm->token_priority++; 71 else {
50 else { 72 if (likely(mm->token_priority > 0))
51 if (likely(mm->token_priority > 0)) 73 mm->token_priority--;
52 mm->token_priority--;
53 }
54 /* Check if we deserve the token */
55 if (mm->token_priority > swap_token_mm->token_priority) {
56 mm->token_priority += 2;
57 swap_token_mm = mm;
58 }
59 } else {
60 /* Token holder came in again! */
61 mm->token_priority += 2;
62 } 74 }
63 75
76 /* Check if we deserve the token */
77 if (mm->token_priority > swap_token_mm->token_priority)
78 goto replace_token;
79
64out: 80out:
65 mm->faultstamp = global_faults; 81 mm->faultstamp = global_faults;
66 mm->last_interval = current_interval; 82 mm->last_interval = current_interval;
67 spin_unlock(&swap_token_lock); 83 spin_unlock(&swap_token_lock);
84 return;
85
86replace_token:
87 mm->token_priority += 2;
88 swap_token_mm = mm;
89 swap_token_memcg = swap_token_memcg_from_mm(mm);
90 goto out;
68} 91}
69 92
70/* Called on process exit. */ 93/* Called on process exit. */
71void __put_swap_token(struct mm_struct *mm) 94void __put_swap_token(struct mm_struct *mm)
72{ 95{
73 spin_lock(&swap_token_lock); 96 spin_lock(&swap_token_lock);
74 if (likely(mm == swap_token_mm)) 97 if (likely(mm == swap_token_mm)) {
75 swap_token_mm = NULL; 98 swap_token_mm = NULL;
99 swap_token_memcg = NULL;
100 }
76 spin_unlock(&swap_token_lock); 101 spin_unlock(&swap_token_lock);
77} 102}
103
104static bool match_memcg(struct mem_cgroup *a, struct mem_cgroup *b)
105{
106 if (!a)
107 return true;
108 if (!b)
109 return true;
110 if (a == b)
111 return true;
112 return false;
113}
114
115void disable_swap_token(struct mem_cgroup *memcg)
116{
117 /* memcg reclaim don't disable unrelated mm token. */
118 if (match_memcg(memcg, swap_token_memcg)) {
119 spin_lock(&swap_token_lock);
120 if (match_memcg(memcg, swap_token_memcg)) {
121 swap_token_mm = NULL;
122 swap_token_memcg = NULL;
123 }
124 spin_unlock(&swap_token_lock);
125 }
126}
diff --git a/mm/vmscan.c b/mm/vmscan.c
index faa0a088f9cc..dbe6ea321df4 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -2081,7 +2081,7 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist,
2081 for (priority = DEF_PRIORITY; priority >= 0; priority--) { 2081 for (priority = DEF_PRIORITY; priority >= 0; priority--) {
2082 sc->nr_scanned = 0; 2082 sc->nr_scanned = 0;
2083 if (!priority) 2083 if (!priority)
2084 disable_swap_token(); 2084 disable_swap_token(sc->mem_cgroup);
2085 total_scanned += shrink_zones(priority, zonelist, sc); 2085 total_scanned += shrink_zones(priority, zonelist, sc);
2086 /* 2086 /*
2087 * Don't shrink slabs when reclaiming memory from 2087 * Don't shrink slabs when reclaiming memory from
@@ -2407,7 +2407,7 @@ loop_again:
2407 2407
2408 /* The swap token gets in the way of swapout... */ 2408 /* The swap token gets in the way of swapout... */
2409 if (!priority) 2409 if (!priority)
2410 disable_swap_token(); 2410 disable_swap_token(NULL);
2411 2411
2412 all_zones_ok = 1; 2412 all_zones_ok = 1;
2413 balanced = 0; 2413 balanced = 0;