1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 2f08c3bdfSopenharmony_ci/* 3f08c3bdfSopenharmony_ci * Copyright (c) International Business Machines Corp., 2004 4f08c3bdfSopenharmony_ci * Copyright (c) Linux Test Project, 2004-2017 5f08c3bdfSopenharmony_ci * 6f08c3bdfSopenharmony_ci * Test Name: hugemmap04 7f08c3bdfSopenharmony_ci * 8f08c3bdfSopenharmony_ci * Test Description: 9f08c3bdfSopenharmony_ci * Verify that, a hugetlb mmap() succeeds when used to map the largest 10f08c3bdfSopenharmony_ci * size possible. 11f08c3bdfSopenharmony_ci * 12f08c3bdfSopenharmony_ci * Expected Result: 13f08c3bdfSopenharmony_ci * mmap() should succeed returning the address of the hugetlb mapped region. 14f08c3bdfSopenharmony_ci * The number of free huge pages should decrease. 15f08c3bdfSopenharmony_ci * 16f08c3bdfSopenharmony_ci * Test: 17f08c3bdfSopenharmony_ci * Loop if the proper options are given. 18f08c3bdfSopenharmony_ci * Execute system call 19f08c3bdfSopenharmony_ci * Check return code, if system call failed (return=-1) 20f08c3bdfSopenharmony_ci * Log the errno and Issue a FAIL message. 21f08c3bdfSopenharmony_ci * 22f08c3bdfSopenharmony_ci * HISTORY 23f08c3bdfSopenharmony_ci * 04/2004 Written by Robbie Williamson 24f08c3bdfSopenharmony_ci */ 25f08c3bdfSopenharmony_ci 26f08c3bdfSopenharmony_ci#include <sys/mount.h> 27f08c3bdfSopenharmony_ci#include <stdio.h> 28f08c3bdfSopenharmony_ci#include <limits.h> 29f08c3bdfSopenharmony_ci#include <sys/param.h> 30f08c3bdfSopenharmony_ci#include "lapi/abisize.h" 31f08c3bdfSopenharmony_ci#include "hugetlb.h" 32f08c3bdfSopenharmony_ci 33f08c3bdfSopenharmony_cistatic char TEMPFILE[MAXPATHLEN]; 34f08c3bdfSopenharmony_ci 35f08c3bdfSopenharmony_cistatic long *addr; 36f08c3bdfSopenharmony_cistatic long long mapsize; 37f08c3bdfSopenharmony_cistatic int fildes; 38f08c3bdfSopenharmony_cistatic long freepages; 39f08c3bdfSopenharmony_cistatic long beforetest; 40f08c3bdfSopenharmony_cistatic long aftertest; 41f08c3bdfSopenharmony_cistatic long hugepagesmapped; 42f08c3bdfSopenharmony_ci 43f08c3bdfSopenharmony_cistatic void test_hugemmap(void) 44f08c3bdfSopenharmony_ci{ 45f08c3bdfSopenharmony_ci int huge_pagesize = 0; 46f08c3bdfSopenharmony_ci 47f08c3bdfSopenharmony_ci /* Creat a temporary file used for huge mapping */ 48f08c3bdfSopenharmony_ci fildes = SAFE_OPEN(TEMPFILE, O_RDWR | O_CREAT, 0666); 49f08c3bdfSopenharmony_ci 50f08c3bdfSopenharmony_ci freepages = SAFE_READ_MEMINFO("HugePages_Free:"); 51f08c3bdfSopenharmony_ci beforetest = freepages; 52f08c3bdfSopenharmony_ci 53f08c3bdfSopenharmony_ci huge_pagesize = SAFE_READ_MEMINFO("Hugepagesize:"); 54f08c3bdfSopenharmony_ci tst_res(TINFO, "Size of huge pages is %d KB", huge_pagesize); 55f08c3bdfSopenharmony_ci 56f08c3bdfSopenharmony_ci#ifdef TST_ABI32 57f08c3bdfSopenharmony_ci tst_res(TINFO, "Total amount of free huge pages is %ld", 58f08c3bdfSopenharmony_ci freepages); 59f08c3bdfSopenharmony_ci tst_res(TINFO, "Max number allowed for 1 mmap file in" 60f08c3bdfSopenharmony_ci " 32-bits is 128"); 61f08c3bdfSopenharmony_ci if (freepages > 128) 62f08c3bdfSopenharmony_ci freepages = 128; 63f08c3bdfSopenharmony_ci#endif 64f08c3bdfSopenharmony_ci mapsize = (long long)freepages * huge_pagesize * 1024; 65f08c3bdfSopenharmony_ci addr = mmap(NULL, mapsize, PROT_READ | PROT_WRITE, 66f08c3bdfSopenharmony_ci MAP_SHARED, fildes, 0); 67f08c3bdfSopenharmony_ci if (addr == MAP_FAILED) { 68f08c3bdfSopenharmony_ci tst_res(TFAIL | TERRNO, "mmap() Failed on %s", 69f08c3bdfSopenharmony_ci TEMPFILE); 70f08c3bdfSopenharmony_ci } else { 71f08c3bdfSopenharmony_ci tst_res(TPASS, 72f08c3bdfSopenharmony_ci "Succeeded mapping file using %ld pages", 73f08c3bdfSopenharmony_ci freepages); 74f08c3bdfSopenharmony_ci 75f08c3bdfSopenharmony_ci /* force to allocate page and change HugePages_Free */ 76f08c3bdfSopenharmony_ci *(int *)addr = 0; 77f08c3bdfSopenharmony_ci /* Make sure the number of free huge pages AFTER testing decreased */ 78f08c3bdfSopenharmony_ci aftertest = SAFE_READ_MEMINFO("HugePages_Free:"); 79f08c3bdfSopenharmony_ci hugepagesmapped = beforetest - aftertest; 80f08c3bdfSopenharmony_ci if (hugepagesmapped < 1) 81f08c3bdfSopenharmony_ci tst_res(TWARN, "Number of HUGEPAGES_FREE stayed the" 82f08c3bdfSopenharmony_ci " same. Okay if multiple copies running due" 83f08c3bdfSopenharmony_ci " to test collision."); 84f08c3bdfSopenharmony_ci } 85f08c3bdfSopenharmony_ci 86f08c3bdfSopenharmony_ci munmap(addr, mapsize); 87f08c3bdfSopenharmony_ci close(fildes); 88f08c3bdfSopenharmony_ci} 89f08c3bdfSopenharmony_ci 90f08c3bdfSopenharmony_civoid setup(void) 91f08c3bdfSopenharmony_ci{ 92f08c3bdfSopenharmony_ci if (tst_hugepages == 0) 93f08c3bdfSopenharmony_ci tst_brk(TCONF, "Not enough hugepages for testing!"); 94f08c3bdfSopenharmony_ci 95f08c3bdfSopenharmony_ci if (!Hopt) 96f08c3bdfSopenharmony_ci Hopt = tst_get_tmpdir(); 97f08c3bdfSopenharmony_ci SAFE_MOUNT("none", Hopt, "hugetlbfs", 0, NULL); 98f08c3bdfSopenharmony_ci 99f08c3bdfSopenharmony_ci snprintf(TEMPFILE, sizeof(TEMPFILE), "%s/mmapfile%d", Hopt, getpid()); 100f08c3bdfSopenharmony_ci} 101f08c3bdfSopenharmony_ci 102f08c3bdfSopenharmony_civoid cleanup(void) 103f08c3bdfSopenharmony_ci{ 104f08c3bdfSopenharmony_ci unlink(TEMPFILE); 105f08c3bdfSopenharmony_ci umount(Hopt); 106f08c3bdfSopenharmony_ci} 107f08c3bdfSopenharmony_ci 108f08c3bdfSopenharmony_cistatic struct tst_test test = { 109f08c3bdfSopenharmony_ci .needs_root = 1, 110f08c3bdfSopenharmony_ci .needs_tmpdir = 1, 111f08c3bdfSopenharmony_ci .options = (struct tst_option[]) { 112f08c3bdfSopenharmony_ci {"H:", &Hopt, "Location of hugetlbfs, i.e. -H /var/hugetlbfs"}, 113f08c3bdfSopenharmony_ci {"s:", &nr_opt, "Set the number of the been allocated hugepages"}, 114f08c3bdfSopenharmony_ci {} 115f08c3bdfSopenharmony_ci }, 116f08c3bdfSopenharmony_ci .setup = setup, 117f08c3bdfSopenharmony_ci .cleanup = cleanup, 118f08c3bdfSopenharmony_ci .test_all = test_hugemmap, 119f08c3bdfSopenharmony_ci .hugepages = {128, TST_REQUEST}, 120f08c3bdfSopenharmony_ci}; 121