1/******************************************************************************/ 2/* */ 3/* Copyright (c) International Business Machines Corp., 2007 */ 4/* Copyright (c) Linux Test Project, 2016 */ 5/* */ 6/* This program is free software: you can redistribute it and/or modify */ 7/* it under the terms of the GNU General Public License as published by */ 8/* the Free Software Foundation, either version 3 of the License, or */ 9/* (at your option) any later version. */ 10/* */ 11/* This program is distributed in the hope that it will be useful, */ 12/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ 13/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ 14/* GNU General Public License for more details. */ 15/* */ 16/* You should have received a copy of the GNU General Public License */ 17/* along with this program. If not, see <http://www.gnu.org/licenses/>. */ 18/* */ 19/******************************************************************************/ 20 21/******************************************************************************/ 22/* */ 23/* File: support_numa.c */ 24/* */ 25/* Description: Allocates memory and touches it to verify numa */ 26/* */ 27/* Author: Sivakumar Chinnaiah Sivakumar.C@in.ibm.com */ 28/* */ 29/******************************************************************************/ 30 31#include <stdio.h> 32#include <stdlib.h> 33#include <errno.h> 34#include <unistd.h> 35#include <signal.h> 36#include <limits.h> 37#include <string.h> 38#include <sys/types.h> 39#include <sys/stat.h> 40#include <sys/mman.h> 41#include <fcntl.h> 42#include "lapi/mmap.h" 43 44/* Global Variables */ 45#define MB (1<<20) 46#define PAGE_SIZE getpagesize() 47#define barrier() __asm__ __volatile__("": : :"memory") 48#define TEST_SFILE "ltp_numa_testfile" 49#define STR "abcdefghijklmnopqrstuvwxyz12345\n" 50 51static void help(void) 52{ 53 printf("Input: Describe input arguments to this program\n"); 54 printf(" argv[1] == \"alloc_1MB\" then allocate 1MB of memory\n"); 55 printf(" argv[1] == \"alloc_1MB_shared\" then allocate 1MB of share memory\n"); 56 printf(" argv[1] == \"alloc_2HPSZ_THP\" then allocate 2HUGE PAGE SIZE of THP memory\n"); 57 printf(" argv[1] == \"alloc_1huge_page\" then allocate 1HUGE PAGE SIZE of memory\n"); 58 printf(" argv[1] == \"pause\" then pause the program to catch sigint\n"); 59 printf("Exit: On failure - Exits with non-zero value\n"); 60 printf(" On success - exits with 0 exit value\n"); 61 62 exit(1); 63} 64 65static int read_hugepagesize(void) 66{ 67 FILE *fp; 68 char line[BUFSIZ], buf[BUFSIZ]; 69 int val; 70 71 fp = fopen("/proc/meminfo", "r"); 72 if (fp == NULL) { 73 fprintf(stderr, "Failed to open /proc/meminfo"); 74 return 0; 75 } 76 77 while (fgets(line, BUFSIZ, fp) != NULL) { 78 if (sscanf(line, "%64s %d", buf, &val) == 2) 79 if (strcmp(buf, "Hugepagesize:") == 0) { 80 fclose(fp); 81 return 1024 * val; 82 } 83 } 84 85 fclose(fp); 86 fprintf(stderr, "can't find \"%s\" in %s", "Hugepagesize:", "/proc/meminfo"); 87 88 return 0; 89} 90 91int main(int argc, char *argv[]) 92{ 93 int i, fd, rc, hpsz; 94 char *buf = NULL; 95 struct stat sb; 96 97 if (argc != 2) { 98 fprintf(stderr, "Here expect only one number(i.e. 2) as the parameter\n"); 99 exit(1); 100 } 101 102 if (!strcmp(argv[1], "alloc_1MB")) { 103 buf = malloc(MB); 104 if (!buf) { 105 fprintf(stderr, "Memory is not available\n"); 106 exit(1); 107 } 108 for (i = 0; i < MB; i += PAGE_SIZE) { 109 buf[i] = 'a'; 110 barrier(); 111 } 112 113 raise(SIGSTOP); 114 115 free(buf); 116 } else if (!strcmp(argv[1], "alloc_1MB_shared")) { 117 fd = open(TEST_SFILE, O_RDWR | O_CREAT, 0666); 118 /* Writing 1MB of random data into this file [32 * 32768 = 1024 * 1024] */ 119 for (i = 0; i < 32768; i++){ 120 rc = write(fd, STR, strlen(STR)); 121 if (rc == -1 || ((size_t)rc != strlen(STR))) 122 fprintf(stderr, "write failed\n"); 123 } 124 125 if ((fstat(fd, &sb)) == -1) 126 fprintf(stderr, "fstat failed\n"); 127 128 buf = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 129 if (buf == MAP_FAILED){ 130 fprintf(stderr, "mmap failed\n"); 131 close(fd); 132 exit(1); 133 } 134 135 memset(buf, 'a', sb.st_size); 136 137 raise(SIGSTOP); 138 139 munmap(buf, sb.st_size); 140 close(fd); 141 remove(TEST_SFILE); 142 } else if (!strcmp(argv[1], "alloc_2HPSZ_THP")) { 143 ssize_t size = 2 * read_hugepagesize(); 144 if (size == 0) 145 exit(1); 146 147 buf = mmap(NULL, size, PROT_READ | PROT_WRITE, 148 MAP_PRIVATE | MAP_ANONYMOUS, 149 -1, 0); 150 if (buf == MAP_FAILED) { 151 perror("mmap failed"); 152 exit(1); 153 } 154 155 memset(buf, 'a', size); 156 157 raise(SIGSTOP); 158 159 munmap(buf, size); 160 } else if (!strcmp(argv[1], "alloc_1huge_page")) { 161 hpsz = read_hugepagesize(); 162 if (hpsz == 0) 163 exit(1); 164 165 buf = mmap(NULL, hpsz, PROT_READ | PROT_WRITE, 166 MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB, 167 -1, 0); 168 169 if (buf == MAP_FAILED) { 170 perror("mmap failed"); 171 exit(1); 172 } 173 174 memset(buf, 'a', hpsz); 175 176 raise(SIGSTOP); 177 178 munmap(buf, hpsz); 179 } else if (!strcmp(argv[1], "pause")) { 180 raise(SIGSTOP); 181 } else { 182 help(); 183 } 184 185 return 0; 186} 187