Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * This program reserves and uses hugetlb memory, supporting a bunch of
0004  * scenarios needed by the charged_reserved_hugetlb.sh test.
0005  */
0006 
0007 #include <err.h>
0008 #include <errno.h>
0009 #include <signal.h>
0010 #include <stdio.h>
0011 #include <stdlib.h>
0012 #include <string.h>
0013 #include <unistd.h>
0014 #include <fcntl.h>
0015 #include <sys/types.h>
0016 #include <sys/shm.h>
0017 #include <sys/stat.h>
0018 #include <sys/mman.h>
0019 
0020 /* Global definitions. */
0021 enum method {
0022     HUGETLBFS,
0023     MMAP_MAP_HUGETLB,
0024     SHM,
0025     MAX_METHOD
0026 };
0027 
0028 
0029 /* Global variables. */
0030 static const char *self;
0031 static char *shmaddr;
0032 static int shmid;
0033 
0034 /*
0035  * Show usage and exit.
0036  */
0037 static void exit_usage(void)
0038 {
0039     printf("Usage: %s -p <path to hugetlbfs file> -s <size to map> "
0040            "[-m <0=hugetlbfs | 1=mmap(MAP_HUGETLB)>] [-l] [-r] "
0041            "[-o] [-w] [-n]\n",
0042            self);
0043     exit(EXIT_FAILURE);
0044 }
0045 
0046 void sig_handler(int signo)
0047 {
0048     printf("Received %d.\n", signo);
0049     if (signo == SIGINT) {
0050         printf("Deleting the memory\n");
0051         if (shmdt((const void *)shmaddr) != 0) {
0052             perror("Detach failure");
0053             shmctl(shmid, IPC_RMID, NULL);
0054             exit(4);
0055         }
0056 
0057         shmctl(shmid, IPC_RMID, NULL);
0058         printf("Done deleting the memory\n");
0059     }
0060     exit(2);
0061 }
0062 
0063 int main(int argc, char **argv)
0064 {
0065     int fd = 0;
0066     int key = 0;
0067     int *ptr = NULL;
0068     int c = 0;
0069     int size = 0;
0070     char path[256] = "";
0071     enum method method = MAX_METHOD;
0072     int want_sleep = 0, private = 0;
0073     int populate = 0;
0074     int write = 0;
0075     int reserve = 1;
0076 
0077     if (signal(SIGINT, sig_handler) == SIG_ERR)
0078         err(1, "\ncan't catch SIGINT\n");
0079 
0080     /* Parse command-line arguments. */
0081     setvbuf(stdout, NULL, _IONBF, 0);
0082     self = argv[0];
0083 
0084     while ((c = getopt(argc, argv, "s:p:m:owlrn")) != -1) {
0085         switch (c) {
0086         case 's':
0087             size = atoi(optarg);
0088             break;
0089         case 'p':
0090             strncpy(path, optarg, sizeof(path));
0091             break;
0092         case 'm':
0093             if (atoi(optarg) >= MAX_METHOD) {
0094                 errno = EINVAL;
0095                 perror("Invalid -m.");
0096                 exit_usage();
0097             }
0098             method = atoi(optarg);
0099             break;
0100         case 'o':
0101             populate = 1;
0102             break;
0103         case 'w':
0104             write = 1;
0105             break;
0106         case 'l':
0107             want_sleep = 1;
0108             break;
0109         case 'r':
0110             private
0111             = 1;
0112             break;
0113         case 'n':
0114             reserve = 0;
0115             break;
0116         default:
0117             errno = EINVAL;
0118             perror("Invalid arg");
0119             exit_usage();
0120         }
0121     }
0122 
0123     if (strncmp(path, "", sizeof(path)) != 0) {
0124         printf("Writing to this path: %s\n", path);
0125     } else {
0126         errno = EINVAL;
0127         perror("path not found");
0128         exit_usage();
0129     }
0130 
0131     if (size != 0) {
0132         printf("Writing this size: %d\n", size);
0133     } else {
0134         errno = EINVAL;
0135         perror("size not found");
0136         exit_usage();
0137     }
0138 
0139     if (!populate)
0140         printf("Not populating.\n");
0141     else
0142         printf("Populating.\n");
0143 
0144     if (!write)
0145         printf("Not writing to memory.\n");
0146 
0147     if (method == MAX_METHOD) {
0148         errno = EINVAL;
0149         perror("-m Invalid");
0150         exit_usage();
0151     } else
0152         printf("Using method=%d\n", method);
0153 
0154     if (!private)
0155         printf("Shared mapping.\n");
0156     else
0157         printf("Private mapping.\n");
0158 
0159     if (!reserve)
0160         printf("NO_RESERVE mapping.\n");
0161     else
0162         printf("RESERVE mapping.\n");
0163 
0164     switch (method) {
0165     case HUGETLBFS:
0166         printf("Allocating using HUGETLBFS.\n");
0167         fd = open(path, O_CREAT | O_RDWR, 0777);
0168         if (fd == -1)
0169             err(1, "Failed to open file.");
0170 
0171         ptr = mmap(NULL, size, PROT_READ | PROT_WRITE,
0172                (private ? MAP_PRIVATE : MAP_SHARED) |
0173                    (populate ? MAP_POPULATE : 0) |
0174                    (reserve ? 0 : MAP_NORESERVE),
0175                fd, 0);
0176 
0177         if (ptr == MAP_FAILED) {
0178             close(fd);
0179             err(1, "Error mapping the file");
0180         }
0181         break;
0182     case MMAP_MAP_HUGETLB:
0183         printf("Allocating using MAP_HUGETLB.\n");
0184         ptr = mmap(NULL, size, PROT_READ | PROT_WRITE,
0185                (private ? (MAP_PRIVATE | MAP_ANONYMOUS) :
0186                       MAP_SHARED) |
0187                    MAP_HUGETLB | (populate ? MAP_POPULATE : 0) |
0188                    (reserve ? 0 : MAP_NORESERVE),
0189                -1, 0);
0190 
0191         if (ptr == MAP_FAILED)
0192             err(1, "mmap");
0193 
0194         printf("Returned address is %p\n", ptr);
0195         break;
0196     case SHM:
0197         printf("Allocating using SHM.\n");
0198         shmid = shmget(key, size,
0199                    SHM_HUGETLB | IPC_CREAT | SHM_R | SHM_W);
0200         if (shmid < 0) {
0201             shmid = shmget(++key, size,
0202                        SHM_HUGETLB | IPC_CREAT | SHM_R | SHM_W);
0203             if (shmid < 0)
0204                 err(1, "shmget");
0205         }
0206         printf("shmid: 0x%x, shmget key:%d\n", shmid, key);
0207 
0208         ptr = shmat(shmid, NULL, 0);
0209         if (ptr == (int *)-1) {
0210             perror("Shared memory attach failure");
0211             shmctl(shmid, IPC_RMID, NULL);
0212             exit(2);
0213         }
0214         printf("shmaddr: %p\n", ptr);
0215 
0216         break;
0217     default:
0218         errno = EINVAL;
0219         err(1, "Invalid method.");
0220     }
0221 
0222     if (write) {
0223         printf("Writing to memory.\n");
0224         memset(ptr, 1, size);
0225     }
0226 
0227     if (want_sleep) {
0228         /* Signal to caller that we're done. */
0229         printf("DONE\n");
0230 
0231         /* Hold memory until external kill signal is delivered. */
0232         while (1)
0233             sleep(100);
0234     }
0235 
0236     if (method == HUGETLBFS)
0237         close(fd);
0238 
0239     return 0;
0240 }