Create test case for MAP_POPULATE of mmap. Verify the following statement "For a file mapping,this causes read-ahead on the file. Later accesses to the mapping will not be blocked by page faults." by mmap-ing a file and check if all pages are present.
Signed-off-by: DAN LI <[email protected]> --- runtest/syscalls | 1 + testcases/kernel/syscalls/mmap/mmap12.c | 194 ++++++++++++++++++++++++++++++++ 2 files changed, 195 insertions(+) create mode 100644 testcases/kernel/syscalls/mmap/mmap12.c diff --git a/runtest/syscalls b/runtest/syscalls index eba0200..3ab19f5 100644 --- a/runtest/syscalls +++ b/runtest/syscalls @@ -561,6 +561,7 @@ mmap06 mmap06 mmap07 mmap07 mmap08 mmap08 mmap09 mmap09 +mmap12 mmap12 mmap13 mmap13 # test is broken, mask it for now. #mmap11 mmap11 -i 30000 diff --git a/testcases/kernel/syscalls/mmap/mmap12.c b/testcases/kernel/syscalls/mmap/mmap12.c new file mode 100644 index 0000000..8494d9a --- /dev/null +++ b/testcases/kernel/syscalls/mmap/mmap12.c @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2013 FNST, DAN LI <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * Test Description: + * Verify MAP_POPULATE works fine. + * "For a file mapping, this causes read-ahead on the file. + * Later accesses to the mapping will not be blocked by page faults" + * + * Expected Result: + * mmap() with MAP_POPULATE should succeed returning the address of the + * mapped region and this file has been read into RAM, so pages should + * be present. + */ +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <errno.h> +#include <unistd.h> +#include <fcntl.h> +#include <string.h> +#include <signal.h> +#include <stdint.h> +#include <sys/stat.h> +#include <sys/mman.h> +#include <sys/shm.h> + +#include "test.h" +#include "usctest.h" + +#define TEMPFILE "mmapfile" +#define LINELEN 256 +#define PATHLEN 256 +#define MMAPSIZE (1UL<<20) + +char *TCID = "mmap12"; +int TST_TOTAL = 1; + +static int fildes; +static char *addr; + +static int page_check(void); +static void setup(void); +static void cleanup(void); + +int main(int argc, char *argv[]) +{ + int lc; + char *msg; + + msg = parse_opts(argc, argv, NULL, NULL); + if (msg != NULL) + tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); + + setup(); + for (lc = 0; TEST_LOOPING(lc); lc++) { + tst_count = 0; + + addr = mmap(NULL, MMAPSIZE, PROT_READ | PROT_WRITE, + MAP_FILE | MAP_PRIVATE | MAP_POPULATE, fildes, 0); + + if (addr == MAP_FAILED) { + tst_resm(TFAIL | TERRNO, "mmap of %s failed", TEMPFILE); + continue; + } + + if (STD_FUNCTIONAL_TEST) { + + if (page_check()) + tst_resm(TFAIL, "Not all pages are present"); + else + tst_resm(TPASS, "Functionality of mmap() " + "successful"); + } + + if (munmap(addr, MMAPSIZE) != 0) + tst_brkm(TFAIL | TERRNO, NULL, "munmap failed"); + } + + cleanup(); + tst_exit(); + +} + +static int page_check(void) +{ + int pid; + int ret; + int pm; + int num_pages; + long index; + off_t offset; + size_t page_sz; + char maps_dev[PATHLEN]; + char pagemap_dev[PATHLEN]; + char line[LINELEN]; + FILE *maps; + unsigned long vm_start; + unsigned long vm_end; + unsigned long long pagemap; + + page_sz = getpagesize(); + + pid = getpid(); + sprintf(maps_dev, "/proc/%d/maps", pid); + sprintf(pagemap_dev, "/proc/%d/pagemap", pid); + + maps = fopen(maps_dev, "r"); + if (maps == NULL) + tst_brkm(TFAIL | TERRNO, NULL, "Open dev maps failed"); + + while (fgets(line, LINELEN, maps) != NULL) + if (strstr(line, TEMPFILE) != NULL) + break; + + ret = sscanf(line, "%lX-%lX", &vm_start, &vm_end); + if (ret != 2) + tst_brkm(TFAIL | TERRNO, NULL, "Get address space failed"); + + num_pages = (vm_end - vm_start) / page_sz; + index = (vm_start / page_sz) * sizeof(unsigned long long); + + pm = open(pagemap_dev, O_RDONLY); + if (pm == -1) + tst_brkm(TFAIL | TERRNO, NULL, "Open dev pagemap failed"); + + offset = lseek(pm, index, SEEK_SET); + if (offset != index) + tst_brkm(TFAIL | TERRNO, NULL, "Reposition offset failed"); + + while (num_pages > 0) { + ret = read(pm, &pagemap, sizeof(unsigned long long)); + if (ret < 0) + tst_brkm(TFAIL | TERRNO, NULL, "Read pagemap failed"); + /* + * Check if the page is present. + */ + if (!(pagemap & (1ULL<<63))) { + close(pm); + fclose(maps); + return 1; + } + num_pages--; + } + + close(pm); + fclose(maps); + + return 0; +} + +static void setup(void) +{ + tst_sig(FORK, DEF_HANDLER, cleanup); + + if ((tst_kvercmp(2, 6, 25)) < 0) + tst_brkm(TCONF, NULL, + "This test can only run on kernels that are 2.6.23 and " + "higher"); + + TEST_PAUSE; + + tst_tmpdir(); + + fildes = open(TEMPFILE, O_RDWR | O_CREAT, 0766); + if (fildes < 0) + tst_brkm(TFAIL, cleanup, "opening %s failed", TEMPFILE); + + if (ftruncate(fildes, MMAPSIZE) < 0) + tst_brkm(TFAIL | TERRNO, cleanup, "ftruncate file failed"); + +} + +static void cleanup(void) +{ + close(fildes); + TEST_CLEANUP; + tst_rmdir(); +} -- 1.8.1 ------------------------------------------------------------------------------ This SF.net email is sponsored by Windows: Build for Windows Store. http://p.sf.net/sfu/windows-dev2dev _______________________________________________ Ltp-list mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/ltp-list
