[Devel] [PATCH rh7 1/2] mm/memcg: fix race with WARN_ON() check and kmem uncharging.
Andrey Ryabinin
aryabinin at virtuozzo.com
Wed Aug 14 15:02:56 MSK 2019
WARN_ON() in mem_cgroup_reparent_charges() may falsely trigger
due to the following race (initial state "memory = kmem"):
while((page_counter_read(memory)
- page_counter_read(kmem) > 0) ....
memcg_unharge_kmem():
page_counter_uncharge(kmem);
WARN_ON((page_counter_read(memory)
- page_counter_read(kmem) > 0)...
page_counter_uncharge(memory);
Fix this by reading counters only once.
https://jira.sw.ru/browse/PSBM-97012
Signed-off-by: Andrey Ryabinin <aryabinin at virtuozzo.com>
---
mm/memcontrol.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 3385160f6168..435fdcf8c141 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -4347,6 +4347,7 @@ static void mem_cgroup_reparent_charges(struct mem_cgroup *memcg)
/* Protection from leaked memcg->memory counter. */
unsigned long start_time = jiffies;
unsigned long timeout = start_time + HZ*1200;
+ unsigned long mem, kmem;
do {
/* This is for making all *used* pages to be on LRU. */
@@ -4378,16 +4379,16 @@ static void mem_cgroup_reparent_charges(struct mem_cgroup *memcg)
* right after the check. RES_USAGE should be safe as we always
* charge before adding to the LRU.
*/
- } while ((page_counter_read(&memcg->memory) -
- page_counter_read(&memcg->kmem) > 0) && time_before(jiffies, timeout));
+ mem = page_counter_read(&memcg->memory);
+ kmem = page_counter_read(&memcg->kmem);
+ } while ((mem - kmem > 0) && time_before(jiffies, timeout));
- WARN_ONCE((page_counter_read(&memcg->memory) -
- page_counter_read(&memcg->kmem) > 0),
+ WARN_ONCE((mem - kmem > 0),
"memcg 0x%p leak suspected: "
"memory=%lu, kmem=%lu start_time=%lx timeout=%lx jiffies=%lx",
memcg,
- page_counter_read(&memcg->memory),
- page_counter_read(&memcg->kmem),
+ mem,
+ kmem,
start_time, timeout, jiffies);
}
--
2.21.0
More information about the Devel
mailing list