aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>2011-06-15 18:08:15 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-06-15 23:03:59 -0400
commitd7911ef30cb7bec52234c2b7a5c275ac8f07905a (patch)
treec3d9dc8ffc5d9478da434faecc27759ee34edf83
parent83cd81a34357a632509f7491eec81e62e71d65f7 (diff)
vmscan: implement swap token priority aging
While testing for memcg aware swap token, I observed a swap token was often grabbed an intermittent running process (eg init, auditd) and they never release a token. Why? Some processes (eg init, auditd, audispd) wake up when a process exiting. And swap token can be get first page-in process when a process exiting makes no swap token owner. Thus such above intermittent running process often get a token. And currently, swap token priority is only decreased at page fault path. Then, if the process sleep immediately after to grab swap token, the swap token priority never be decreased. That's obviously undesirable. This patch implement very poor (and lightweight) priority aging. It only be affect to the above corner case and doesn't change swap tendency workload performance (eg multi process qsbench load) Signed-off-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> Reviewed-by: Rik van Riel <riel@redhat.com> Reviewed-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--include/trace/events/vmscan.h20
-rw-r--r--mm/thrash.c11
2 files changed, 23 insertions, 8 deletions
diff --git a/include/trace/events/vmscan.h b/include/trace/events/vmscan.h
index 1798e0cee2a9..b2c33bd955fa 100644
--- a/include/trace/events/vmscan.h
+++ b/include/trace/events/vmscan.h
@@ -366,9 +366,10 @@ DEFINE_EVENT_CONDITION(put_swap_token_template, disable_swap_token,
366 366
367TRACE_EVENT_CONDITION(update_swap_token_priority, 367TRACE_EVENT_CONDITION(update_swap_token_priority,
368 TP_PROTO(struct mm_struct *mm, 368 TP_PROTO(struct mm_struct *mm,
369 unsigned int old_prio), 369 unsigned int old_prio,
370 struct mm_struct *swap_token_mm),
370 371
371 TP_ARGS(mm, old_prio), 372 TP_ARGS(mm, old_prio, swap_token_mm),
372 373
373 TP_CONDITION(mm->token_priority != old_prio), 374 TP_CONDITION(mm->token_priority != old_prio),
374 375
@@ -376,16 +377,21 @@ TRACE_EVENT_CONDITION(update_swap_token_priority,
376 __field(struct mm_struct*, mm) 377 __field(struct mm_struct*, mm)
377 __field(unsigned int, old_prio) 378 __field(unsigned int, old_prio)
378 __field(unsigned int, new_prio) 379 __field(unsigned int, new_prio)
380 __field(struct mm_struct*, swap_token_mm)
381 __field(unsigned int, swap_token_prio)
379 ), 382 ),
380 383
381 TP_fast_assign( 384 TP_fast_assign(
382 __entry->mm = mm; 385 __entry->mm = mm;
383 __entry->old_prio = old_prio; 386 __entry->old_prio = old_prio;
384 __entry->new_prio = mm->token_priority; 387 __entry->new_prio = mm->token_priority;
388 __entry->swap_token_mm = swap_token_mm;
389 __entry->swap_token_prio = swap_token_mm ? swap_token_mm->token_priority : 0;
385 ), 390 ),
386 391
387 TP_printk("mm=%p old_prio=%u new_prio=%u", 392 TP_printk("mm=%p old_prio=%u new_prio=%u swap_token_mm=%p token_prio=%u",
388 __entry->mm, __entry->old_prio, __entry->new_prio) 393 __entry->mm, __entry->old_prio, __entry->new_prio,
394 __entry->swap_token_mm, __entry->swap_token_prio)
389); 395);
390 396
391#endif /* _TRACE_VMSCAN_H */ 397#endif /* _TRACE_VMSCAN_H */
diff --git a/mm/thrash.c b/mm/thrash.c
index 17d9e29e4c9c..fabf2d0f5169 100644
--- a/mm/thrash.c
+++ b/mm/thrash.c
@@ -25,10 +25,13 @@
25 25
26#include <trace/events/vmscan.h> 26#include <trace/events/vmscan.h>
27 27
28#define TOKEN_AGING_INTERVAL (0xFF)
29
28static DEFINE_SPINLOCK(swap_token_lock); 30static DEFINE_SPINLOCK(swap_token_lock);
29struct mm_struct *swap_token_mm; 31struct mm_struct *swap_token_mm;
30struct mem_cgroup *swap_token_memcg; 32struct mem_cgroup *swap_token_memcg;
31static unsigned int global_faults; 33static unsigned int global_faults;
34static unsigned int last_aging;
32 35
33#ifdef CONFIG_CGROUP_MEM_RES_CTLR 36#ifdef CONFIG_CGROUP_MEM_RES_CTLR
34static struct mem_cgroup *swap_token_memcg_from_mm(struct mm_struct *mm) 37static struct mem_cgroup *swap_token_memcg_from_mm(struct mm_struct *mm)
@@ -64,6 +67,11 @@ void grab_swap_token(struct mm_struct *mm)
64 if (!swap_token_mm) 67 if (!swap_token_mm)
65 goto replace_token; 68 goto replace_token;
66 69
70 if ((global_faults - last_aging) > TOKEN_AGING_INTERVAL) {
71 swap_token_mm->token_priority /= 2;
72 last_aging = global_faults;
73 }
74
67 if (mm == swap_token_mm) { 75 if (mm == swap_token_mm) {
68 mm->token_priority += 2; 76 mm->token_priority += 2;
69 goto update_priority; 77 goto update_priority;
@@ -81,7 +89,7 @@ void grab_swap_token(struct mm_struct *mm)
81 goto replace_token; 89 goto replace_token;
82 90
83update_priority: 91update_priority:
84 trace_update_swap_token_priority(mm, old_prio); 92 trace_update_swap_token_priority(mm, old_prio, swap_token_mm);
85 93
86out: 94out:
87 mm->faultstamp = global_faults; 95 mm->faultstamp = global_faults;
@@ -94,6 +102,7 @@ replace_token:
94 trace_replace_swap_token(swap_token_mm, mm); 102 trace_replace_swap_token(swap_token_mm, mm);
95 swap_token_mm = mm; 103 swap_token_mm = mm;
96 swap_token_memcg = swap_token_memcg_from_mm(mm); 104 swap_token_memcg = swap_token_memcg_from_mm(mm);
105 last_aging = global_faults;
97 goto out; 106 goto out;
98} 107}
99 108