|
@@ -94,6 +94,8 @@ enum mem_cgroup_events_index {
|
|
|
MEM_CGROUP_EVENTS_PGPGIN, /* # of pages paged in */
|
|
|
MEM_CGROUP_EVENTS_PGPGOUT, /* # of pages paged out */
|
|
|
MEM_CGROUP_EVENTS_COUNT, /* # of pages paged in/out */
|
|
|
+ MEM_CGROUP_EVENTS_PGFAULT, /* # of page-faults */
|
|
|
+ MEM_CGROUP_EVENTS_PGMAJFAULT, /* # of major page-faults */
|
|
|
MEM_CGROUP_EVENTS_NSTATS,
|
|
|
};
|
|
|
/*
|
|
@@ -590,6 +592,16 @@ static void mem_cgroup_swap_statistics(struct mem_cgroup *mem,
|
|
|
this_cpu_add(mem->stat->count[MEM_CGROUP_STAT_SWAPOUT], val);
|
|
|
}
|
|
|
|
|
|
+void mem_cgroup_pgfault(struct mem_cgroup *mem, int val)
|
|
|
+{
|
|
|
+ this_cpu_add(mem->stat->events[MEM_CGROUP_EVENTS_PGFAULT], val);
|
|
|
+}
|
|
|
+
|
|
|
+void mem_cgroup_pgmajfault(struct mem_cgroup *mem, int val)
|
|
|
+{
|
|
|
+ this_cpu_add(mem->stat->events[MEM_CGROUP_EVENTS_PGMAJFAULT], val);
|
|
|
+}
|
|
|
+
|
|
|
static unsigned long mem_cgroup_read_events(struct mem_cgroup *mem,
|
|
|
enum mem_cgroup_events_index idx)
|
|
|
{
|
|
@@ -827,6 +839,33 @@ static inline bool mem_cgroup_is_root(struct mem_cgroup *mem)
|
|
|
return (mem == root_mem_cgroup);
|
|
|
}
|
|
|
|
|
|
+void mem_cgroup_count_vm_event(struct mm_struct *mm, enum vm_event_item idx)
|
|
|
+{
|
|
|
+ struct mem_cgroup *mem;
|
|
|
+
|
|
|
+ if (!mm)
|
|
|
+ return;
|
|
|
+
|
|
|
+ rcu_read_lock();
|
|
|
+ mem = mem_cgroup_from_task(rcu_dereference(mm->owner));
|
|
|
+ if (unlikely(!mem))
|
|
|
+ goto out;
|
|
|
+
|
|
|
+ switch (idx) {
|
|
|
+ case PGMAJFAULT:
|
|
|
+ mem_cgroup_pgmajfault(mem, 1);
|
|
|
+ break;
|
|
|
+ case PGFAULT:
|
|
|
+ mem_cgroup_pgfault(mem, 1);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ BUG();
|
|
|
+ }
|
|
|
+out:
|
|
|
+ rcu_read_unlock();
|
|
|
+}
|
|
|
+EXPORT_SYMBOL(mem_cgroup_count_vm_event);
|
|
|
+
|
|
|
/*
|
|
|
* Following LRU functions are allowed to be used without PCG_LOCK.
|
|
|
* Operations are called by routine of global LRU independently from memcg.
|
|
@@ -3958,6 +3997,8 @@ enum {
|
|
|
MCS_PGPGIN,
|
|
|
MCS_PGPGOUT,
|
|
|
MCS_SWAP,
|
|
|
+ MCS_PGFAULT,
|
|
|
+ MCS_PGMAJFAULT,
|
|
|
MCS_INACTIVE_ANON,
|
|
|
MCS_ACTIVE_ANON,
|
|
|
MCS_INACTIVE_FILE,
|
|
@@ -3980,6 +4021,8 @@ struct {
|
|
|
{"pgpgin", "total_pgpgin"},
|
|
|
{"pgpgout", "total_pgpgout"},
|
|
|
{"swap", "total_swap"},
|
|
|
+ {"pgfault", "total_pgfault"},
|
|
|
+ {"pgmajfault", "total_pgmajfault"},
|
|
|
{"inactive_anon", "total_inactive_anon"},
|
|
|
{"active_anon", "total_active_anon"},
|
|
|
{"inactive_file", "total_inactive_file"},
|
|
@@ -4008,6 +4051,10 @@ mem_cgroup_get_local_stat(struct mem_cgroup *mem, struct mcs_total_stat *s)
|
|
|
val = mem_cgroup_read_stat(mem, MEM_CGROUP_STAT_SWAPOUT);
|
|
|
s->stat[MCS_SWAP] += val * PAGE_SIZE;
|
|
|
}
|
|
|
+ val = mem_cgroup_read_events(mem, MEM_CGROUP_EVENTS_PGFAULT);
|
|
|
+ s->stat[MCS_PGFAULT] += val;
|
|
|
+ val = mem_cgroup_read_events(mem, MEM_CGROUP_EVENTS_PGMAJFAULT);
|
|
|
+ s->stat[MCS_PGMAJFAULT] += val;
|
|
|
|
|
|
/* per zone stat */
|
|
|
val = mem_cgroup_get_local_zonestat(mem, LRU_INACTIVE_ANON);
|