[Devel] [PATCH rh7] memcg, bc/vm_pages.c: account some swapped memory as used in CT in /proc/meminfo

Andrey Ryabinin aryabinin at virtuozzo.com
Tue Mar 17 17:37:39 MSK 2020


If swapped memory of container exceed CT's swap size (can happen
on external memory pressure) it's unaccounted in /proc/meminfo.

Fix this by adding swapped above swap size to used counter.
Ideally we should also add this to inactive anon and/or shmem, but
we don't really know what was swapped, so leave it as is.

https://jira.sw.ru/browse/PSBM-102266
Signed-off-by: Andrey Ryabinin <aryabinin at virtuozzo.com>
---
 kernel/bc/vm_pages.c | 33 +++++----------------------------
 mm/memcontrol.c      | 29 +++++++++++++++++++++++++++++
 2 files changed, 34 insertions(+), 28 deletions(-)

diff --git a/kernel/bc/vm_pages.c b/kernel/bc/vm_pages.c
index 0e44c8e86118..e5019c0a44a3 100644
--- a/kernel/bc/vm_pages.c
+++ b/kernel/bc/vm_pages.c
@@ -155,42 +155,19 @@ int ub_enough_memory(struct mm_struct *mm, long pages)
 	return ret;
 }
 
+extern void mem_cgroup_fill_sysinfo(struct mem_cgroup *memcg, struct sysinfo *si);
 static int bc_fill_sysinfo(struct user_beancounter *ub,
 		unsigned long meminfo_val, struct sysinfo *si)
 {
-	unsigned long used, total;
-	unsigned long totalram, totalswap;
+	struct cgroup_subsys_state *css;
 
 	/* No virtualization */
 	if (meminfo_val == VE_MEMINFO_SYSTEM)
 		return NOTIFY_DONE | NOTIFY_STOP_MASK;
 
-	totalram = si->totalram;
-	totalswap = si->totalswap;
-
-	memset(si, 0, sizeof(*si));
-
-	ub_sync_memcg(ub);
-
-	total = ub->ub_parms[UB_PHYSPAGES].limit;
-	used = ub->ub_parms[UB_PHYSPAGES].held;
-
-	if (total == UB_MAXVALUE)
-		total = totalram;
-
-	si->totalram = total;
-	si->freeram = (total > used ? total - used : 0);
-
-	total = ub->ub_parms[UB_SWAPPAGES].limit;
-	used = ub->ub_parms[UB_SWAPPAGES].held;
-
-	if (total == UB_MAXVALUE)
-		total = totalswap;
-
-	si->totalswap = total;
-	si->freeswap = (total > used ? total - used : 0);
-
-	si->mem_unit = PAGE_SIZE;
+	css = ub_get_mem_css(ub);
+	mem_cgroup_fill_sysinfo(mem_cgroup_from_cont(css->cgroup), si);
+	css_put(css);
 
 	return NOTIFY_OK;
 }
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 4846e7a9bf63..897913b1b8d8 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -4650,6 +4650,35 @@ void mem_cgroup_fill_meminfo(struct mem_cgroup *memcg, struct meminfo *mi)
 	mi->available += mi->slab_reclaimable;
 }
 
+void mem_cgroup_fill_sysinfo(struct mem_cgroup *memcg, struct sysinfo *si)
+{
+	unsigned long totalram, totalswap;
+	unsigned long swaped, used;
+
+	totalram = si->totalram;
+	totalswap = si->totalswap;
+
+	memset(si, 0, sizeof(*si));
+
+	used = page_counter_read(&memcg->memory);
+	si->totalram = min(totalram, memcg->memory.limit);
+
+	swaped = page_counter_read(&memcg->memsw) - page_counter_read(&memcg->memory);
+	si->totalswap = min(totalswap, memcg->memsw.limit - memcg->memory.limit);
+
+	used = page_counter_read(&memcg->memory);
+
+	if (swaped > si->totalswap) {
+		si->freeswap = 0;
+		used += swaped - si->totalswap;
+	} else {
+		si->freeswap = si->totalswap - swaped;
+	}
+
+	si->freeram = (si->totalram > used ? si->totalram - used : 0);
+	si->mem_unit = PAGE_SIZE;
+}
+
 int mem_cgroup_enough_memory(struct mem_cgroup *memcg, long pages)
 {
 	long free;
-- 
2.24.1



More information about the Devel mailing list