Created
August 22, 2019 17:26
-
-
Save sandip4n/eedeb9ad210c7d8d89f3ab1e960d20cf to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define _LARGEFILE64_SOURCE | |
#define _GNU_SOURCE | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <inttypes.h> | |
#include <errno.h> | |
#include <sys/mman.h> | |
#include <unistd.h> | |
#define HPAGE_SIZE (16 * 1024 * 1024ULL) | |
#define MAP_LENGTH (2 * HPAGE_SIZE) | |
#define HPAGE_BASE_FMT "/sys/kernel/mm/hugepages/hugepages-%lukB/" | |
#define HPAGE_FREE_FMT HPAGE_BASE_FMT "free_hugepages" | |
#define HPAGE_RESV_FMT HPAGE_BASE_FMT "resv_hugepages" | |
unsigned long read_ulong_from_file(char *filename) | |
{ | |
unsigned long val; | |
FILE *fp; | |
fp = fopen(filename, "r"); | |
if (!fp) { | |
fprintf(stderr, "fopen(): %s\n", strerror(errno)); | |
exit(EXIT_FAILURE); | |
} | |
fscanf(fp, "%lu", &val); | |
fclose(fp); | |
return val; | |
} | |
void print_hpage_stats(unsigned long pgsize) | |
{ | |
unsigned long free, resv, pgsizekb; | |
char filename[128]; | |
fflush(stdout); | |
pgsizekb = pgsize / 1024; | |
/* Read count of free huge pages */ | |
sprintf(filename, HPAGE_FREE_FMT, pgsizekb); | |
free = read_ulong_from_file(filename); | |
/* Read count of reserved huge pages */ | |
sprintf(filename, HPAGE_RESV_FMT, pgsizekb); | |
resv = read_ulong_from_file(filename); | |
printf("stats: free = %lu, resv = %lu\n", free, resv); | |
} | |
int get_hugetlbfs_subpool_fd(void) | |
{ | |
const char *path = "/var/lib/hugetlbfs/global/pagesize-16MB"; | |
// const char *path = "/home/sandipan/hugemount"; | |
char name[64]; | |
int fd; | |
/* Build temporary file name template */ | |
strcpy(name, path); | |
strncat(name, "/libhugetlbfs.tmp.XXXXXX", sizeof(name) - 1); | |
/* Create temporary file */ | |
fd = mkstemp64(name); | |
if (fd < 0) { | |
fprintf(stderr, "mkstemp(): %s\n", strerror(errno)); | |
exit(EXIT_FAILURE); | |
} | |
/* Unlink file */ | |
unlink(name); | |
return fd; | |
} | |
void print_proc_maps(void) | |
{ | |
const char *fmt = "cat /proc/%u/maps"; | |
char cmd[128]; | |
sprintf(cmd, fmt, (unsigned int) getpid()); | |
system(cmd); | |
} | |
int main(int argc, char **argv) | |
{ | |
void *ptr; | |
int fd; | |
fd = get_hugetlbfs_subpool_fd(); | |
printf("pre-mmap: "); | |
print_hpage_stats(HPAGE_SIZE); | |
/* Allocate a huge page */ | |
ptr = mmap(NULL, MAP_LENGTH, PROT_READ | PROT_WRITE, | |
MAP_PRIVATE, fd, 0); | |
if (ptr == MAP_FAILED) { | |
fprintf(stderr, "mmap(): %s\n", strerror(errno)); | |
return EXIT_FAILURE; | |
} | |
printf("post-mmap, pre-fault: "); | |
print_hpage_stats(HPAGE_SIZE); | |
getchar(); | |
/* Attempt to generate a page fault */ | |
printf("mmap-ed base = 0x%016lx\n", (unsigned long) ptr); | |
((char *) ptr)[0] = 0xff; | |
((char *) ptr)[HPAGE_SIZE] = 0xff; | |
printf("post-fault: "); | |
print_hpage_stats(HPAGE_SIZE); | |
print_proc_maps(); | |
getchar(); | |
/* Free up the huge page */ | |
if (munmap(ptr, MAP_LENGTH) < 0) { | |
fprintf(stderr, "munmap(): %s\n", strerror(errno)); | |
return EXIT_FAILURE; | |
} | |
close(fd); | |
return EXIT_SUCCESS; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment