• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (C) 2024 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
4  */
5 
6 /*\
7  * [Description]
8  *
9  * This test verifies that cachestat() syscall is properly counting cached pages
10  * written inside a shared memory.
11  *
12  * [Algorithm]
13  *
14  * - create a shared memory with a specific amount of pages
15  * - monitor file with cachestat()
16  * - check if the right amount of pages have been moved into cache
17  */
18 
19 #include <stdlib.h>
20 #include "cachestat.h"
21 
22 #define FILENAME "myfile.bin"
23 
24 static int page_size;
25 static char *page_data;
26 static struct cachestat *cs;
27 static struct cachestat_range *cs_range;
28 
test_cached_pages(const int num_pages)29 static void test_cached_pages(const int num_pages)
30 {
31 	int fd, file_size;
32 
33 	tst_res(TINFO, "Number of pages: %d", num_pages);
34 
35 	memset(cs, 0, sizeof(struct cachestat));
36 
37 	fd = shm_open(FILENAME, O_RDWR | O_CREAT, 0600);
38 	if (fd < 0)
39 		tst_brk(TBROK | TERRNO, "shm_open error");
40 
41 	file_size = page_size * num_pages;
42 
43 	cs_range->off = 0;
44 	cs_range->len = file_size;
45 
46 	SAFE_FTRUNCATE(fd, file_size);
47 	for (int i = 0; i < num_pages; i++)
48 		SAFE_WRITE(0, fd, page_data, page_size);
49 
50 	memset(cs, 0xff, sizeof(*cs));
51 
52 	TST_EXP_PASS(cachestat(fd, cs_range, cs, 0));
53 	print_cachestat(cs);
54 
55 	TST_EXP_EQ_LI(cs->nr_cache + cs->nr_evicted, num_pages);
56 
57 	SAFE_CLOSE(fd);
58 	shm_unlink(FILENAME);
59 }
60 
run(void)61 static void run(void)
62 {
63 	for (int i = 0; i < 10; i++)
64 		test_cached_pages(1 << i);
65 }
66 
setup(void)67 static void setup(void)
68 {
69 	page_size = (int)sysconf(_SC_PAGESIZE);
70 
71 	page_data = SAFE_MALLOC(page_size);
72 	memset(page_data, 'a', page_size);
73 }
74 
cleanup(void)75 static void cleanup(void)
76 {
77 	free(page_data);
78 }
79 
80 static struct tst_test test = {
81 	.test_all = run,
82 	.setup = setup,
83 	.cleanup = cleanup,
84 	.needs_tmpdir = 1,
85 	.bufs = (struct tst_buffers []) {
86 		{&cs, .size = sizeof(struct cachestat)},
87 		{&cs_range, .size = sizeof(struct cachestat_range)},
88 		{}
89 	},
90 };
91