@@ -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;
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(-)