|
@@ -62,7 +62,8 @@ enum mem_cgroup_stat_index {
|
|
|
* For MEM_CONTAINER_TYPE_ALL, usage = pagecache + rss.
|
|
|
*/
|
|
|
MEM_CGROUP_STAT_CACHE, /* # of pages charged as cache */
|
|
|
- MEM_CGROUP_STAT_RSS, /* # of pages charged as rss */
|
|
|
+ MEM_CGROUP_STAT_RSS, /* # of pages charged as anon rss */
|
|
|
+ MEM_CGROUP_STAT_MAPPED_FILE, /* # of pages charged as file rss */
|
|
|
MEM_CGROUP_STAT_PGPGIN_COUNT, /* # of pages paged in */
|
|
|
MEM_CGROUP_STAT_PGPGOUT_COUNT, /* # of pages paged out */
|
|
|
|
|
@@ -900,6 +901,44 @@ static void record_last_oom(struct mem_cgroup *mem)
|
|
|
mem_cgroup_walk_tree(mem, NULL, record_last_oom_cb);
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * Currently used to update mapped file statistics, but the routine can be
|
|
|
+ * generalized to update other statistics as well.
|
|
|
+ */
|
|
|
+void mem_cgroup_update_mapped_file_stat(struct page *page, int val)
|
|
|
+{
|
|
|
+ struct mem_cgroup *mem;
|
|
|
+ struct mem_cgroup_stat *stat;
|
|
|
+ struct mem_cgroup_stat_cpu *cpustat;
|
|
|
+ int cpu;
|
|
|
+ struct page_cgroup *pc;
|
|
|
+
|
|
|
+ if (!page_is_file_cache(page))
|
|
|
+ return;
|
|
|
+
|
|
|
+ pc = lookup_page_cgroup(page);
|
|
|
+ if (unlikely(!pc))
|
|
|
+ return;
|
|
|
+
|
|
|
+ lock_page_cgroup(pc);
|
|
|
+ mem = pc->mem_cgroup;
|
|
|
+ if (!mem)
|
|
|
+ goto done;
|
|
|
+
|
|
|
+ if (!PageCgroupUsed(pc))
|
|
|
+ goto done;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Preemption is already disabled, we don't need get_cpu()
|
|
|
+ */
|
|
|
+ cpu = smp_processor_id();
|
|
|
+ stat = &mem->stat;
|
|
|
+ cpustat = &stat->cpustat[cpu];
|
|
|
+
|
|
|
+ __mem_cgroup_stat_add_safe(cpustat, MEM_CGROUP_STAT_MAPPED_FILE, val);
|
|
|
+done:
|
|
|
+ unlock_page_cgroup(pc);
|
|
|
+}
|
|
|
|
|
|
/*
|
|
|
* Unlike exported interface, "oom" parameter is added. if oom==true,
|
|
@@ -1098,6 +1137,10 @@ static int mem_cgroup_move_account(struct page_cgroup *pc,
|
|
|
struct mem_cgroup_per_zone *from_mz, *to_mz;
|
|
|
int nid, zid;
|
|
|
int ret = -EBUSY;
|
|
|
+ struct page *page;
|
|
|
+ int cpu;
|
|
|
+ struct mem_cgroup_stat *stat;
|
|
|
+ struct mem_cgroup_stat_cpu *cpustat;
|
|
|
|
|
|
VM_BUG_ON(from == to);
|
|
|
VM_BUG_ON(PageLRU(pc->page));
|
|
@@ -1118,6 +1161,23 @@ static int mem_cgroup_move_account(struct page_cgroup *pc,
|
|
|
|
|
|
res_counter_uncharge(&from->res, PAGE_SIZE);
|
|
|
mem_cgroup_charge_statistics(from, pc, false);
|
|
|
+
|
|
|
+ page = pc->page;
|
|
|
+ if (page_is_file_cache(page) && page_mapped(page)) {
|
|
|
+ cpu = smp_processor_id();
|
|
|
+ /* Update mapped_file data for mem_cgroup "from" */
|
|
|
+ stat = &from->stat;
|
|
|
+ cpustat = &stat->cpustat[cpu];
|
|
|
+ __mem_cgroup_stat_add_safe(cpustat, MEM_CGROUP_STAT_MAPPED_FILE,
|
|
|
+ -1);
|
|
|
+
|
|
|
+ /* Update mapped_file data for mem_cgroup "to" */
|
|
|
+ stat = &to->stat;
|
|
|
+ cpustat = &stat->cpustat[cpu];
|
|
|
+ __mem_cgroup_stat_add_safe(cpustat, MEM_CGROUP_STAT_MAPPED_FILE,
|
|
|
+ 1);
|
|
|
+ }
|
|
|
+
|
|
|
if (do_swap_account)
|
|
|
res_counter_uncharge(&from->memsw, PAGE_SIZE);
|
|
|
css_put(&from->css);
|
|
@@ -2046,6 +2106,7 @@ static int mem_cgroup_reset(struct cgroup *cont, unsigned int event)
|
|
|
enum {
|
|
|
MCS_CACHE,
|
|
|
MCS_RSS,
|
|
|
+ MCS_MAPPED_FILE,
|
|
|
MCS_PGPGIN,
|
|
|
MCS_PGPGOUT,
|
|
|
MCS_INACTIVE_ANON,
|
|
@@ -2066,6 +2127,7 @@ struct {
|
|
|
} memcg_stat_strings[NR_MCS_STAT] = {
|
|
|
{"cache", "total_cache"},
|
|
|
{"rss", "total_rss"},
|
|
|
+ {"mapped_file", "total_mapped_file"},
|
|
|
{"pgpgin", "total_pgpgin"},
|
|
|
{"pgpgout", "total_pgpgout"},
|
|
|
{"inactive_anon", "total_inactive_anon"},
|
|
@@ -2086,6 +2148,8 @@ static int mem_cgroup_get_local_stat(struct mem_cgroup *mem, void *data)
|
|
|
s->stat[MCS_CACHE] += val * PAGE_SIZE;
|
|
|
val = mem_cgroup_read_stat(&mem->stat, MEM_CGROUP_STAT_RSS);
|
|
|
s->stat[MCS_RSS] += val * PAGE_SIZE;
|
|
|
+ val = mem_cgroup_read_stat(&mem->stat, MEM_CGROUP_STAT_MAPPED_FILE);
|
|
|
+ s->stat[MCS_MAPPED_FILE] += val * PAGE_SIZE;
|
|
|
val = mem_cgroup_read_stat(&mem->stat, MEM_CGROUP_STAT_PGPGIN_COUNT);
|
|
|
s->stat[MCS_PGPGIN] += val;
|
|
|
val = mem_cgroup_read_stat(&mem->stat, MEM_CGROUP_STAT_PGPGOUT_COUNT);
|