aboutsummaryrefslogtreecommitdiffstats
path: root/mm/memcontrol.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/memcontrol.c')
-rw-r--r--mm/memcontrol.c43
1 files changed, 41 insertions, 2 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index f1a0ae6e11b8..7f1a356153c0 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -338,7 +338,7 @@ struct mem_cgroup {
338static size_t memcg_size(void) 338static size_t memcg_size(void)
339{ 339{
340 return sizeof(struct mem_cgroup) + 340 return sizeof(struct mem_cgroup) +
341 nr_node_ids * sizeof(struct mem_cgroup_per_node); 341 nr_node_ids * sizeof(struct mem_cgroup_per_node *);
342} 342}
343 343
344/* internal only representation about the status of kmem accounting. */ 344/* internal only representation about the status of kmem accounting. */
@@ -2694,7 +2694,10 @@ static int __mem_cgroup_try_charge(struct mm_struct *mm,
2694 goto bypass; 2694 goto bypass;
2695 2695
2696 if (unlikely(task_in_memcg_oom(current))) 2696 if (unlikely(task_in_memcg_oom(current)))
2697 goto bypass; 2697 goto nomem;
2698
2699 if (gfp_mask & __GFP_NOFAIL)
2700 oom = false;
2698 2701
2699 /* 2702 /*
2700 * We always charge the cgroup the mm_struct belongs to. 2703 * We always charge the cgroup the mm_struct belongs to.
@@ -6352,6 +6355,42 @@ static void mem_cgroup_css_offline(struct cgroup_subsys_state *css)
6352static void mem_cgroup_css_free(struct cgroup_subsys_state *css) 6355static void mem_cgroup_css_free(struct cgroup_subsys_state *css)
6353{ 6356{
6354 struct mem_cgroup *memcg = mem_cgroup_from_css(css); 6357 struct mem_cgroup *memcg = mem_cgroup_from_css(css);
6358 /*
6359 * XXX: css_offline() would be where we should reparent all
6360 * memory to prepare the cgroup for destruction. However,
6361 * memcg does not do css_tryget() and res_counter charging
6362 * under the same RCU lock region, which means that charging
6363 * could race with offlining. Offlining only happens to
6364 * cgroups with no tasks in them but charges can show up
6365 * without any tasks from the swapin path when the target
6366 * memcg is looked up from the swapout record and not from the
6367 * current task as it usually is. A race like this can leak
6368 * charges and put pages with stale cgroup pointers into
6369 * circulation:
6370 *
6371 * #0 #1
6372 * lookup_swap_cgroup_id()
6373 * rcu_read_lock()
6374 * mem_cgroup_lookup()
6375 * css_tryget()
6376 * rcu_read_unlock()
6377 * disable css_tryget()
6378 * call_rcu()
6379 * offline_css()
6380 * reparent_charges()
6381 * res_counter_charge()
6382 * css_put()
6383 * css_free()
6384 * pc->mem_cgroup = dead memcg
6385 * add page to lru
6386 *
6387 * The bulk of the charges are still moved in offline_css() to
6388 * avoid pinning a lot of pages in case a long-term reference
6389 * like a swapout record is deferring the css_free() to long
6390 * after offlining. But this makes sure we catch any charges
6391 * made after offlining:
6392 */
6393 mem_cgroup_reparent_charges(memcg);
6355 6394
6356 memcg_destroy_kmem(memcg); 6395 memcg_destroy_kmem(memcg);
6357 __mem_cgroup_free(memcg); 6396 __mem_cgroup_free(memcg);