/* * libhugetlbfs - Easy use of Linux hugepages * Copyright (C) 2005-2006 David Gibson & Adam Litke, IBM Corporation. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MECHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _HUGETESTS_H #define _HUGETESTS_H #include #include #include #include "libhugetlbfs_privutils.h" #include "libhugetlbfs_testprobes.h" #define DEBUG /* Test return codes */ #define RC_PASS 0 #define RC_CONFIG 1 #define RC_FAIL 2 #define RC_XFAIL 3 /* Expected Failure */ #define RC_XPASS 4 /* Unexpected Pass */ #define RC_BUG 99 #define FOURGB (1UL << 32) extern int verbose_test; extern char *test_name; void check_free_huge_pages(int nr_pages_needed); void check_must_be_root(void); void check_hugetlb_shm_group(void); void check_online_cpus(int[], int); void test_init(int argc, char *argv[]); int test_addr_huge(void *p); unsigned long long get_mapping_page_size(void *p); long read_meminfo(const char *tag); ino_t get_addr_inode(void *p); int range_is_mapped(unsigned long low, unsigned long high); #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) #define PALIGN(p, a) ((void *)ALIGN((unsigned long)(p), (a))) #ifndef barrier # ifdef mb # define barrier() mb() # else # define barrier() __asm__ __volatile__ ("" : : : "memory") # endif #endif /* Each test case must define this function */ void cleanup(void); #define verbose_printf(...) \ if (verbose_test) { \ printf(__VA_ARGS__); \ fflush(stdout); \ } #define ERR "ERR: " #define ERROR(fmt, args...) fprintf(stderr, ERR fmt, ## args) #define PASS() \ do { \ cleanup(); \ printf("PASS\n"); \ exit(RC_PASS); \ } while (0) #define PASS_INCONCLUSIVE() \ do { \ cleanup(); \ printf("PASS (inconclusive)\n"); \ exit(RC_PASS); \ } while (0) #define IRRELEVANT() \ do { \ cleanup(); \ printf("PASS (irrelevant)\n"); \ exit(RC_PASS); \ } while (0) /* Look out, gcc extension below... */ #define FAIL(fmt, ...) \ do { \ cleanup(); \ printf("FAIL\t" fmt "\n", ##__VA_ARGS__); \ exit(RC_FAIL); \ } while (0) #define CONFIG(fmt, ...) \ do { \ cleanup(); \ printf("Bad configuration: " fmt "\n", ##__VA_ARGS__); \ exit(RC_CONFIG); \ } while (0) #define TEST_BUG(fmt, ...) \ do { \ cleanup(); \ printf("BUG in testsuite: " fmt "\n", ##__VA_ARGS__); \ exit(RC_BUG); \ } while (0) /* stressutils.c stuff */ int remove_shmid(int shmid); extern long gethugepagesize (void) __attribute__ ((weak)); static inline long check_hugepagesize() { long __hpage_size = gethugepagesize(); if (__hpage_size < 0) { if (errno == ENOSYS) CONFIG("No hugepage kernel support\n"); else if (errno == EOVERFLOW) CONFIG("Hugepage size too large"); else CONFIG("Hugepage size (%s)", strerror(errno)); } return __hpage_size; } static inline void check_if_gigantic_page(void) { long page_size, hpage_size, max_order; FILE *fp; page_size = sysconf(_SC_PAGESIZE); hpage_size = gethugepagesize(); fp = popen("cat /proc/pagetypeinfo | " "awk '/Free pages count per migrate type at order/ " "{print $NF}'", "r"); if (!fp || fscanf(fp, "%lu", &max_order) < 0) FAIL("Couldn't determine max page allocation order"); pclose(fp); if (hpage_size > ((1 << max_order) * page_size)) CONFIG("Gigantic pages are not supported"); } int using_system_hpage_size(const char *mount); /* WARNING: Racy -- use for test cases only! */ int kernel_has_private_reservations(void); #endif /* _HUGETESTS_H */