diff options
Diffstat (limited to 'mm/memcontrol.c')
-rw-r--r-- | mm/memcontrol.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index c52ec893e241..2bd7541d7c11 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -466,6 +466,8 @@ static void mem_cgroup_update_tree(struct mem_cgroup *memcg, struct page *page) | |||
466 | struct mem_cgroup_tree_per_node *mctz; | 466 | struct mem_cgroup_tree_per_node *mctz; |
467 | 467 | ||
468 | mctz = soft_limit_tree_from_page(page); | 468 | mctz = soft_limit_tree_from_page(page); |
469 | if (!mctz) | ||
470 | return; | ||
469 | /* | 471 | /* |
470 | * Necessary to update all ancestors when hierarchy is used. | 472 | * Necessary to update all ancestors when hierarchy is used. |
471 | * because their event counter is not touched. | 473 | * because their event counter is not touched. |
@@ -503,7 +505,8 @@ static void mem_cgroup_remove_from_trees(struct mem_cgroup *memcg) | |||
503 | for_each_node(nid) { | 505 | for_each_node(nid) { |
504 | mz = mem_cgroup_nodeinfo(memcg, nid); | 506 | mz = mem_cgroup_nodeinfo(memcg, nid); |
505 | mctz = soft_limit_tree_node(nid); | 507 | mctz = soft_limit_tree_node(nid); |
506 | mem_cgroup_remove_exceeded(mz, mctz); | 508 | if (mctz) |
509 | mem_cgroup_remove_exceeded(mz, mctz); | ||
507 | } | 510 | } |
508 | } | 511 | } |
509 | 512 | ||
@@ -2558,7 +2561,7 @@ unsigned long mem_cgroup_soft_limit_reclaim(pg_data_t *pgdat, int order, | |||
2558 | * is empty. Do it lockless to prevent lock bouncing. Races | 2561 | * is empty. Do it lockless to prevent lock bouncing. Races |
2559 | * are acceptable as soft limit is best effort anyway. | 2562 | * are acceptable as soft limit is best effort anyway. |
2560 | */ | 2563 | */ |
2561 | if (RB_EMPTY_ROOT(&mctz->rb_root)) | 2564 | if (!mctz || RB_EMPTY_ROOT(&mctz->rb_root)) |
2562 | return 0; | 2565 | return 0; |
2563 | 2566 | ||
2564 | /* | 2567 | /* |
@@ -4135,17 +4138,22 @@ static void free_mem_cgroup_per_node_info(struct mem_cgroup *memcg, int node) | |||
4135 | kfree(memcg->nodeinfo[node]); | 4138 | kfree(memcg->nodeinfo[node]); |
4136 | } | 4139 | } |
4137 | 4140 | ||
4138 | static void mem_cgroup_free(struct mem_cgroup *memcg) | 4141 | static void __mem_cgroup_free(struct mem_cgroup *memcg) |
4139 | { | 4142 | { |
4140 | int node; | 4143 | int node; |
4141 | 4144 | ||
4142 | memcg_wb_domain_exit(memcg); | ||
4143 | for_each_node(node) | 4145 | for_each_node(node) |
4144 | free_mem_cgroup_per_node_info(memcg, node); | 4146 | free_mem_cgroup_per_node_info(memcg, node); |
4145 | free_percpu(memcg->stat); | 4147 | free_percpu(memcg->stat); |
4146 | kfree(memcg); | 4148 | kfree(memcg); |
4147 | } | 4149 | } |
4148 | 4150 | ||
4151 | static void mem_cgroup_free(struct mem_cgroup *memcg) | ||
4152 | { | ||
4153 | memcg_wb_domain_exit(memcg); | ||
4154 | __mem_cgroup_free(memcg); | ||
4155 | } | ||
4156 | |||
4149 | static struct mem_cgroup *mem_cgroup_alloc(void) | 4157 | static struct mem_cgroup *mem_cgroup_alloc(void) |
4150 | { | 4158 | { |
4151 | struct mem_cgroup *memcg; | 4159 | struct mem_cgroup *memcg; |
@@ -4196,7 +4204,7 @@ static struct mem_cgroup *mem_cgroup_alloc(void) | |||
4196 | fail: | 4204 | fail: |
4197 | if (memcg->id.id > 0) | 4205 | if (memcg->id.id > 0) |
4198 | idr_remove(&mem_cgroup_idr, memcg->id.id); | 4206 | idr_remove(&mem_cgroup_idr, memcg->id.id); |
4199 | mem_cgroup_free(memcg); | 4207 | __mem_cgroup_free(memcg); |
4200 | return NULL; | 4208 | return NULL; |
4201 | } | 4209 | } |
4202 | 4210 | ||