diff mbox series

[v4,2/2] lib: memutils: include also available memory when polluting

Message ID 20211021083547.111590-2-krzysztof.kozlowski@canonical.com
State Accepted
Headers show
Series [v4,1/2] lib: memutils: respect minimum memory watermark when polluting memory | expand

Commit Message

Krzysztof Kozlowski Oct. 21, 2021, 8:35 a.m. UTC
Usually available memory (MemAvailable from /proc/meminfo) is higher
than free memory, although not always. On kernel v5.14 the formula is
approximately:
  available = free - reserved + pagecache + reclaimable

The reserved part comes from vm.min_free_kbytes (already included in
previous patch: lib: memutils: respect minimum memory watermark when
polluting memory) and vm.lowmem_reserve_ratio. If user set specific
vm.lowmem_reserve_ratio (sysctl), the available memory could be actually
lower than free.

Use lower value of these (free/available), to avoid out-of-memory killer
for such system configurations.

Reported-by: Li Wang <liwang@redhat.com>
Reported-by: Liu Xinpeng <liuxp11@chinatelecom.cn>
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>

---

Changes since v3:
1. New patch
---
 lib/tst_memutils.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

Comments

Li Wang Oct. 21, 2021, 9:45 a.m. UTC | #1
Hi Krzysztof,

Thanks for the fixes. For the series:

Reviewed-by: Li Wang <liwang@redhat.com>
liuxp11@chinatelecom.cn Oct. 21, 2021, 10:51 a.m. UTC | #2
Good solution,thanks.

Reviewed-by: Liu Xinpeng <liuxp11@chinatelecom.cn>
diff mbox series

Patch

diff --git a/lib/tst_memutils.c b/lib/tst_memutils.c
index df53c542d239..bd09cf6fad9b 100644
--- a/lib/tst_memutils.c
+++ b/lib/tst_memutils.c
@@ -16,6 +16,7 @@ 
 void tst_pollute_memory(size_t maxsize, int fillchar)
 {
 	size_t i, map_count = 0, safety = 0, blocksize = BLOCKSIZE;
+	unsigned long long freeram;
 	unsigned long min_free;
 	void **map_blocks;
 	struct sysinfo info;
@@ -33,15 +34,24 @@  void tst_pollute_memory(size_t maxsize, int fillchar)
 	if (info.freeswap > safety)
 		safety = 0;
 
+	/*
+	 * MemFree usually is lower than MemAvailable, although when setting
+	 * sysctl vm.lowmem_reserve_ratio, this could reverse.
+	 *
+	 * Use the lower value of both for pollutable memory. Usually this
+	 * means we will not evict any caches.
+	 */
+	freeram = MIN(info.freeram, (tst_available_mem() * 1024));
+
 	/* Not enough free memory to avoid invoking OOM killer */
-	if (info.freeram <= safety)
+	if (freeram <= safety)
 		return;
 
 	if (!maxsize)
 		maxsize = SIZE_MAX;
 
-	if (info.freeram - safety < maxsize / info.mem_unit)
-		maxsize = (info.freeram - safety) * info.mem_unit;
+	if (freeram - safety < maxsize / info.mem_unit)
+		maxsize = (freeram - safety) * info.mem_unit;
 
 	blocksize = MIN(maxsize, blocksize);
 	map_count = maxsize / blocksize;