mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2026-08-09 06:14:34 +02:00
The droppable test currently relies on creating memory pressure in a child
process to trigger dropping the droppable pages.
That not only takes a long time on some machines (allocating and filling
all that memory), on large machines this will not work as we hardcode the
area size to 134217728 bytes.
... further, we rely on timeouts to detect that memory was not dropped,
which is really suboptimal.
Instead, let's just use MADV_PAGEOUT on a 2 MiB region. MADV_PAGEOUT
works with droppable memory even without swap.
There is the low chance of MADV_PAGEOUT failing to drop a page because of
speculative references. We'll wait 1s and retry 10 times to rule that
unlikely case out as best as we can.
On a machine without swap:
$ ./droppable
TAP version 13
1..1
ok 1 madvise(MADV_PAGEOUT) behavior
# Totals: pass:1 fail:0 xfail:0 xpass:0 skip:0 error:0
Link: https://lore.kernel.org/20260611-droppable_test-v1-1-b6a73d99f658@kernel.org
Fixes: 9651fcedf7 ("mm: add MAP_DROPPABLE for designating always lazily freeable mappings")
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Reported-by: Aishwarya TCV <Aishwarya.TCV@arm.com>
Tested-by: Sarthak Sharma <sarthak.sharma@arm.com>
Tested-by: Lance Yang <lance.yang@linux.dev>
Reviewed-by: Dev Jain <dev.jain@arm.com>
Reviewed-by: SeongJae Park <sj@kernel.org>
Tested-by: Lorenzo Stoakes <ljs@kernel.org>
Reviewed-by: Lorenzo Stoakes <ljs@kernel.org>
Reviewed-by: Jason A. Donenfeld <Jason@zx2c4.com>
Cc: Anthony Yznaga <anthony.yznaga@oracle.com>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Mark Brown <broonie@kernel.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Shuah Khan <shuah@kernel.org>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Vlastimil Babka <vbabka@kernel.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
67 lines
1.5 KiB
C
67 lines
1.5 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* Copyright (C) 2024 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
|
|
*/
|
|
|
|
#include <assert.h>
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <signal.h>
|
|
#include <sys/mman.h>
|
|
#include <linux/mman.h>
|
|
|
|
#include "kselftest.h"
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
const size_t alloc_size = 2 * 1024 * 1024;
|
|
int retry_count = 10;
|
|
bool dropped;
|
|
void *alloc;
|
|
|
|
ksft_print_header();
|
|
ksft_set_plan(1);
|
|
|
|
alloc = mmap(0, alloc_size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_DROPPABLE, -1, 0);
|
|
if (alloc == MAP_FAILED) {
|
|
if ((errno == EOPNOTSUPP) || (errno == EINVAL)) {
|
|
ksft_test_result_skip("MAP_DROPPABLE not supported\n");
|
|
exit(KSFT_SKIP);
|
|
}
|
|
ksft_test_result_fail("mmap error: %s\n", strerror(errno));
|
|
exit(KSFT_FAIL);
|
|
}
|
|
memset(alloc, 'A', alloc_size);
|
|
|
|
while (retry_count--) {
|
|
if (madvise(alloc, alloc_size, MADV_PAGEOUT)) {
|
|
if (errno == EINVAL) {
|
|
ksft_test_result_skip("madvise(MADV_PAGEOUT) not supported\n");
|
|
exit(KSFT_SKIP);
|
|
}
|
|
ksft_test_result_fail("madvise(MADV_PAGEOUT) error: %s\n", strerror(errno));
|
|
exit(KSFT_FAIL);
|
|
}
|
|
|
|
dropped = memchr(alloc, 'A', alloc_size) == NULL;
|
|
|
|
/*
|
|
* Speculative reference can temporarily prevent some
|
|
* pages from getting dropped. So sleep and retry.
|
|
*
|
|
* If a page is not droppable for 10s, something
|
|
* is seriously messed up and we want to fail.
|
|
*/
|
|
if (dropped)
|
|
break;
|
|
sleep(1);
|
|
}
|
|
|
|
ksft_test_result(dropped, "madvise(MADV_PAGEOUT) behavior\n");
|
|
|
|
ksft_finished();
|
|
}
|