aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNaoya Horiguchi <n-horiguchi@ah.jp.nec.com>2010-10-08 14:35:29 +0900
committerAndi Kleen <ak@linux.intel.com>2010-10-29 00:56:32 +0200
commitb97d8bd5faf48f70bd26e55f83350270945bb8c2 (patch)
tree068f8922c22a2cf35e1730d5c6f0227574dfa531
parent45d5bad24653f676155a3999070a03c9151863f4 (diff)
downloadmce-test-b97d8bd5faf48f70bd26e55f83350270945bb8c2.tar.gz
add header file giving utility functions for hugepage
Add routines allocating/freeing hugepages of the following types: - hugepage on shared memory, - anonymous hugepage, - filebacked hugepage. And also add read/write helper functions. Signed-off-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com> Signed-off-by: Andi Kleen <ak@linux.intel.com>
-rw-r--r--tsrc/hugepage.h162
1 files changed, 162 insertions, 0 deletions
diff --git a/tsrc/hugepage.h b/tsrc/hugepage.h
new file mode 100644
index 0000000..c2ff779
--- /dev/null
+++ b/tsrc/hugepage.h
@@ -0,0 +1,162 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+
+int HPS;
+#define err(x) perror(x), exit(1)
+#define errmsg(x) fprintf(stderr, x), exit(1)
+
+void write_hugepage(char *addr, int size, char *avoid)
+{
+ int i, j;
+ for (i = 0; i < size; i++) {
+ if (addr == avoid)
+ continue;
+ for (j = 0; j < HPS; j++) {
+ *(addr + i * HPS + j) = (char)('a' + ((i + j) % 26));
+ }
+ }
+}
+
+/* return -1 if buffer content differs from the expected ones */
+int read_hugepage(char *addr, int size, char *avoid)
+{
+ int i, j;
+ int ret = 0;
+
+ for (i = 0; i < size; i++) {
+ if (addr == avoid)
+ continue;
+ for (j = 0; j < HPS; j++) {
+ if (*(addr + i * HPS + j) != (char)('a' + ((i + j) % 26))) {
+ printf("Mismatch at %d\n", i + j);
+ ret = -1;
+ break;
+ }
+ }
+ }
+ return ret;
+}
+
+int hugetlbfs_root(char *dir)
+{
+ int found = 0;
+ FILE *f = fopen("/proc/mounts", "r");
+ if (!f) err("open /proc/mounts");
+ char *line = NULL;
+ size_t linelen = 0;
+ char dummy[100];
+ while (getline(&line, &linelen, f) > 0) {
+ if (sscanf(line, "none %s hugetlbfs %[^ ]",
+ dir, dummy) >= 2) {
+ found = 1;
+ break;
+ }
+ }
+ free(line);
+ fclose(f);
+ if (!found)
+ printf("cannot find hugetlbfs directory in /proc/mounts\n");
+ return found;
+}
+
+void *alloc_shm_hugepage(int *key, int size)
+{
+ void *addr;
+ int shmid;
+ if ((shmid = shmget(*key, size,
+ SHM_HUGETLB | IPC_CREAT | SHM_R | SHM_W)) < 0) {
+ perror("shmget");
+ return NULL;
+ }
+ addr = shmat(shmid, (void *)0x0UL, 0);
+ if (addr == (char *)-1) {
+ perror("Shared memory attach failure");
+ shmctl(shmid, IPC_RMID, NULL);
+ return NULL;
+ }
+ *key = shmid;
+ return addr;
+}
+
+void *alloc_anonymous_hugepage(int size, int private)
+{
+ void *addr;
+ int mapflag = MAP_ANONYMOUS | 0x40000; /* MAP_HUGETLB */
+ if (private)
+ mapflag |= MAP_PRIVATE;
+ else
+ mapflag |= MAP_SHARED;
+ if ((addr = mmap(0, size,
+ PROT_READ|PROT_WRITE, mapflag, -1, 0)) == MAP_FAILED) {
+ perror("mmap");
+ return NULL;
+ }
+ return addr;
+}
+
+void *alloc_filebacked_hugepage(char *filepath, int size, int private, int *fd)
+{
+ int mapflag = MAP_SHARED;
+ void *addr;
+ if (private)
+ mapflag = MAP_PRIVATE;
+ if ((*fd = open(filepath, O_CREAT | O_RDWR, 0777)) < 0) {
+ perror("open");
+ return NULL;
+ }
+ if ((addr = mmap(0, size,
+ PROT_READ|PROT_WRITE, mapflag, *fd, 0)) == MAP_FAILED) {
+ perror("mmap");
+ unlink(filepath);
+ return NULL;
+ }
+ return addr;
+}
+
+int free_shm_hugepage(int key, void *addr)
+{
+ if (shmdt((const void *)addr) != 0) {
+ perror("Detach failure");
+ shmctl(key, IPC_RMID, NULL);
+ return -1;
+ }
+ shmctl(key, IPC_RMID, NULL);
+ return 0;
+}
+
+int free_anonymous_hugepage(void *addr, int size)
+{
+ int ret = 0;
+ if (munmap(addr, size)) {
+ perror("munmap");
+ ret = -1;
+ }
+ return ret;
+}
+
+int free_filebacked_hugepage(void *addr, int size, int fd, char *filepath)
+{
+ int ret = 0;
+ if (munmap(addr, size)) {
+ perror("munmap");
+ ret = -1;
+ }
+ if (close(fd)) {
+ perror("close");
+ ret = -1;
+ }
+ if (filepath) {
+ if (unlink(filepath)) {
+ perror("unlink");
+ ret = -1;
+ }
+ } else {
+ fprintf(stderr, "Filepath not specified.\n");
+ ret = -1;
+ }
+ return ret;
+}