#include <linux/swap.h>
#include <linux/memcontrol.h>
+#include <trace/events/vmscan.h>
+
+#define TOKEN_AGING_INTERVAL (0xFF)
+
static DEFINE_SPINLOCK(swap_token_lock);
struct mm_struct *swap_token_mm;
struct mem_cgroup *swap_token_memcg;
static unsigned int global_faults;
+static unsigned int last_aging;
#ifdef CONFIG_CGROUP_MEM_RES_CTLR
static struct mem_cgroup *swap_token_memcg_from_mm(struct mm_struct *mm)
void grab_swap_token(struct mm_struct *mm)
{
int current_interval;
+ unsigned int old_prio = mm->token_priority;
global_faults++;
if (!swap_token_mm)
goto replace_token;
+ if ((global_faults - last_aging) > TOKEN_AGING_INTERVAL) {
+ swap_token_mm->token_priority /= 2;
+ last_aging = global_faults;
+ }
+
if (mm == swap_token_mm) {
mm->token_priority += 2;
- goto out;
+ goto update_priority;
}
if (current_interval < mm->last_interval)
if (mm->token_priority > swap_token_mm->token_priority)
goto replace_token;
+update_priority:
+ trace_update_swap_token_priority(mm, old_prio, swap_token_mm);
+
out:
mm->faultstamp = global_faults;
mm->last_interval = current_interval;
replace_token:
mm->token_priority += 2;
+ trace_replace_swap_token(swap_token_mm, mm);
swap_token_mm = mm;
swap_token_memcg = swap_token_memcg_from_mm(mm);
+ last_aging = global_faults;
goto out;
}
{
spin_lock(&swap_token_lock);
if (likely(mm == swap_token_mm)) {
+ trace_put_swap_token(swap_token_mm);
swap_token_mm = NULL;
swap_token_memcg = NULL;
}
if (match_memcg(memcg, swap_token_memcg)) {
spin_lock(&swap_token_lock);
if (match_memcg(memcg, swap_token_memcg)) {
+ trace_disable_swap_token(swap_token_mm);
swap_token_mm = NULL;
swap_token_memcg = NULL;
}