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 <[email protected]>
---
 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

_______________________________________________
Devel mailing list
[email protected]
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to