[RHEL7,COMMIT] mm/memcontrol: try to free all memcg during offline

Submitted by Konstantin Khorenko on April 27, 2018, 10:55 a.m.

Details

Message ID 201804271055.w3RAtAvS001087@finist_ce7.work
State New
Series "Series without cover letter"
Headers show

Commit Message

Konstantin Khorenko April 27, 2018, 10:55 a.m.
The commit is pushed to "branch-rh7-3.10.0-693.21.1.vz7.47.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-693.21.1.vz7.47.2
------>
commit b2da9c48ff3fa83487d293a05c804eafeaa285f6
Author: Andrey Ryabinin <aryabinin@virtuozzo.com>
Date:   Fri Apr 27 13:55:10 2018 +0300

    mm/memcontrol: try to free all memcg during offline
    
    Currently we don't reclaim memory on memcg offlining.
    kmem in memcg pins cgroup indefinitely which don't allow
    us to reuse cgroup's id. Since cgroups id count is limited
    to ~65K we may exhaust all possible ids.
    
    Try to free all memcg memory during offline. This should
    allow us to destroy cgroup almost immedieatly and reuse id.
    
    https://jira.sw.ru/browse/PSBM-83628
    Signed-off-by: Andrey Ryabinin <aryabinin@virtuozzo.com>
---
 mm/memcontrol.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

Patch hide | download patch | download mbox

diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 6b78b97f6084..65c069a1eeae 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -6158,6 +6158,19 @@  static void mem_cgroup_invalidate_reclaim_iterators(struct mem_cgroup *memcg)
 		mem_cgroup_iter_invalidate(root_mem_cgroup);
 }
 
+static void mem_cgroup_free_all(struct mem_cgroup *memcg)
+{
+	int nr_retries = 5;
+
+	lru_add_drain_all();
+
+	while (nr_retries && page_counter_read(&memcg->memory))
+		if (!try_to_free_mem_cgroup_pages(memcg, -1UL, GFP_KERNEL, 0))
+			nr_retries--;
+
+	lru_add_drain();
+}
+
 static void mem_cgroup_css_offline(struct cgroup *cont)
 {
 	struct mem_cgroup *memcg = mem_cgroup_from_cont(cont);
@@ -6187,6 +6200,7 @@  static void mem_cgroup_css_offline(struct cgroup *cont)
 		rcu_read_lock();
 	}
 	rcu_read_unlock();
+	mem_cgroup_free_all(memcg);
 	mem_cgroup_reparent_charges(memcg);
 
 	/*