[Devel] [PATCH rh7 1/2] mm/memcg: Don't enable interrupts too soon.
Andrey Ryabinin
aryabinin at virtuozzo.com
Mon Oct 30 16:51:23 MSK 2017
When mem_cgroup_move_parent() moves huge page it disables interrupt:
if (nr_pages > 1) {
VM_BUG_ON_PAGE(!PageTransHuge(page), page);
flags = compound_lock_irqsave(page);
}
and calls:
ret = mem_cgroup_move_account(page, nr_pages, ...
which does the following:
local_irq_disable();
mem_cgroup_charge_statistics(to, page, nr_pages);
...
local_irq_enable();
So the last local_irq_enable() enables irq too early, which may lead
to the deadlock. mem_cgroup_move_account() should use local_irq_save()/
local_irq_restore() primitives instead.
Found while investigating https://jira.sw.ru/browse/PSBM-76011
but unrelated.
Signed-off-by: Andrey Ryabinin <aryabinin at virtuozzo.com>
---
mm/memcontrol.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 239fbca70b59..efc455d8ca81 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -3597,15 +3597,14 @@ static int mem_cgroup_move_account(struct page *page,
/* caller should have done css_get */
pc->mem_cgroup = to;
- move_unlock_mem_cgroup(from, &flags);
+ spin_unlock(&from->move_lock);
ret = 0;
- local_irq_disable();
mem_cgroup_charge_statistics(to, page, nr_pages);
memcg_check_events(to, page);
mem_cgroup_charge_statistics(from, page, -nr_pages);
memcg_check_events(from, page);
- local_irq_enable();
+ local_irq_restore(flags);
out_unlock:
unlock_page(page);
out:
--
2.13.6
More information about the Devel
mailing list