From 53548d64cba3af8e063f41f0eedbeecf8fa1b67b Mon Sep 17 00:00:00 2001 From: Namhoon Kim Date: Mon, 6 Feb 2017 16:20:41 -0500 Subject: Kernel page device is added. --- include/linux/mmzone.h | 9 ++ include/litmus/page_dev.h | 30 +++++ litmus/Makefile | 3 +- litmus/page_dev.c | 292 ++++++++++++++++++++++++++++++++++++++++++++++ mm/page_alloc.c | 1 + 5 files changed, 334 insertions(+), 1 deletion(-) create mode 100644 include/litmus/page_dev.h create mode 100644 litmus/page_dev.c diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 54d74f6eb233..92084abf3cf5 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -35,6 +35,15 @@ */ #define PAGE_ALLOC_COSTLY_ORDER 3 +/* For page coloring - This address decoding is used in imx6-sabresd + * platform without bank interleaving . + */ +#define BANK_MASK 0x38000000 +#define BANK_SHIFT 27 + +#define CACHE_MASK 0x0000f000 +#define CACHE_SHIFT 12 + enum { MIGRATE_UNMOVABLE, MIGRATE_RECLAIMABLE, diff --git a/include/litmus/page_dev.h b/include/litmus/page_dev.h new file mode 100644 index 000000000000..9dac293651f0 --- /dev/null +++ b/include/litmus/page_dev.h @@ -0,0 +1,30 @@ +/* + * page_dev.h - Implementation of the page coloring for cache and bank partition. + * The file will keep a pool of colored pages. MMU can allocate pages with + * specific color or bank number. + * Author: Namhoon Kim (namhoonk@cs.unc.edu) + */ + +#ifndef _LITMUS_PAGE_DEV_H +#define _LITMUS_PAGE_DEV_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +int llc_partition_handler(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos); +int dram_partition_handler(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos); + +#endif /* _LITMUS_PAGE_DEV_H */ \ No newline at end of file diff --git a/litmus/Makefile b/litmus/Makefile index 7e4711cf25b4..29ae4b04f046 100644 --- a/litmus/Makefile +++ b/litmus/Makefile @@ -29,7 +29,8 @@ obj-y = sched_plugin.o litmus.o \ bank_proc.o \ color_shm.o \ replicate_lib.o \ - cache_proc.o + cache_proc.o \ + page_dev.o obj-$(CONFIG_PLUGIN_CEDF) += sched_cedf.o obj-$(CONFIG_PLUGIN_PFAIR) += sched_pfair.o diff --git a/litmus/page_dev.c b/litmus/page_dev.c new file mode 100644 index 000000000000..16a6b756353b --- /dev/null +++ b/litmus/page_dev.c @@ -0,0 +1,292 @@ +/* + * page_dev.c - Implementation of the page coloring for cache and bank partition. + * The file will keep a pool of colored pages. MMU can allocate pages with + * specific color or bank number. + * Author: Namhoon Kim (namhoonk@cs.unc.edu) + */ + +#include + +#define NR_PARTITIONS 9 + +struct mutex dev_mutex; + +/* Initial partitions for LLC and DRAM bank */ +/* 4 color for each core, all colors for Level C */ +unsigned int llc_partition[NR_PARTITIONS] = { + 0x00000003, /* Core 0, and Level A*/ + 0x00000003, /* Core 0, and Level B*/ + 0x0000000C, /* Core 1, and Level A*/ + 0x0000000C, /* Core 1, and Level B*/ + 0x00000030, /* Core 2, and Level A*/ + 0x00000030, /* Core 2, and Level B*/ + 0x000000C0, /* Core 3, and Level A*/ + 0x000000C0, /* Core 3, and Level B*/ + 0x0000ffff, /* Level C */ +}; + +/* 1 bank for each core, 2 banks for Level C */ +unsigned int dram_partition[NR_PARTITIONS] = { + 0x00000010, /* Core 0, and Level A*/ + 0x00000010, /* Core 0, and Level B*/ + 0x00000020, /* Core 1, and Level A*/ + 0x00000020, /* Core 1, and Level B*/ + 0x00000040, /* Core 2, and Level A*/ + 0x00000040, /* Core 2, and Level B*/ + 0x00000080, /* Core 3, and Level A*/ + 0x00000080, /* Core 3, and Level B*/ + 0x0000000c, /* Level C */ +}; + +/* Bounds for values */ +unsigned int llc_partition_max = 0x0000ffff; +unsigned int llc_partition_min = 0; +unsigned int dram_partition_max = 0x000000ff; +unsigned int dram_partition_min = 0; + +static struct ctl_table partition_table[] = +{ + + { + .procname = "C0_LA_color", + .mode = 0666, + .proc_handler = llc_partition_handler, + .data = &llc_partition[0], + .maxlen = sizeof(llc_partition[0]), + .extra1 = &llc_partition_min, + .extra2 = &llc_partition_max, + }, + { + .procname = "C0_LB_color", + .mode = 0666, + .proc_handler = llc_partition_handler, + .data = &llc_partition[1], + .maxlen = sizeof(llc_partition[1]), + .extra1 = &llc_partition_min, + .extra2 = &llc_partition_max, + }, + { + .procname = "C1_LA_color", + .mode = 0666, + .proc_handler = llc_partition_handler, + .data = &llc_partition[2], + .maxlen = sizeof(llc_partition[2]), + .extra1 = &llc_partition_min, + .extra2 = &llc_partition_max, + }, + { + .procname = "C1_LB_color", + .mode = 0666, + .proc_handler = llc_partition_handler, + .data = &llc_partition[3], + .maxlen = sizeof(llc_partition[3]), + .extra1 = &llc_partition_min, + .extra2 = &llc_partition_max, + }, + { + .procname = "C2_LA_color", + .mode = 0666, + .proc_handler = llc_partition_handler, + .data = &llc_partition[4], + .maxlen = sizeof(llc_partition[4]), + .extra1 = &llc_partition_min, + .extra2 = &llc_partition_max, + }, + { + .procname = "C2_LB_color", + .mode = 0666, + .proc_handler = llc_partition_handler, + .data = &llc_partition[5], + .maxlen = sizeof(llc_partition[5]), + .extra1 = &llc_partition_min, + .extra2 = &llc_partition_max, + }, + { + .procname = "C3_LA_color", + .mode = 0666, + .proc_handler = llc_partition_handler, + .data = &llc_partition[6], + .maxlen = sizeof(llc_partition[6]), + .extra1 = &llc_partition_min, + .extra2 = &llc_partition_max, + }, + { + .procname = "C3_LB_color", + .mode = 0666, + .proc_handler = llc_partition_handler, + .data = &llc_partition[7], + .maxlen = sizeof(llc_partition[7]), + .extra1 = &llc_partition_min, + .extra2 = &llc_partition_max, + }, + { + .procname = "Call_LC_color", + .mode = 0666, + .proc_handler = llc_partition_handler, + .data = &llc_partition[8], + .maxlen = sizeof(llc_partition[8]), + .extra1 = &llc_partition_min, + .extra2 = &llc_partition_max, + }, + { + .procname = "C0_LA_dram", + .mode = 0666, + .proc_handler = dram_partition_handler, + .data = &dram_partition[0], + .maxlen = sizeof(llc_partition[0]), + .extra1 = &dram_partition_min, + .extra2 = &dram_partition_max, + }, + { + .procname = "C0_LB_dram", + .mode = 0666, + .proc_handler = dram_partition_handler, + .data = &dram_partition[1], + .maxlen = sizeof(llc_partition[1]), + .extra1 = &dram_partition_min, + .extra2 = &dram_partition_max, + }, + { + .procname = "C1_LA_dram", + .mode = 0666, + .proc_handler = dram_partition_handler, + .data = &dram_partition[2], + .maxlen = sizeof(llc_partition[2]), + .extra1 = &dram_partition_min, + .extra2 = &dram_partition_max, + }, + { + .procname = "C1_LB_dram", + .mode = 0666, + .proc_handler = dram_partition_handler, + .data = &dram_partition[3], + .maxlen = sizeof(llc_partition[3]), + .extra1 = &dram_partition_min, + .extra2 = &dram_partition_max, + }, + { + .procname = "C2_LA_dram", + .mode = 0666, + .proc_handler = dram_partition_handler, + .data = &dram_partition[4], + .maxlen = sizeof(llc_partition[4]), + .extra1 = &dram_partition_min, + .extra2 = &dram_partition_max, + }, + { + .procname = "C2_LB_dram", + .mode = 0666, + .proc_handler = dram_partition_handler, + .data = &dram_partition[5], + .maxlen = sizeof(llc_partition[5]), + .extra1 = &dram_partition_min, + .extra2 = &dram_partition_max, + }, + { + .procname = "C3_LA_dram", + .mode = 0666, + .proc_handler = dram_partition_handler, + .data = &dram_partition[6], + .maxlen = sizeof(llc_partition[6]), + .extra1 = &dram_partition_min, + .extra2 = &dram_partition_max, + }, + { + .procname = "C3_LB_dram", + .mode = 0666, + .proc_handler = dram_partition_handler, + .data = &dram_partition[7], + .maxlen = sizeof(llc_partition[7]), + .extra1 = &dram_partition_min, + .extra2 = &dram_partition_max, + }, + { + .procname = "Call_LC_dram", + .mode = 0666, + .proc_handler = dram_partition_handler, + .data = &dram_partition[8], + .maxlen = sizeof(llc_partition[8]), + .extra1 = &dram_partition_min, + .extra2 = &dram_partition_max, + }, + { } +}; + +static struct ctl_table litmus_dir_table[] = { + { + .procname = "litmus", + .mode = 0555, + .child = partition_table, + }, + { } +}; + +static struct ctl_table_header *litmus_sysctls; + +int llc_partition_handler(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) +{ + int ret = 0, i; + mutex_lock(&dev_mutex); + ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); + if (ret) + goto out; + if (write) { + printk("New LLC Partition : \n"); + for(i = 0; i < NR_PARTITIONS; i++) { + printk("llc_partition[%d] = %x\n", i, llc_partition[i]); + } + } +out: + mutex_unlock(&dev_mutex); + return ret; +} + +int dram_partition_handler(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) +{ + int ret = 0, i; + mutex_lock(&dev_mutex); + ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); + if (ret) + goto out; + if (write) { + for(i = 0; i < NR_PARTITIONS; i++) { + printk("dram_partition[%d] = %x\n", i, dram_partition[i]); + } + } +out: + mutex_unlock(&dev_mutex); + return ret; +} + +/* + * Initialize this page_dev proc. + */ +static int __init init_litmus_page_dev(void) +{ + int err = 0; + + printk("Initialize page_dev.c\n"); + + mutex_init(&dev_mutex); + + printk(KERN_INFO "Registering LITMUS^RT proc page_dev sysctl.\n"); + + litmus_sysctls = register_sysctl_table(litmus_dir_table); + if (!litmus_sysctls) { + printk(KERN_WARNING "Could not register LITMUS^RT page_dev sysctl.\n"); + err = -EFAULT; + goto out; + } + + printk(KERN_INFO "Registering LITMUS^RT page_dev proc.\n"); +out: + return err; +} + +static void __exit exit_litmus_page_dev(void) +{ + mutex_destroy(&dev_mutex); +} + +module_init(init_litmus_page_dev); +module_exit(exit_litmus_page_dev); \ No newline at end of file diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 950c002bbb45..ff2d2830e877 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -65,6 +65,7 @@ #include #include /* for is_realtime() */ +#include /* for coloring pages */ #include #include -- cgit v1.2.2