• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) Zilogic Systems Pvt. Ltd., 2020
4  * Email: code@zilogic.com
5  */
6 
7 /*
8  * mincore04
9  * Test shows that pages mapped in one process(parent) and
10  * faulted in another(child) results in mincore(in parent) reporting
11  * that all mapped pages are resident.
12  */
13 
14 #include <unistd.h>
15 #include <sys/types.h>
16 #include <sys/mman.h>
17 #include <sys/types.h>
18 #include <sys/stat.h>
19 #include <sys/wait.h>
20 #include <fcntl.h>
21 #include <stdlib.h>
22 #include "tst_test.h"
23 
24 #define NUM_PAGES 3
25 
26 static int fd;
27 static int size;
28 static void *ptr;
29 
cleanup(void)30 static void cleanup(void)
31 {
32 	if (fd > 0)
33 		SAFE_CLOSE(fd);
34 	if (ptr) {
35 		SAFE_MUNLOCK(ptr, size);
36 		SAFE_MUNMAP(ptr, size);
37 	}
38 }
39 
setup(void)40 static void setup(void)
41 {
42 	int page_size, ret;
43 
44 	page_size = getpagesize();
45 	size = page_size * NUM_PAGES;
46 	fd = SAFE_OPEN("FILE", O_CREAT | O_RDWR, 0600);
47 	SAFE_FTRUNCATE(fd, size);
48 
49 	/* File pages from file creation are cleared from cache. */
50 	SAFE_FSYNC(fd);
51 	ret = posix_fadvise(fd, 0, size, POSIX_FADV_DONTNEED);
52 	if (ret == -1)
53 		tst_brk(TBROK | TERRNO, "fadvise failed");
54 }
55 
lock_file(void)56 static void lock_file(void)
57 {
58 	SAFE_MLOCK(ptr, size);
59 	TST_CHECKPOINT_WAKE(0);
60 	TST_CHECKPOINT_WAIT(1);
61 }
62 
count_pages_in_cache(void)63 static int count_pages_in_cache(void)
64 {
65 	int locked_pages = 0;
66 	int count, ret;
67 	unsigned char vec[NUM_PAGES];
68 
69 	TST_CHECKPOINT_WAIT(0);
70 
71 	ret = mincore(ptr, size, vec);
72 	if (ret == -1)
73 		tst_brk(TBROK | TERRNO, "mincore failed");
74 	for (count = 0; count < NUM_PAGES; count++) {
75 		if (vec[count] & 1)
76 			locked_pages++;
77 	}
78 
79 	TST_CHECKPOINT_WAKE(1);
80 	return locked_pages;
81 }
82 
test_mincore(void)83 static void test_mincore(void)
84 {
85 	int  locked_pages;
86 
87 	ptr = SAFE_MMAP(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
88 	pid_t child_pid = SAFE_FORK();
89 
90 	if (child_pid == 0) {
91 		lock_file();
92 		exit(0);
93 	}
94 
95 	locked_pages = count_pages_in_cache();
96 	tst_reap_children();
97 
98 	if (locked_pages == NUM_PAGES)
99 		tst_res(TPASS, "mincore reports all %d pages locked by child process "
100 			"are resident", locked_pages);
101 	else
102 		tst_res(TFAIL, "mincore reports %d pages resident but %d pages "
103 			"locked by child process", locked_pages, NUM_PAGES);
104 }
105 
106 static struct tst_test test = {
107 	.setup = setup,
108 	.cleanup = cleanup,
109 	.forks_child = 1,
110 	.test_all = test_mincore,
111 	.needs_checkpoints = 1,
112 };
113