Skip to content

Instantly share code, notes, and snippets.

@sandip4n
Created August 22, 2019 17:26
Show Gist options
  • Save sandip4n/eedeb9ad210c7d8d89f3ab1e960d20cf to your computer and use it in GitHub Desktop.
Save sandip4n/eedeb9ad210c7d8d89f3ab1e960d20cf to your computer and use it in GitHub Desktop.
#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