blob: 7fad17ab3cddd22baf46adadbf79a793ef56dd24 [file] [log] [blame]
subrata_modakfcfd1602007-10-17 14:33:24 +00001/*
2 * Copyright (C) Ingo Molnar, 2002
3 * Copyright (C) Ricardo Salveti de Araujo, 2007
4 * Copyright (C) International Business Machines Corp., 2007
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of version 2 of the GNU General Public License as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it would be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 *
14 * Further, this software is distributed without any warranty that it is
15 * free of the rightful claim of any third person regarding infringement
16 * or the like. Any license provided herein, whether implied or
17 * otherwise, applies only to this software file. Patent licenses, if
18 * any, provided herein do not apply to combinations of this program with
19 * other software, or any other product whatsoever.
20 *
21 * You should have received a copy of the GNU General Public License along
Wanlong Gaofed96412012-10-24 10:10:29 +080022 * with this program; if not, write the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
subrata_modakfcfd1602007-10-17 14:33:24 +000024 */
25
26/*
27 * NAME
28 * remap_file_pages01
29 *
30 * DESCRIPTION
31 * The remap_file_pages() system call is used to create a non-linear
32 * mapping, that is, a mapping in which the pages of the file are mapped
33 * into a non-sequential order in memory. The advantage of using
34 * remap_file_pages() over using repeated calls to mmap(2) is that
35 * the former approach does not require the kernel to create
36 * additional VMA (Virtual Memory Area) data structures.
37 *
subrata_modak4bb656a2009-02-26 12:02:09 +000038 * Runs remap_file_pages agains a mmaped area and check the results
subrata_modakfcfd1602007-10-17 14:33:24 +000039 *
40 * Setup:
41 * Create a temp directory, open a file and get the file descriptor
42 *
43 * Test:
subrata_modakcf179582008-02-26 08:01:53 +000044 * Test with a normal file and with /dev/shm/cache_<pid>
subrata_modakfcfd1602007-10-17 14:33:24 +000045 * 1. Set up the cache
46 * 2. Write the cache to the file
subrata_modak4bb656a2009-02-26 12:02:09 +000047 * 3. Runs mmap at the same file
subrata_modakfcfd1602007-10-17 14:33:24 +000048 * 4. Runs remap_file_pages at the mapped memory
49 * 5. Check the results
subrata_modak56207ce2009-03-23 13:35:39 +000050 * $
subrata_modakfcfd1602007-10-17 14:33:24 +000051 * Cleanup:
52 * Remove the file and erase the tmp directory
53 *
54 * Usage: <for command-line>
55 * remap_file_pages01 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
56 * where, -c n : Run n copies concurrently.
57 * -f : Turn off functionality Testing.
58 * -i n : Execute test n times.
59 * -I x : Execute test for x seconds.
60 * -P x : Pause for x seconds between iterations.
61 * -t : Turn on syscall timing.
62 *
63 * HISTORY
64 * - Ingo Molnar, <mingo@elte.hu> wrote this test case
65 * - Nick Piggin, <nickpiggin@yahoo.com.au> did the following cleanup
66 *
67 * 11/10/2007 - Port to LTP format by Subrata Modak, <subrata@linux.vnet.ibm.com>
68 * and Ricardo Salveti de Araujo, <rsalveti@linux.vnet.ibm.com>
subrata_modakcf179582008-02-26 08:01:53 +000069 * 25/02/2008 - Renaud Lottiaux, <Renaud.Lottiaux@kerlabs.com>
70 * Fix NFS remove tmpdir issue due to non unmapped files.
71 * Fix concurrency issue on the file /dev/shm/cache.
subrata_modakfcfd1602007-10-17 14:33:24 +000072 */
73
74#define _GNU_SOURCE
75#include <stdio.h>
76#include <unistd.h>
77#include <sys/mman.h>
78#include <sys/stat.h>
79#include <sys/types.h>
80#include <fcntl.h>
81#include <errno.h>
82#include <stdlib.h>
83#include <sys/times.h>
84#include <sys/wait.h>
85#include <sys/ioctl.h>
86#include <sys/syscall.h>
87#include <linux/unistd.h>
88
subrata_modak56207ce2009-03-23 13:35:39 +000089#include "test.h" /*LTP Specific Include File */
subrata_modakfcfd1602007-10-17 14:33:24 +000090
91/* Test case defines */
92#define WINDOW_START 0x48000000
93
Zeng Linggang9d048f82015-01-29 18:20:45 +080094static int page_sz;
subrata_modakfcfd1602007-10-17 14:33:24 +000095size_t page_words;
96size_t cache_pages;
97size_t cache_sz;
98size_t window_pages;
99size_t window_sz;
100
101static void setup();
102static void cleanup();
103static void test_nonlinear(int fd);
104
Cyril Hrubisfdce7d52013-04-04 18:35:48 +0200105char *TCID = "remap_file_pages01";
106int TST_TOTAL = 2;
subrata_modakfcfd1602007-10-17 14:33:24 +0000107
108static char *cache_contents;
subrata_modak56207ce2009-03-23 13:35:39 +0000109int fd1, fd2; /* File descriptors used at the test */
subrata_modakcf179582008-02-26 08:01:53 +0000110char fname[255];
subrata_modakfcfd1602007-10-17 14:33:24 +0000111
subrata_modak56207ce2009-03-23 13:35:39 +0000112int main(int ac, char **av)
subrata_modakfcfd1602007-10-17 14:33:24 +0000113{
Cyril Hrubis89af32a2012-10-24 16:39:11 +0200114 int lc;
Cyril Hrubis0b9589f2014-05-27 17:40:33 +0200115 const char *msg;
subrata_modakfcfd1602007-10-17 14:33:24 +0000116
subrata_modak631d20d2008-10-15 15:12:21 +0000117#if defined (__s390__) || (__s390x__) || (__ia64__)
subrata_modak6aa34d02008-01-21 06:52:54 +0000118 /* Disables the test in case the kernel version is lower than 2.6.12 and arch is s390 */
subrata_modak56207ce2009-03-23 13:35:39 +0000119 if ((tst_kvercmp(2, 6, 12)) < 0) {
120 tst_resm(TWARN,
121 "This test can only run on kernels that are 2.6.12 and higher");
subrata_modak6aa34d02008-01-21 06:52:54 +0000122 exit(0);
123 }
124#endif
125
Garrett Cooper45e285d2010-11-22 12:19:25 -0800126 if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) {
Garrett Cooper60fa8012010-11-22 13:50:58 -0800127 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
subrata_modakfcfd1602007-10-17 14:33:24 +0000128 }
129
subrata_modakfcfd1602007-10-17 14:33:24 +0000130 setup();
131
subrata_modakfcfd1602007-10-17 14:33:24 +0000132 for (lc = 0; TEST_LOOPING(lc); lc++) {
133
Caspar Zhangd59a6592013-03-07 14:59:12 +0800134 tst_count = 0;
subrata_modakfcfd1602007-10-17 14:33:24 +0000135
136 test_nonlinear(fd1);
137 tst_resm(TPASS, "Non-Linear shm file OK");
138
139 test_nonlinear(fd2);
140 tst_resm(TPASS, "Non-Linear /tmp/ file OK");
141 }
142
143 /* clean up and exit */
144 cleanup();
Garrett Cooper1e6f5a62010-12-19 09:58:10 -0800145 tst_exit();
subrata_modakfcfd1602007-10-17 14:33:24 +0000146
subrata_modakfcfd1602007-10-17 14:33:24 +0000147}
148
149/* test case function, that runs remap_file_pages */
150static void test_nonlinear(int fd)
151{
152 char *data = NULL;
153 int i, j, repeat = 2;
154
155 for (i = 0; i < cache_pages; i++) {
subrata_modak56207ce2009-03-23 13:35:39 +0000156 char *page = cache_contents + i * page_sz;
subrata_modakfcfd1602007-10-17 14:33:24 +0000157
158 for (j = 0; j < page_words; j++)
159 page[j] = i;
160 }
161
162 if (write(fd, cache_contents, cache_sz) != cache_sz) {
subrata_modak56207ce2009-03-23 13:35:39 +0000163 tst_resm(TFAIL,
Markos Chandrasf4539c62012-01-03 09:41:10 +0000164 "Write Error for \"cache_contents\" to \"cache_sz\" of %zu (errno=%d : %s)",
subrata_modakfcfd1602007-10-17 14:33:24 +0000165 cache_sz, errno, strerror(errno));
subrata_modak8b2171f2008-02-26 07:52:26 +0000166 cleanup(NULL);
subrata_modakfcfd1602007-10-17 14:33:24 +0000167 }
168
169 data = mmap((void *)WINDOW_START,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800170 window_sz, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
subrata_modakfcfd1602007-10-17 14:33:24 +0000171
172 if (data == MAP_FAILED) {
subrata_modak56207ce2009-03-23 13:35:39 +0000173 tst_resm(TFAIL, "mmap Error, errno=%d : %s", errno,
174 strerror(errno));
subrata_modak8b2171f2008-02-26 07:52:26 +0000175 cleanup(NULL);
subrata_modakfcfd1602007-10-17 14:33:24 +0000176 }
177
Wanlong Gao354ebb42012-12-07 10:10:04 +0800178again:
subrata_modakfcfd1602007-10-17 14:33:24 +0000179 for (i = 0; i < window_pages; i += 2) {
subrata_modak56207ce2009-03-23 13:35:39 +0000180 char *page = data + i * page_sz;
subrata_modakfcfd1602007-10-17 14:33:24 +0000181
182 if (remap_file_pages(page, page_sz * 2, 0,
subrata_modak56207ce2009-03-23 13:35:39 +0000183 (window_pages - i - 2), 0) == -1) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800184 tst_resm(TFAIL | TERRNO,
Zeng Linggang9d048f82015-01-29 18:20:45 +0800185 "remap_file_pages error for page=%p, "
186 "page_sz=%d, window_pages=%zu",
subrata_modak923b23f2009-11-02 13:57:16 +0000187 page, (page_sz * 2), (window_pages - i - 2));
subrata_modak8b2171f2008-02-26 07:52:26 +0000188 cleanup(data);
subrata_modakfcfd1602007-10-17 14:33:24 +0000189 }
190 }
191
192 for (i = 0; i < window_pages; i++) {
193 /*
194 * Double-check the correctness of the mapping:
195 */
196 if (i & 1) {
subrata_modak56207ce2009-03-23 13:35:39 +0000197 if (data[i * page_sz] != window_pages - i) {
198 tst_resm(TFAIL,
Zeng Linggang9d048f82015-01-29 18:20:45 +0800199 "hm, mapped incorrect data, "
200 "data[%d]=%d, (window_pages-%d)=%zu",
subrata_modak56207ce2009-03-23 13:35:39 +0000201 (i * page_sz), data[i * page_sz], i,
202 (window_pages - i));
subrata_modak8b2171f2008-02-26 07:52:26 +0000203 cleanup(data);
subrata_modakfcfd1602007-10-17 14:33:24 +0000204 }
205 } else {
subrata_modak56207ce2009-03-23 13:35:39 +0000206 if (data[i * page_sz] != window_pages - i - 2) {
207 tst_resm(TFAIL,
Zeng Linggang9d048f82015-01-29 18:20:45 +0800208 "hm, mapped incorrect data, "
209 "data[%d]=%d, (window_pages-%d-2)=%zu",
subrata_modak56207ce2009-03-23 13:35:39 +0000210 (i * page_sz), data[i * page_sz], i,
211 (window_pages - i - 2));
212 cleanup(data);
subrata_modakfcfd1602007-10-17 14:33:24 +0000213 }
214 }
215 }
216
217 if (--repeat)
218 goto again;
subrata_modak8b2171f2008-02-26 07:52:26 +0000219
subrata_modak56207ce2009-03-23 13:35:39 +0000220 munmap(data, window_sz);
subrata_modakfcfd1602007-10-17 14:33:24 +0000221}
222
223/* setup() - performs all ONE TIME setup for this test */
Mike Frysingerc57fba52014-04-09 18:56:30 -0400224void setup(void)
subrata_modakfcfd1602007-10-17 14:33:24 +0000225{
Garrett Cooper2c282152010-12-16 00:55:50 -0800226
subrata_modakfcfd1602007-10-17 14:33:24 +0000227 tst_sig(FORK, DEF_HANDLER, cleanup);
228
subrata_modakfcfd1602007-10-17 14:33:24 +0000229 tst_tmpdir();
230
subrata_modakfcfd1602007-10-17 14:33:24 +0000231 TEST_PAUSE;
232
233 /* Get page size */
Zeng Linggang9d048f82015-01-29 18:20:45 +0800234 page_sz = getpagesize();
subrata_modakfcfd1602007-10-17 14:33:24 +0000235
Zeng Linggang9d048f82015-01-29 18:20:45 +0800236 page_words = page_sz;
subrata_modakfcfd1602007-10-17 14:33:24 +0000237
238 /* Set the cache size */
239 cache_pages = 1024;
subrata_modak56207ce2009-03-23 13:35:39 +0000240 cache_sz = cache_pages * page_sz;
Cyril Hrubisd218f342014-09-23 13:14:56 +0200241 cache_contents = malloc(cache_sz * sizeof(char));
subrata_modakfcfd1602007-10-17 14:33:24 +0000242
243 /* Set the window size */
244 window_pages = 16;
subrata_modak56207ce2009-03-23 13:35:39 +0000245 window_sz = window_pages * page_sz;
subrata_modakfcfd1602007-10-17 14:33:24 +0000246
subrata_modak56207ce2009-03-23 13:35:39 +0000247 sprintf(fname, "/dev/shm/cache_%d", getpid());
subrata_modakcf179582008-02-26 08:01:53 +0000248
subrata_modak56207ce2009-03-23 13:35:39 +0000249 if ((fd1 = open(fname, O_RDWR | O_CREAT | O_TRUNC, S_IRWXU)) < 0) {
subrata_modakfcfd1602007-10-17 14:33:24 +0000250 tst_brkm(TBROK, cleanup,
subrata_modak56207ce2009-03-23 13:35:39 +0000251 "open(%s, O_RDWR|O_CREAT|O_TRUNC,S_IRWXU) Failed, errno=%d : %s",
252 fname, errno, strerror(errno));
subrata_modakfcfd1602007-10-17 14:33:24 +0000253 }
254
subrata_modak56207ce2009-03-23 13:35:39 +0000255 if ((fd2 = open("cache", O_RDWR | O_CREAT | O_TRUNC, S_IRWXU)) < 0) {
subrata_modakfcfd1602007-10-17 14:33:24 +0000256 tst_brkm(TBROK, cleanup,
subrata_modak56207ce2009-03-23 13:35:39 +0000257 "open(%s, O_RDWR|O_CREAT|O_TRUNC,S_IRWXU) Failed, errno=%d : %s",
258 "cache", errno, strerror(errno));
subrata_modakfcfd1602007-10-17 14:33:24 +0000259 }
260
Garrett Cooper2c282152010-12-16 00:55:50 -0800261}
subrata_modakfcfd1602007-10-17 14:33:24 +0000262
263/*
264* cleanup() - Performs one time cleanup for this test at
265* completion or premature exit
266*/
subrata_modak56207ce2009-03-23 13:35:39 +0000267void cleanup(char *data)
subrata_modakfcfd1602007-10-17 14:33:24 +0000268{
269 /* Close the file descriptors */
270 close(fd1);
271 close(fd2);
272
subrata_modak8b2171f2008-02-26 07:52:26 +0000273 if (data)
subrata_modak56207ce2009-03-23 13:35:39 +0000274 munmap(data, window_sz);
subrata_modak8b2171f2008-02-26 07:52:26 +0000275
subrata_modakcf179582008-02-26 08:01:53 +0000276 /* Remove the /dev/shm/cache_<pid> file */
subrata_modak56207ce2009-03-23 13:35:39 +0000277 unlink(fname);
subrata_modakcf179582008-02-26 08:01:53 +0000278
subrata_modakfcfd1602007-10-17 14:33:24 +0000279 tst_rmdir();
280
Chris Dearmanec6edca2012-10-17 19:54:01 -0700281}