Skip to content

Commit 116d573

Browse files
leitaoakpm00
authored andcommitted
selftests/mm: add a new test for madv and hugetlb
Create a selftest that exercises the race between page faults and madvise(MADV_DONTNEED) in the same huge page. Do it by running two threads that touches the huge page and madvise(MADV_DONTNEED) at the same time. In case of a SIGBUS coming at pagefault, the test should fail, since we hit the bug. The test doesn't have a signal handler, and if it fails, it fails like the following ---------------------------------- running ./hugetlb_fault_after_madv ---------------------------------- ./run_vmtests.sh: line 186: 595563 Bus error (core dumped) "$@" [FAIL] This selftest goes together with the fix of the bug[1] itself. [1] https://lore.kernel.org/all/[email protected]/#r Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Breno Leitao <[email protected]> Reviewed-by: Rik van Riel <[email protected]> Tested-by: Rik van Riel <[email protected]> Cc: Mike Kravetz <[email protected]> Cc: Muchun Song <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent c8b9073 commit 116d573

File tree

3 files changed

+78
-0
lines changed

3 files changed

+78
-0
lines changed

tools/testing/selftests/mm/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ TEST_GEN_FILES += split_huge_page_test
6969
TEST_GEN_FILES += ksm_tests
7070
TEST_GEN_FILES += ksm_functional_tests
7171
TEST_GEN_FILES += mdwe_test
72+
TEST_GEN_FILES += hugetlb_fault_after_madv
7273

7374
ifneq ($(ARCH),arm64)
7475
TEST_GEN_PROGS += soft-dirty
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
#include <pthread.h>
3+
#include <stdio.h>
4+
#include <stdlib.h>
5+
#include <sys/mman.h>
6+
#include <sys/types.h>
7+
#include <unistd.h>
8+
9+
#include "vm_util.h"
10+
#include "../kselftest.h"
11+
12+
#define MMAP_SIZE (1 << 21)
13+
#define INLOOP_ITER 100
14+
15+
char *huge_ptr;
16+
17+
/* Touch the memory while it is being madvised() */
18+
void *touch(void *unused)
19+
{
20+
char *ptr = (char *)huge_ptr;
21+
22+
for (int i = 0; i < INLOOP_ITER; i++)
23+
ptr[0] = '.';
24+
25+
return NULL;
26+
}
27+
28+
void *madv(void *unused)
29+
{
30+
usleep(rand() % 10);
31+
32+
for (int i = 0; i < INLOOP_ITER; i++)
33+
madvise(huge_ptr, MMAP_SIZE, MADV_DONTNEED);
34+
35+
return NULL;
36+
}
37+
38+
int main(void)
39+
{
40+
unsigned long free_hugepages;
41+
pthread_t thread1, thread2;
42+
/*
43+
* On kernel 6.4, we are able to reproduce the problem with ~1000
44+
* interactions
45+
*/
46+
int max = 10000;
47+
48+
srand(getpid());
49+
50+
free_hugepages = get_free_hugepages();
51+
if (free_hugepages != 1) {
52+
ksft_exit_skip("This test needs one and only one page to execute. Got %lu\n",
53+
free_hugepages);
54+
}
55+
56+
while (max--) {
57+
huge_ptr = mmap(NULL, MMAP_SIZE, PROT_READ | PROT_WRITE,
58+
MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB,
59+
-1, 0);
60+
61+
if ((unsigned long)huge_ptr == -1)
62+
ksft_exit_skip("Failed to allocated huge page\n");
63+
64+
pthread_create(&thread1, NULL, madv, NULL);
65+
pthread_create(&thread2, NULL, touch, NULL);
66+
67+
pthread_join(thread1, NULL);
68+
pthread_join(thread2, NULL);
69+
munmap(huge_ptr, MMAP_SIZE);
70+
}
71+
72+
return KSFT_PASS;
73+
}

tools/testing/selftests/mm/run_vmtests.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,10 @@ CATEGORY="hugetlb" run_test ./hugepage-mremap
223223
CATEGORY="hugetlb" run_test ./hugepage-vmemmap
224224
CATEGORY="hugetlb" run_test ./hugetlb-madvise
225225

226+
# For this test, we need one and just one huge page
227+
echo 1 > /proc/sys/vm/nr_hugepages
228+
CATEGORY="hugetlb" run_test ./hugetlb_fault_after_madv
229+
226230
if test_selected "hugetlb"; then
227231
echo "NOTE: These hugetlb tests provide minimal coverage. Use"
228232
echo " https://github.com/libhugetlbfs/libhugetlbfs.git for"

0 commit comments

Comments
 (0)