[Devel] [PATCH RHEL7 COMMIT] mm: try harder to decrease cache.limit_in_bytes

Konstantin Khorenko khorenko at virtuozzo.com
Wed Jan 31 18:48:04 MSK 2018


The commit is pushed to "branch-rh7-3.10.0-693.11.6.vz7.42.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-693.11.6.vz7.42.4
------>
commit 546729e87a2c4e7b3b9a53a79146714a5d2b0501
Author: Andrey Ryabinin <aryabinin at virtuozzo.com>
Date:   Wed Jan 31 18:48:04 2018 +0300

    mm: try harder to decrease cache.limit_in_bytes
    
    mem_cgroup_resize_cache_limit() tries to free only 32 (SWAP_CLUSTER_MAX)
    pages on each iteration.  This makes it practically impossible to decrease
    limit of memory cgroup.  Tasks could easily allocate back 32 pages, so we
    can't reduce memory usage, and once retry_count reaches zero we return
    -EBUSY.
    
    Easy to reproduce the problem by running the following commands:
    
      mkdir /sys/fs/cgroup/memory/test
      echo $$ >> /sys/fs/cgroup/memory/test/tasks
      cat big_file > /dev/null &
      sleep 1 && echo $((100*1024*1024)) > /sys/fs/cgroup/memory/test/memory.cache.limit_in_bytes
      -bash: echo: write error: Device or resource busy
    
    Instead of relying on retry_count, keep retrying the reclaim until the
    desired limit is reached or fail if the reclaim doesn't make any progress
    or a signal is pending.
    
    https://marc.info/?i=20180110124317.28887-1-aryabinin%40virtuozzo.com
    https://jira.sw.ru/browse/PSBM-80732
    Signed-off-by: Andrey Ryabinin <aryabinin at virtuozzo.com>
---
 mm/memcontrol.c | 14 ++++----------
 1 file changed, 4 insertions(+), 10 deletions(-)

diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 22471a7b995a..99cabf41bc9f 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -4456,15 +4456,9 @@ static int memcg_update_cache_limit(struct mem_cgroup *memcg,
 	int retry_count;
 	int ret;
 
-	/*
-	 * For keeping hierarchical_reclaim simple, how long we should retry
-	 * is depends on callers. We set our retry-count to be function
-	 * of # of children which we should visit in this loop.
-	 */
-	retry_count = MEM_CGROUP_RECLAIM_RETRIES *
-		      mem_cgroup_count_children(memcg);
+	retry_count = MEM_CGROUP_RECLAIM_RETRIES;
 
-	oldusage = page_counter_read(&memcg->cache);
+	curusage = oldusage = page_counter_read(&memcg->cache);
 
 	do {
 		if (signal_pending(current)) {
@@ -4482,8 +4476,8 @@ static int memcg_update_cache_limit(struct mem_cgroup *memcg,
 		if (!ret)
 			break;
 
-		mem_cgroup_reclaim(memcg, GFP_KERNEL,
-				   MEM_CGROUP_RECLAIM_NOSWAP);
+		try_to_free_mem_cgroup_pages(memcg, curusage - limit, GFP_KERNEL,
+					MEM_CGROUP_RECLAIM_NOSWAP);
 		curusage = page_counter_read(&memcg->cache);
 		/* Usage is reduced ? */
 		if (curusage >= oldusage)


More information about the Devel mailing list