Skip to content

Commit 8d22a93

Browse files
Hugh Dickinstorvalds
authored andcommitted
mm/memcg: fix refcount error while moving and swapping
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]>
1 parent 82ff165 commit 8d22a93

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
@@ -5669,7 +5669,6 @@ static void __mem_cgroup_clear_mc(void)
56695669
if (!mem_cgroup_is_root(mc.to))
56705670
page_counter_uncharge(&mc.to->memory, mc.moved_swap);
56715671

5672-
mem_cgroup_id_get_many(mc.to, mc.moved_swap);
56735672
css_put_many(&mc.to->css, mc.moved_swap);
56745673

56755674
mc.moved_swap = 0;
@@ -5860,7 +5859,8 @@ static int mem_cgroup_move_charge_pte_range(pmd_t *pmd,
58605859
ent = target.ent;
58615860
if (!mem_cgroup_move_swap_account(ent, mc.from, mc.to)) {
58625861
mc.precharge--;
5863-
/* we fixup refcnts and charges later. */
5862+
mem_cgroup_id_get_many(mc.to, 1);
5863+
/* we fixup other refcnts and charges later. */
58645864
mc.moved_swap++;
58655865
}
58665866
break;

0 commit comments

Comments
 (0)