aboutsummaryrefslogtreecommitdiffstats
path: root/mm/memcontrol.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/memcontrol.c')
-rw-r--r--mm/memcontrol.c66
1 files changed, 65 insertions, 1 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 70db6e0a5eec..6f682901deb5 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -62,7 +62,8 @@ enum mem_cgroup_stat_index {
62 * For MEM_CONTAINER_TYPE_ALL, usage = pagecache + rss. 62 * For MEM_CONTAINER_TYPE_ALL, usage = pagecache + rss.
63 */ 63 */
64 MEM_CGROUP_STAT_CACHE, /* # of pages charged as cache */ 64 MEM_CGROUP_STAT_CACHE, /* # of pages charged as cache */
65 MEM_CGROUP_STAT_RSS, /* # of pages charged as rss */ 65 MEM_CGROUP_STAT_RSS, /* # of pages charged as anon rss */
66 MEM_CGROUP_STAT_MAPPED_FILE, /* # of pages charged as file rss */
66 MEM_CGROUP_STAT_PGPGIN_COUNT, /* # of pages paged in */ 67 MEM_CGROUP_STAT_PGPGIN_COUNT, /* # of pages paged in */
67 MEM_CGROUP_STAT_PGPGOUT_COUNT, /* # of pages paged out */ 68 MEM_CGROUP_STAT_PGPGOUT_COUNT, /* # of pages paged out */
68 69
@@ -900,6 +901,44 @@ static void record_last_oom(struct mem_cgroup *mem)
900 mem_cgroup_walk_tree(mem, NULL, record_last_oom_cb); 901 mem_cgroup_walk_tree(mem, NULL, record_last_oom_cb);
901} 902}
902 903
904/*
905 * Currently used to update mapped file statistics, but the routine can be
906 * generalized to update other statistics as well.
907 */
908void mem_cgroup_update_mapped_file_stat(struct page *page, int val)
909{
910 struct mem_cgroup *mem;
911 struct mem_cgroup_stat *stat;
912 struct mem_cgroup_stat_cpu *cpustat;
913 int cpu;
914 struct page_cgroup *pc;
915
916 if (!page_is_file_cache(page))
917 return;
918
919 pc = lookup_page_cgroup(page);
920 if (unlikely(!pc))
921 return;
922
923 lock_page_cgroup(pc);
924 mem = pc->mem_cgroup;
925 if (!mem)
926 goto done;
927
928 if (!PageCgroupUsed(pc))
929 goto done;
930
931 /*
932 * Preemption is already disabled, we don't need get_cpu()
933 */
934 cpu = smp_processor_id();
935 stat = &mem->stat;
936 cpustat = &stat->cpustat[cpu];
937
938 __mem_cgroup_stat_add_safe(cpustat, MEM_CGROUP_STAT_MAPPED_FILE, val);
939done:
940 unlock_page_cgroup(pc);
941}
903 942
904/* 943/*
905 * Unlike exported interface, "oom" parameter is added. if oom==true, 944 * Unlike exported interface, "oom" parameter is added. if oom==true,
@@ -1098,6 +1137,10 @@ static int mem_cgroup_move_account(struct page_cgroup *pc,
1098 struct mem_cgroup_per_zone *from_mz, *to_mz; 1137 struct mem_cgroup_per_zone *from_mz, *to_mz;
1099 int nid, zid; 1138 int nid, zid;
1100 int ret = -EBUSY; 1139 int ret = -EBUSY;
1140 struct page *page;
1141 int cpu;
1142 struct mem_cgroup_stat *stat;
1143 struct mem_cgroup_stat_cpu *cpustat;
1101 1144
1102 VM_BUG_ON(from == to); 1145 VM_BUG_ON(from == to);
1103 VM_BUG_ON(PageLRU(pc->page)); 1146 VM_BUG_ON(PageLRU(pc->page));
@@ -1118,6 +1161,23 @@ static int mem_cgroup_move_account(struct page_cgroup *pc,
1118 1161
1119 res_counter_uncharge(&from->res, PAGE_SIZE); 1162 res_counter_uncharge(&from->res, PAGE_SIZE);
1120 mem_cgroup_charge_statistics(from, pc, false); 1163 mem_cgroup_charge_statistics(from, pc, false);
1164
1165 page = pc->page;
1166 if (page_is_file_cache(page) && page_mapped(page)) {
1167 cpu = smp_processor_id();
1168 /* Update mapped_file data for mem_cgroup "from" */
1169 stat = &from->stat;
1170 cpustat = &stat->cpustat[cpu];
1171 __mem_cgroup_stat_add_safe(cpustat, MEM_CGROUP_STAT_MAPPED_FILE,
1172 -1);
1173
1174 /* Update mapped_file data for mem_cgroup "to" */
1175 stat = &to->stat;
1176 cpustat = &stat->cpustat[cpu];
1177 __mem_cgroup_stat_add_safe(cpustat, MEM_CGROUP_STAT_MAPPED_FILE,
1178 1);
1179 }
1180
1121 if (do_swap_account) 1181 if (do_swap_account)
1122 res_counter_uncharge(&from->memsw, PAGE_SIZE); 1182 res_counter_uncharge(&from->memsw, PAGE_SIZE);
1123 css_put(&from->css); 1183 css_put(&from->css);
@@ -2046,6 +2106,7 @@ static int mem_cgroup_reset(struct cgroup *cont, unsigned int event)
2046enum { 2106enum {
2047 MCS_CACHE, 2107 MCS_CACHE,
2048 MCS_RSS, 2108 MCS_RSS,
2109 MCS_MAPPED_FILE,
2049 MCS_PGPGIN, 2110 MCS_PGPGIN,
2050 MCS_PGPGOUT, 2111 MCS_PGPGOUT,
2051 MCS_INACTIVE_ANON, 2112 MCS_INACTIVE_ANON,
@@ -2066,6 +2127,7 @@ struct {
2066} memcg_stat_strings[NR_MCS_STAT] = { 2127} memcg_stat_strings[NR_MCS_STAT] = {
2067 {"cache", "total_cache"}, 2128 {"cache", "total_cache"},
2068 {"rss", "total_rss"}, 2129 {"rss", "total_rss"},
2130 {"mapped_file", "total_mapped_file"},
2069 {"pgpgin", "total_pgpgin"}, 2131 {"pgpgin", "total_pgpgin"},
2070 {"pgpgout", "total_pgpgout"}, 2132 {"pgpgout", "total_pgpgout"},
2071 {"inactive_anon", "total_inactive_anon"}, 2133 {"inactive_anon", "total_inactive_anon"},
@@ -2086,6 +2148,8 @@ static int mem_cgroup_get_local_stat(struct mem_cgroup *mem, void *data)
2086 s->stat[MCS_CACHE] += val * PAGE_SIZE; 2148 s->stat[MCS_CACHE] += val * PAGE_SIZE;
2087 val = mem_cgroup_read_stat(&mem->stat, MEM_CGROUP_STAT_RSS); 2149 val = mem_cgroup_read_stat(&mem->stat, MEM_CGROUP_STAT_RSS);
2088 s->stat[MCS_RSS] += val * PAGE_SIZE; 2150 s->stat[MCS_RSS] += val * PAGE_SIZE;
2151 val = mem_cgroup_read_stat(&mem->stat, MEM_CGROUP_STAT_MAPPED_FILE);
2152 s->stat[MCS_MAPPED_FILE] += val * PAGE_SIZE;
2089 val = mem_cgroup_read_stat(&mem->stat, MEM_CGROUP_STAT_PGPGIN_COUNT); 2153 val = mem_cgroup_read_stat(&mem->stat, MEM_CGROUP_STAT_PGPGIN_COUNT);
2090 s->stat[MCS_PGPGIN] += val; 2154 s->stat[MCS_PGPGIN] += val;
2091 val = mem_cgroup_read_stat(&mem->stat, MEM_CGROUP_STAT_PGPGOUT_COUNT); 2155 val = mem_cgroup_read_stat(&mem->stat, MEM_CGROUP_STAT_PGPGOUT_COUNT);