-
Notifications
You must be signed in to change notification settings - Fork 1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add mincore() test for pages cached by another process
It tests the result of mincore when memory is mapped and cached by another process. A file is mapped in both parent and child process.Then the mapped memory is accessed in the child process. The results of mincore are tested in the parent process. Closes: #460 Signed-off-by: Shwetha Subramanian. <shwetha@zilogic.com> Reviewed-by: Vijay Kumar B. <vijaykumar@zilogic.com> Acked-by: Jan Stancek <jstancek@redhat.com> Reviewed-by: Petr Vorel <pvorel@suse.cz>
- Loading branch information
Showing
3 changed files
with
114 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 |
---|---|---|
@@ -1,3 +1,4 @@ | ||
/mincore01 | ||
/mincore02 | ||
/mincore03 | ||
/mincore04 |
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,112 @@ | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
/* | ||
* Copyright (c) Zilogic Systems Pvt. Ltd., 2020 | ||
* Email: code@zilogic.com | ||
*/ | ||
|
||
/* | ||
* mincore04 | ||
* Test shows that pages mapped in one process(parent) and | ||
* faulted in another(child) results in mincore(in parent) reporting | ||
* that all mapped pages are resident. | ||
*/ | ||
|
||
#include <unistd.h> | ||
#include <sys/types.h> | ||
#include <sys/mman.h> | ||
#include <sys/types.h> | ||
#include <sys/stat.h> | ||
#include <sys/wait.h> | ||
#include <fcntl.h> | ||
#include <stdlib.h> | ||
#include "tst_test.h" | ||
|
||
#define NUM_PAGES 3 | ||
|
||
static int fd; | ||
static int size; | ||
static void *ptr; | ||
|
||
static void cleanup(void) | ||
{ | ||
if (fd > 0) | ||
SAFE_CLOSE(fd); | ||
if (ptr) { | ||
SAFE_MUNLOCK(ptr, size); | ||
SAFE_MUNMAP(ptr, size); | ||
} | ||
} | ||
|
||
static void setup(void) | ||
{ | ||
int page_size, ret; | ||
|
||
page_size = getpagesize(); | ||
size = page_size * NUM_PAGES; | ||
fd = SAFE_OPEN("FILE", O_CREAT | O_RDWR, 0600); | ||
SAFE_FTRUNCATE(fd, size); | ||
|
||
/* File pages from file creation are cleared from cache. */ | ||
SAFE_FSYNC(fd); | ||
ret = posix_fadvise(fd, 0, size, POSIX_FADV_DONTNEED); | ||
if (ret == -1) | ||
tst_brk(TBROK | TERRNO, "fadvise failed"); | ||
} | ||
|
||
static void lock_file(void) | ||
{ | ||
SAFE_MLOCK(ptr, size); | ||
TST_CHECKPOINT_WAKE(0); | ||
TST_CHECKPOINT_WAIT(1); | ||
} | ||
|
||
static int count_pages_in_cache(void) | ||
{ | ||
int locked_pages = 0; | ||
int count, ret; | ||
unsigned char vec[NUM_PAGES]; | ||
|
||
TST_CHECKPOINT_WAIT(0); | ||
|
||
ret = mincore(ptr, size, vec); | ||
if (ret == -1) | ||
tst_brk(TBROK | TERRNO, "mincore failed"); | ||
for (count = 0; count < NUM_PAGES; count++) { | ||
if (vec[count] & 1) | ||
locked_pages++; | ||
} | ||
|
||
TST_CHECKPOINT_WAKE(1); | ||
return locked_pages; | ||
} | ||
|
||
static void test_mincore(void) | ||
{ | ||
int locked_pages; | ||
|
||
ptr = SAFE_MMAP(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); | ||
pid_t child_pid = SAFE_FORK(); | ||
|
||
if (child_pid == 0) { | ||
lock_file(); | ||
exit(0); | ||
} | ||
|
||
locked_pages = count_pages_in_cache(); | ||
tst_reap_children(); | ||
|
||
if (locked_pages == NUM_PAGES) | ||
tst_res(TPASS, "mincore reports all %d pages locked by child process " | ||
"are resident", locked_pages); | ||
else | ||
tst_res(TFAIL, "mincore reports %d pages resident but %d pages " | ||
"locked by child process", locked_pages, NUM_PAGES); | ||
} | ||
|
||
static struct tst_test test = { | ||
.setup = setup, | ||
.cleanup = cleanup, | ||
.forks_child = 1, | ||
.test_all = test_mincore, | ||
.needs_checkpoints = 1, | ||
}; |