support for huge pages

This commit is contained in:
Andreas Abel
2019-03-28 21:33:27 +01:00
parent c91ffef8f8
commit de6f3606c3
4 changed files with 63 additions and 3 deletions

View File

@@ -45,6 +45,7 @@ void* runtime_rbp;
void* runtime_rdi;
void* runtime_rsi;
void* runtime_rsp;
void* huge_pages = NULL;
int64_t pfc_mem[MAX_PROGRAMMABLE_COUNTERS];
void* RSP_mem;
@@ -383,7 +384,11 @@ void create_runtime_code(char* measurement_template, long local_unroll_count, lo
templateI += 8;
rci += 8;
} else if (starts_with_magic_bytes(&measurement_template[templateI], MAGIC_BYTES_RUNTIME_R14)) {
*(void**)(&runtime_code[rci]) = runtime_r14 + RUNTIME_R_SIZE/2;
if (huge_pages) {
*(void**)(&runtime_code[rci]) = huge_pages;
} else {
*(void**)(&runtime_code[rci]) = runtime_r14 + RUNTIME_R_SIZE/2;
}
templateI += 8;
rci += 8;
} else if (starts_with_magic_bytes(&measurement_template[templateI], MAGIC_BYTES_RUNTIME_RBP)) {

View File

@@ -158,6 +158,9 @@ extern void* runtime_rdi;
extern void* runtime_rsi;
extern void* runtime_rsp;
// If non-null, R14 will contain this address instead of runtime_r14.
extern void* huge_pages;
// Stores performance counter values during measurements.
extern int64_t pfc_mem[MAX_PROGRAMMABLE_COUNTERS];

View File

@@ -20,10 +20,12 @@ CFLAGS_nanoBench.o := -DDEBUG
ccflags-y+=-std=gnu99 -Wno-declaration-after-statement
all:
all: hp
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
hp: hp.o
clean:
rm -f ../common/*.o ../common/*.ur-safe
rm -f hp ../common/*.o ../common/*.ur-safe
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

View File

@@ -11,6 +11,8 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <../arch/x86/include/asm/fpu/api.h>
#include "../common/nanoBench.h"
@@ -18,6 +20,9 @@
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Andreas Abel");
struct page** pages = NULL;
unsigned long npages = 0;
static ssize_t init_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) {
memcpy(buf, code_init, code_init_length);
return code_init_length;
@@ -158,6 +163,42 @@ static ssize_t agg_store(struct kobject *kobj, struct kobj_attribute *attr, cons
}
static struct kobj_attribute agg_attribute =__ATTR(agg, 0660, agg_show, agg_store);
static ssize_t use_huge_pages_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) {
return 0;
}
static ssize_t use_huge_pages_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) {
if (huge_pages) {
vm_unmap_ram(huge_pages, npages);
}
for (int i=0; i<npages; i++) {
put_page(pages[i]);
}
vfree(pages);
long len = *(long*)(buf+sizeof(void*));
npages = (len+PAGE_SIZE-1)/PAGE_SIZE;
if (npages == 0) {
pr_debug("Huge pages disabled.");
pages = NULL;
huge_pages = NULL;
return count;
}
pages = vmalloc(npages * sizeof(struct page*));
down_read(&current->mm->mmap_sem);
int res = get_user_pages(*(unsigned long*)(buf), npages, FOLL_WRITE, pages, NULL);
if (res) {
int nid = page_to_nid(pages[0]);
huge_pages = vm_map_ram(pages, npages, nid, PAGE_KERNEL);
}
up_read(&current->mm->mmap_sem);
pr_debug("Huge pages enabled. Start address: %px", huge_pages);
return count;
}
static struct kobj_attribute use_huge_pages_attribute =__ATTR(use_huge_pages, 0660, use_huge_pages_show, use_huge_pages_store);
static ssize_t verbose_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) {
return sprintf(buf, "%u\n", verbose);
}
@@ -381,6 +422,7 @@ static int __init nb_init (void) {
error |= sysfs_create_file(nb_kobject, &agg_attribute.attr);
error |= sysfs_create_file(nb_kobject, &basic_mode_attribute.attr);
error |= sysfs_create_file(nb_kobject, &no_mem_attribute.attr);
error |= sysfs_create_file(nb_kobject, &use_huge_pages_attribute.attr);
error |= sysfs_create_file(nb_kobject, &verbose_attribute.attr);
if (error) {
@@ -402,6 +444,14 @@ static void __exit nb_exit (void) {
vfree(runtime_rsi);
vfree(runtime_rsp);
if (huge_pages) {
vm_unmap_ram(huge_pages, npages);
}
for (int i=0; i<npages; i++) {
put_page(pages[i]);
}
vfree(pages);
for (int i=0; i<MAX_PROGRAMMABLE_COUNTERS; i++) {
kfree(measurement_results[i]);
kfree(measurement_results_base[i]);