[Devel] [PATCH RHEL7 COMMIT] mm/workingset: fix possible race with memcg deletion.

Konstantin Khorenko khorenko at virtuozzo.com
Tue May 21 18:34:57 MSK 2019


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.1
------>
commit cf8a0c31ab620a4275584bec8c01ed09e5dded7a
Author: Andrey Ryabinin <aryabinin at virtuozzo.com>
Date:   Tue May 21 18:34:55 2019 +0300

    mm/workingset: fix possible race with memcg deletion.
    
    workingset_refault() releases RCU lock too soon, before the
    memcg_inc_ws_activate() which may result in crash if memcg deletion
    runs in parallel with workingset_refault()
    
    Fixes: f6a8b015027e ("ms/mm: workingset: per-cgroup cache thrash detection")
    Signed-off-by: Andrey Ryabinin <aryabinin at virtuozzo.com>
---
 mm/workingset.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/mm/workingset.c b/mm/workingset.c
index 1168cc122828..1d7bdbf7a5d6 100644
--- a/mm/workingset.c
+++ b/mm/workingset.c
@@ -250,6 +250,7 @@ bool workingset_refault(void *shadow)
 	unsigned long refault;
 	struct zone *zone;
 	int memcgid;
+	bool ret = false;
 
 	unpack_shadow(shadow, &memcgid, &zone, &eviction);
 
@@ -278,7 +279,6 @@ bool workingset_refault(void *shadow)
 	lruvec = mem_cgroup_zone_lruvec(zone, memcg);
 	refault = atomic_long_read(&lruvec->inactive_age);
 	active_file = lruvec_lru_size(lruvec, LRU_ACTIVE_FILE);
-	rcu_read_unlock();
 
 	/*
 	 * The unsigned subtraction here gives an accurate distance
@@ -303,9 +303,10 @@ bool workingset_refault(void *shadow)
 	if (refault_distance <= active_file) {
 		memcg_inc_ws_activate(memcg);
 		inc_zone_state(zone, WORKINGSET_ACTIVATE);
-		return true;
+		ret = true;
 	}
-	return false;
+	rcu_read_unlock();
+	return ret;
 }
 
 /**



More information about the Devel mailing list