[Devel] [PATCH RHEL7 COMMIT] ms/mm: memcontrol: simplify move precharge function

Konstantin Khorenko khorenko at virtuozzo.com
Mon Jan 16 08:27:11 PST 2017


The commit is pushed to "branch-rh7-3.10.0-514.vz7.27.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-514.vz7.27.10
------>
commit aa466d093712b6859118b15830f150a5c7ec74b4
Author: Johannes Weiner <hannes at cmpxchg.org>
Date:   Mon Jan 16 20:27:11 2017 +0400

    ms/mm: memcontrol: simplify move precharge function
    
    The move precharge function does some baroque things: it tries raw
    res_counter charging of the entire amount first, and then falls back to
    a loop of one-by-one charges, with checks for pending signals and
    cond_resched() batching.
    
    Just use mem_cgroup_try_charge() without __GFP_WAIT for the first bulk
    charge attempt.  In the one-by-one loop, remove the signal check (this
    is already checked in try_charge), and simply call cond_resched() after
    every charge - it's not that expensive.
    
    Signed-off-by: Johannes Weiner <hannes at cmpxchg.org>
    Acked-by: Michal Hocko <mhocko at suse.cz>
    Cc: Hugh Dickins <hughd at google.com>
    Cc: Tejun Heo <tj at kernel.org>
    Cc: Vladimir Davydov <vdavydov at parallels.com>
    Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
    
    https://jira.sw.ru/browse/PSBM-51558
    (cherry picked from commit 9476db974d9e18885123fcebc09f4596bb922e5f)
    Signed-off-by: Andrey Ryabinin <aryabinin at virtuozzo.com>
---
 mm/memcontrol.c | 48 +++++++++++++++---------------------------------
 1 file changed, 15 insertions(+), 33 deletions(-)

diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index a1aab9f..32533bf 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -6722,56 +6722,38 @@ static void mem_cgroup_css_free(struct cgroup *cont)
 
 #ifdef CONFIG_MMU
 /* Handlers for move charge at task migration. */
-#define PRECHARGE_COUNT_AT_ONCE	256
 static int mem_cgroup_do_precharge(unsigned long count)
 {
 	int ret = 0;
-	int batch_count = PRECHARGE_COUNT_AT_ONCE;
-	struct mem_cgroup *memcg = mc.to;
 
-	if (mem_cgroup_is_root(memcg)) {
+	if (mem_cgroup_is_root(mc.to)) {
 		mc.precharge += count;
 		/* we don't need css_get for root */
 		return ret;
 	}
-	/* try to charge at once */
-	if (count > 1) {
-		struct page_counter *dummy;
-		/*
-		 * "memcg" cannot be under rmdir() because we've already checked
-		 * by cgroup_lock_live_cgroup() that it is not removed and we
-		 * are still under the same cgroup_mutex. So we can postpone
-		 * css_get().
-		 */
-		if (page_counter_try_charge(&memcg->memory, count, &dummy))
-			goto one_by_one;
-		if (do_swap_account &&
-		    page_counter_try_charge(&memcg->memsw, count, &dummy)) {
-			page_counter_uncharge(&memcg->memory, count);
-			goto one_by_one;
-		}
+
+	/* Try a single bulk charge without reclaim first */
+	ret = mem_cgroup_try_charge(mc.to, GFP_KERNEL & ~__GFP_WAIT, count);
+	if (!ret) {
 		mc.precharge += count;
 		return ret;
 	}
-one_by_one:
-	/* fall back to one by one charge */
+
+	/* Try charges one by one with reclaim */
 	while (count--) {
-		if (signal_pending(current)) {
-			ret = -EINTR;
-			break;
-		}
-		if (!batch_count--) {
-			batch_count = PRECHARGE_COUNT_AT_ONCE;
-			cond_resched();
-		}
-		ret = mem_cgroup_try_charge(memcg,
+		ret = mem_cgroup_try_charge(mc.to,
 					    GFP_KERNEL & ~__GFP_NORETRY, 1);
+		/*
+		 * In case of failure, any residual charges against
+		 * mc.to will be dropped by mem_cgroup_clear_mc()
+		 * later on.
+		 */
 		if (ret)
-			/* mem_cgroup_clear_mc() will do uncharge later */
 			return ret;
 		mc.precharge++;
+		cond_resched();
 	}
-	return ret;
+	return 0;
 }
 
 /**


More information about the Devel mailing list