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
help(void)51 static 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
read_hugepagesize(void)65 static 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
main(int argc,char * argv[])91 int 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