[RHEL7,COMMIT] memcg/kmem: don't show fake charge in usage and limits

Submitted by Vasily Averin on July 25, 2020, 6:21 a.m.

Details

Message ID 202007250621.06P6LsMg012639@vvs.co7.work.ct
State New
Series "memcg/kmem: don't show fake charge in usage and limits"
Headers show

Commit Message

Vasily Averin July 25, 2020, 6:21 a.m.
The commit is pushed to "branch-rh7-3.10.0-1127.10.1.vz7.162.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-1127.10.1.vz7.162.14
------>
commit 53024d44b4143601edbe887471e9e2e87bcfda08
Author: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
Date:   Sat Jul 25 09:21:54 2020 +0300

    memcg/kmem: don't show fake charge in usage and limits
    
    We've faced a problem with docker/containerd cgroups configuration code.
    It does write 1(-1) to memory.kmem.limit_in_bytes of newly created
    memory cgroup as a verification check that memory cgroup works (we've
    already made a pull request to containerd to remove this strange check).
    We have a fake charge of one page in each memory cgroup, so setting
    limit to 1 returns EBUSY because limit < usage.
    
    Let's add one page when updating kmem limit so that our fake charge does
    not implicitly reduce the limit and then showing kmem limit we will
    remove this fake page and show what was set originally.
    
    Note: now when setting -1 to kmem limit it will convert to real pages
    limit of PAGE_COUNTER_MAX+1, it looks like there is nothing bad in it,
    but save it here for history.
    
    Let's also remove one page when showing kmem usage and max usage, to
    maintain consistency between limits and usage.
    
    https://jira.sw.ru/browse/PSBM-106065
    
    Co-Developed-by: Andrey Ryabinin <aryabinin@virtuozzo.com>
    Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
    Reviewed-by: Andrey Ryabinin <aryabinin@virtuozzo.com>
---
 mm/memcontrol.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

Patch hide | download patch | download mbox

diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index fa7b2cad93add..9570e9d8487f7 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -4767,14 +4767,24 @@  static ssize_t mem_cgroup_read(struct cgroup *cont, struct cftype *cft,
 			val = (u64)mem_cgroup_usage(memcg, false) * PAGE_SIZE;
 		else if (counter == &memcg->memsw)
 			val = (u64)mem_cgroup_usage(memcg, true) * PAGE_SIZE;
+		else if (counter == &memcg->kmem)
+			 /* remove fake charge, see __memcg_activate_kmem() */
+			val = (u64)(page_counter_read(counter) - 1) * PAGE_SIZE;
 		else
 			val = (u64)page_counter_read(counter) * PAGE_SIZE;
 		break;
 	case RES_LIMIT:
-		val = (u64)counter->limit * PAGE_SIZE;
+		if (counter == &memcg->kmem)
+			/* remove fake charge from kmem limit, see __memcg_activate_kmem() */
+			val = (u64)(counter->limit - 1) * PAGE_SIZE;
+		else
+			val = (u64)counter->limit * PAGE_SIZE;
 		break;
 	case RES_MAX_USAGE:
 		val = (u64)counter->watermark * PAGE_SIZE;
+		 if (counter == &memcg->kmem)
+			 /* remove fake charge, see __memcg_activate_kmem() */
+			 val -= PAGE_SIZE;
 		break;
 	case RES_FAILCNT:
 		val = (u64)counter->failcnt;
@@ -4907,6 +4917,9 @@  static int memcg_update_kmem_limit(struct mem_cgroup *memcg,
 {
 	int ret;
 
+	/* add fake charge to kmem limit, see __memcg_activate_kmem() */
+	nr_pages++;
+
 	mutex_lock(&memcg_limit_mutex);
 	if (!memcg_kmem_is_active(memcg))
 		ret = memcg_activate_kmem(memcg, nr_pages);