[RHEL7,COMMIT] mm/memcontrol: don't reparent forever if counter leaked.

Submitted by Konstantin Khorenko on June 24, 2019, 3:26 p.m.

Details

Message ID 201906241526.x5OFQ2td012159@finist-ce7.sw.ru
State New
Series "mm/memcontrol: don't reparent forever if counter leaked."
Headers show

Commit Message

Konstantin Khorenko June 24, 2019, 3:26 p.m.
The commit is pushed to "branch-rh7-3.10.0-957.12.2.vz7.96.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-957.12.2.vz7.96.17
------>
commit 77c54cbf9ae12ef62f5488a7109bda9b11acf291
Author: Andrey Ryabinin <aryabinin@virtuozzo.com>
Date:   Mon Jun 24 18:26:02 2019 +0300

    mm/memcontrol: don't reparent forever if counter leaked.
    
    In case of leaked memcg->memory counter mem_cgroup_reparent_charges()
    may stuck forever under global cgroup_mutex making the whole
    system unusable. I don't see reson for 'while ((memory - kmem) > 0)'
    loop, IMO memory should be equal to kmem after the first iteration.
    And if not it's a leak, but just in case make several attempts.
    
    https://pmc.acronis.com/browse/VSTOR-24241
    Signed-off-by: Andrey Ryabinin <aryabinin@virtuozzo.com>
---
 mm/memcontrol.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

Patch hide | download patch | download mbox

diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index d11aa24ed207..edc6bebc1f34 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -4290,6 +4290,8 @@  static void mem_cgroup_force_empty_list(struct mem_cgroup *memcg,
 static void mem_cgroup_reparent_charges(struct mem_cgroup *memcg)
 {
 	int node, zid;
+	/* Protection from leaked memcg->memory counter. */
+	int reparent_attempts = 10;
 
 	do {
 		/* This is for making all *used* pages to be on LRU. */
@@ -4321,8 +4323,8 @@  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);
+	} while ((page_counter_read(&memcg->memory) -
+		 page_counter_read(&memcg->kmem) > 0) && reparent_attempts--);
 }
 
 /*