Skip to content

Commit da63188

Browse files
Hugh Dickinskelmously
authored andcommitted
mm/memcg: fix refcount error while moving and swapping
BugLink: https://bugs.launchpad.net/bugs/1889669 commit 8d22a93 upstream. It was hard to keep a test running, moving tasks between memcgs with move_charge_at_immigrate, while swapping: mem_cgroup_id_get_many()'s refcount is discovered to be 0 (supposedly impossible), so it is then forced to REFCOUNT_SATURATED, and after thousands of warnings in quick succession, the test is at last put out of misery by being OOM killed. This is because of the way moved_swap accounting was saved up until the task move gets completed in __mem_cgroup_clear_mc(), deferred from when mem_cgroup_move_swap_account() actually exchanged old and new ids. Concurrent activity can free up swap quicker than the task is scanned, bringing id refcount down 0 (which should only be possible when offlining). Just skip that optimization: do that part of the accounting immediately. Fixes: 615d66c ("mm: memcontrol: fix memcg id ref counter on swap charge move") Signed-off-by: Hugh Dickins <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Reviewed-by: Alex Shi <[email protected]> Cc: Johannes Weiner <[email protected]> Cc: Alex Shi <[email protected]> Cc: Shakeel Butt <[email protected]> Cc: Michal Hocko <[email protected]> Cc: <[email protected]> Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Linus Torvalds <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]> Signed-off-by: Kamal Mostafa <[email protected]> Signed-off-by: Kelsey Skunberg <[email protected]>
1 parent e64ab9f commit da63188

File tree

1 file changed

+2
-2
lines changed

1 file changed

+2
-2
lines changed

mm/memcontrol.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5770,7 +5770,6 @@ static void __mem_cgroup_clear_mc(void)
57705770
if (!mem_cgroup_is_root(mc.to))
57715771
page_counter_uncharge(&mc.to->memory, mc.moved_swap);
57725772

5773-
mem_cgroup_id_get_many(mc.to, mc.moved_swap);
57745773
css_put_many(&mc.to->css, mc.moved_swap);
57755774

57765775
mc.moved_swap = 0;
@@ -5961,7 +5960,8 @@ static int mem_cgroup_move_charge_pte_range(pmd_t *pmd,
59615960
ent = target.ent;
59625961
if (!mem_cgroup_move_swap_account(ent, mc.from, mc.to)) {
59635962
mc.precharge--;
5964-
/* we fixup refcnts and charges later. */
5963+
mem_cgroup_id_get_many(mc.to, 1);
5964+
/* we fixup other refcnts and charges later. */
59655965
mc.moved_swap++;
59665966
}
59675967
break;

0 commit comments

Comments
 (0)