[Devel] [PATCH RHEL7 COMMIT] mm/memcg: sleep if mem_cgroup_force_empty_list() stumped on busy page

Konstantin Khorenko khorenko at virtuozzo.com
Wed Sep 6 19:41:51 MSK 2017


The commit is pushed to "branch-rh7-3.10.0-514.26.1.vz7.35.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-514.26.1.vz7.35.7
------>
commit e05136b00c77d9391045d556c8884d9e985af708
Author: Andrey Ryabinin <aryabinin at virtuozzo.com>
Date:   Wed Sep 6 19:41:51 2017 +0300

    mm/memcg: sleep if mem_cgroup_force_empty_list() stumped on busy page
    
    mem_cgroup_force_empty_list() executed in workqueue context. If work doesn't
    go to sleep the workqueue engine thinks that this work is making progress,
    so there is no need to start more workers to execute other works.
    
    So, if we need other works to be executed to unlock those pages we might
    have a deadlock. I think this easy might happen with fuse, something
    like this:
    
    fuse:                              cgroup_destroy work:
    			              mem_cgroup_force_empty_list()
                                              //busy wait for fuse to unlock pages.
     queue_work()
    
     //this may have to wait
     //for mem_cgroup_force_empty_list
     //to finish
     flush_work()
    
     read pages and unlock them.
    
    The solution to this problem is to put mem_cgroup_force_empty_list() in short
    sleep() instead of cond_resched(). This will allow other works to make progress
    if mem_cgroup_force_empty_list() is stuck.
    
    https://jira.sw.ru/browse/PSBM-70021
    
    Signed-off-by: Andrey Ryabinin <aryabinin at virtuozzo.com>
---
 mm/memcontrol.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 5372151..0ddcfd5 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -4039,7 +4039,7 @@ static void mem_cgroup_force_empty_list(struct mem_cgroup *memcg,
 		if (mem_cgroup_move_parent(page, pc, memcg)) {
 			/* found lock contention or "pc" is obsolete. */
 			busy = page;
-			cond_resched();
+			schedule_timeout_uninterruptible(1);
 		} else
 			busy = NULL;
 	} while (!list_empty(list));


More information about the Devel mailing list