summaryrefslogtreecommitdiffstats
path: root/mm/memcontrol.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/memcontrol.c')
-rw-r--r--mm/memcontrol.c60
1 files changed, 60 insertions, 0 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 6f5c0c517c49..26e2999af608 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -3260,6 +3260,60 @@ static u64 mem_cgroup_read_u64(struct cgroup_subsys_state *css,
3260 } 3260 }
3261} 3261}
3262 3262
3263static void memcg_flush_percpu_vmstats(struct mem_cgroup *memcg)
3264{
3265 unsigned long stat[MEMCG_NR_STAT];
3266 struct mem_cgroup *mi;
3267 int node, cpu, i;
3268
3269 for (i = 0; i < MEMCG_NR_STAT; i++)
3270 stat[i] = 0;
3271
3272 for_each_online_cpu(cpu)
3273 for (i = 0; i < MEMCG_NR_STAT; i++)
3274 stat[i] += raw_cpu_read(memcg->vmstats_percpu->stat[i]);
3275
3276 for (mi = memcg; mi; mi = parent_mem_cgroup(mi))
3277 for (i = 0; i < MEMCG_NR_STAT; i++)
3278 atomic_long_add(stat[i], &mi->vmstats[i]);
3279
3280 for_each_node(node) {
3281 struct mem_cgroup_per_node *pn = memcg->nodeinfo[node];
3282 struct mem_cgroup_per_node *pi;
3283
3284 for (i = 0; i < NR_VM_NODE_STAT_ITEMS; i++)
3285 stat[i] = 0;
3286
3287 for_each_online_cpu(cpu)
3288 for (i = 0; i < NR_VM_NODE_STAT_ITEMS; i++)
3289 stat[i] += raw_cpu_read(
3290 pn->lruvec_stat_cpu->count[i]);
3291
3292 for (pi = pn; pi; pi = parent_nodeinfo(pi, node))
3293 for (i = 0; i < NR_VM_NODE_STAT_ITEMS; i++)
3294 atomic_long_add(stat[i], &pi->lruvec_stat[i]);
3295 }
3296}
3297
3298static void memcg_flush_percpu_vmevents(struct mem_cgroup *memcg)
3299{
3300 unsigned long events[NR_VM_EVENT_ITEMS];
3301 struct mem_cgroup *mi;
3302 int cpu, i;
3303
3304 for (i = 0; i < NR_VM_EVENT_ITEMS; i++)
3305 events[i] = 0;
3306
3307 for_each_online_cpu(cpu)
3308 for (i = 0; i < NR_VM_EVENT_ITEMS; i++)
3309 events[i] += raw_cpu_read(
3310 memcg->vmstats_percpu->events[i]);
3311
3312 for (mi = memcg; mi; mi = parent_mem_cgroup(mi))
3313 for (i = 0; i < NR_VM_EVENT_ITEMS; i++)
3314 atomic_long_add(events[i], &mi->vmevents[i]);
3315}
3316
3263#ifdef CONFIG_MEMCG_KMEM 3317#ifdef CONFIG_MEMCG_KMEM
3264static int memcg_online_kmem(struct mem_cgroup *memcg) 3318static int memcg_online_kmem(struct mem_cgroup *memcg)
3265{ 3319{
@@ -4682,6 +4736,12 @@ static void __mem_cgroup_free(struct mem_cgroup *memcg)
4682{ 4736{
4683 int node; 4737 int node;
4684 4738
4739 /*
4740 * Flush percpu vmstats and vmevents to guarantee the value correctness
4741 * on parent's and all ancestor levels.
4742 */
4743 memcg_flush_percpu_vmstats(memcg);
4744 memcg_flush_percpu_vmevents(memcg);
4685 for_each_node(node) 4745 for_each_node(node)
4686 free_mem_cgroup_per_node_info(memcg, node); 4746 free_mem_cgroup_per_node_info(memcg, node);
4687 free_percpu(memcg->vmstats_percpu); 4747 free_percpu(memcg->vmstats_percpu);