diff --git a/common/nanoBench.c b/common/nanoBench.c index ff5aa47..5bb2813 100644 --- a/common/nanoBench.c +++ b/common/nanoBench.c @@ -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)) { diff --git a/common/nanoBench.h b/common/nanoBench.h index 870af2d..5965349 100644 --- a/common/nanoBench.h +++ b/common/nanoBench.h @@ -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]; diff --git a/kernel/Makefile b/kernel/Makefile index c899ae3..b8ad214 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -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 diff --git a/kernel/nb_km.c b/kernel/nb_km.c index 6397f58..a1e9c33 100644 --- a/kernel/nb_km.c +++ b/kernel/nb_km.c @@ -11,6 +11,8 @@ #include #include +#include +#include #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; imm->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(¤t->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