forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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]>
- Loading branch information
Showing
3 changed files
with
78 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
#include <pthread.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <sys/mman.h> | ||
#include <sys/types.h> | ||
#include <unistd.h> | ||
|
||
#include "vm_util.h" | ||
#include "../kselftest.h" | ||
|
||
#define MMAP_SIZE (1 << 21) | ||
#define INLOOP_ITER 100 | ||
|
||
char *huge_ptr; | ||
|
||
/* Touch the memory while it is being madvised() */ | ||
void *touch(void *unused) | ||
{ | ||
char *ptr = (char *)huge_ptr; | ||
|
||
for (int i = 0; i < INLOOP_ITER; i++) | ||
ptr[0] = '.'; | ||
|
||
return NULL; | ||
} | ||
|
||
void *madv(void *unused) | ||
{ | ||
usleep(rand() % 10); | ||
|
||
for (int i = 0; i < INLOOP_ITER; i++) | ||
madvise(huge_ptr, MMAP_SIZE, MADV_DONTNEED); | ||
|
||
return NULL; | ||
} | ||
|
||
int main(void) | ||
{ | ||
unsigned long free_hugepages; | ||
pthread_t thread1, thread2; | ||
/* | ||
* On kernel 6.4, we are able to reproduce the problem with ~1000 | ||
* interactions | ||
*/ | ||
int max = 10000; | ||
|
||
srand(getpid()); | ||
|
||
free_hugepages = get_free_hugepages(); | ||
if (free_hugepages != 1) { | ||
ksft_exit_skip("This test needs one and only one page to execute. Got %lu\n", | ||
free_hugepages); | ||
} | ||
|
||
while (max--) { | ||
huge_ptr = mmap(NULL, MMAP_SIZE, PROT_READ | PROT_WRITE, | ||
MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB, | ||
-1, 0); | ||
|
||
if ((unsigned long)huge_ptr == -1) | ||
ksft_exit_skip("Failed to allocated huge page\n"); | ||
|
||
pthread_create(&thread1, NULL, madv, NULL); | ||
pthread_create(&thread2, NULL, touch, NULL); | ||
|
||
pthread_join(thread1, NULL); | ||
pthread_join(thread2, NULL); | ||
munmap(huge_ptr, MMAP_SIZE); | ||
} | ||
|
||
return KSFT_PASS; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters