diff options
author | Namhoon Kim <namhoonk@cs.unc.edu> | 2017-02-06 16:20:41 -0500 |
---|---|---|
committer | Namhoon Kim <namhoonk@cs.unc.edu> | 2017-02-06 16:20:41 -0500 |
commit | 53548d64cba3af8e063f41f0eedbeecf8fa1b67b (patch) | |
tree | 736157d151711ccadf8a6ce40adff51796b421f3 | |
parent | a53078ec5cc167413bad6dd7ce3c1fc8ec97d39e (diff) |
Kernel page device is added.
-rw-r--r-- | include/linux/mmzone.h | 9 | ||||
-rw-r--r-- | include/litmus/page_dev.h | 30 | ||||
-rw-r--r-- | litmus/Makefile | 3 | ||||
-rw-r--r-- | litmus/page_dev.c | 292 | ||||
-rw-r--r-- | mm/page_alloc.c | 1 |
5 files changed, 334 insertions, 1 deletions
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 @@ | |||
35 | */ | 35 | */ |
36 | #define PAGE_ALLOC_COSTLY_ORDER 3 | 36 | #define PAGE_ALLOC_COSTLY_ORDER 3 |
37 | 37 | ||
38 | /* For page coloring - This address decoding is used in imx6-sabresd | ||
39 | * platform without bank interleaving . | ||
40 | */ | ||
41 | #define BANK_MASK 0x38000000 | ||
42 | #define BANK_SHIFT 27 | ||
43 | |||
44 | #define CACHE_MASK 0x0000f000 | ||
45 | #define CACHE_SHIFT 12 | ||
46 | |||
38 | enum { | 47 | enum { |
39 | MIGRATE_UNMOVABLE, | 48 | MIGRATE_UNMOVABLE, |
40 | MIGRATE_RECLAIMABLE, | 49 | 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 @@ | |||
1 | /* | ||
2 | * page_dev.h - Implementation of the page coloring for cache and bank partition. | ||
3 | * The file will keep a pool of colored pages. MMU can allocate pages with | ||
4 | * specific color or bank number. | ||
5 | * Author: Namhoon Kim (namhoonk@cs.unc.edu) | ||
6 | */ | ||
7 | |||
8 | #ifndef _LITMUS_PAGE_DEV_H | ||
9 | #define _LITMUS_PAGE_DEV_H | ||
10 | |||
11 | #include <linux/init.h> | ||
12 | #include <linux/types.h> | ||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/sysctl.h> | ||
16 | #include <linux/slab.h> | ||
17 | #include <linux/io.h> | ||
18 | #include <linux/mutex.h> | ||
19 | #include <linux/mm.h> | ||
20 | #include <linux/random.h> | ||
21 | #include <linux/mmzone.h> | ||
22 | |||
23 | #include <litmus/litmus_proc.h> | ||
24 | #include <litmus/sched_trace.h> | ||
25 | #include <litmus/litmus.h> | ||
26 | |||
27 | int llc_partition_handler(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos); | ||
28 | int dram_partition_handler(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos); | ||
29 | |||
30 | #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 \ | |||
29 | bank_proc.o \ | 29 | bank_proc.o \ |
30 | color_shm.o \ | 30 | color_shm.o \ |
31 | replicate_lib.o \ | 31 | replicate_lib.o \ |
32 | cache_proc.o | 32 | cache_proc.o \ |
33 | page_dev.o | ||
33 | 34 | ||
34 | obj-$(CONFIG_PLUGIN_CEDF) += sched_cedf.o | 35 | obj-$(CONFIG_PLUGIN_CEDF) += sched_cedf.o |
35 | obj-$(CONFIG_PLUGIN_PFAIR) += sched_pfair.o | 36 | 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 @@ | |||
1 | /* | ||
2 | * page_dev.c - Implementation of the page coloring for cache and bank partition. | ||
3 | * The file will keep a pool of colored pages. MMU can allocate pages with | ||
4 | * specific color or bank number. | ||
5 | * Author: Namhoon Kim (namhoonk@cs.unc.edu) | ||
6 | */ | ||
7 | |||
8 | #include <litmus/page_dev.h> | ||
9 | |||
10 | #define NR_PARTITIONS 9 | ||
11 | |||
12 | struct mutex dev_mutex; | ||
13 | |||
14 | /* Initial partitions for LLC and DRAM bank */ | ||
15 | /* 4 color for each core, all colors for Level C */ | ||
16 | unsigned int llc_partition[NR_PARTITIONS] = { | ||
17 | 0x00000003, /* Core 0, and Level A*/ | ||
18 | 0x00000003, /* Core 0, and Level B*/ | ||
19 | 0x0000000C, /* Core 1, and Level A*/ | ||
20 | 0x0000000C, /* Core 1, and Level B*/ | ||
21 | 0x00000030, /* Core 2, and Level A*/ | ||
22 | 0x00000030, /* Core 2, and Level B*/ | ||
23 | 0x000000C0, /* Core 3, and Level A*/ | ||
24 | 0x000000C0, /* Core 3, and Level B*/ | ||
25 | 0x0000ffff, /* Level C */ | ||
26 | }; | ||
27 | |||
28 | /* 1 bank for each core, 2 banks for Level C */ | ||
29 | unsigned int dram_partition[NR_PARTITIONS] = { | ||
30 | 0x00000010, /* Core 0, and Level A*/ | ||
31 | 0x00000010, /* Core 0, and Level B*/ | ||
32 | 0x00000020, /* Core 1, and Level A*/ | ||
33 | 0x00000020, /* Core 1, and Level B*/ | ||
34 | 0x00000040, /* Core 2, and Level A*/ | ||
35 | 0x00000040, /* Core 2, and Level B*/ | ||
36 | 0x00000080, /* Core 3, and Level A*/ | ||
37 | 0x00000080, /* Core 3, and Level B*/ | ||
38 | 0x0000000c, /* Level C */ | ||
39 | }; | ||
40 | |||
41 | /* Bounds for values */ | ||
42 | unsigned int llc_partition_max = 0x0000ffff; | ||
43 | unsigned int llc_partition_min = 0; | ||
44 | unsigned int dram_partition_max = 0x000000ff; | ||
45 | unsigned int dram_partition_min = 0; | ||
46 | |||
47 | static struct ctl_table partition_table[] = | ||
48 | { | ||
49 | |||
50 | { | ||
51 | .procname = "C0_LA_color", | ||
52 | .mode = 0666, | ||
53 | .proc_handler = llc_partition_handler, | ||
54 | .data = &llc_partition[0], | ||
55 | .maxlen = sizeof(llc_partition[0]), | ||
56 | .extra1 = &llc_partition_min, | ||
57 | .extra2 = &llc_partition_max, | ||
58 | }, | ||
59 | { | ||
60 | .procname = "C0_LB_color", | ||
61 | .mode = 0666, | ||
62 | .proc_handler = llc_partition_handler, | ||
63 | .data = &llc_partition[1], | ||
64 | .maxlen = sizeof(llc_partition[1]), | ||
65 | .extra1 = &llc_partition_min, | ||
66 | .extra2 = &llc_partition_max, | ||
67 | }, | ||
68 | { | ||
69 | .procname = "C1_LA_color", | ||
70 | .mode = 0666, | ||
71 | .proc_handler = llc_partition_handler, | ||
72 | .data = &llc_partition[2], | ||
73 | .maxlen = sizeof(llc_partition[2]), | ||
74 | .extra1 = &llc_partition_min, | ||
75 | .extra2 = &llc_partition_max, | ||
76 | }, | ||
77 | { | ||
78 | .procname = "C1_LB_color", | ||
79 | .mode = 0666, | ||
80 | .proc_handler = llc_partition_handler, | ||
81 | .data = &llc_partition[3], | ||
82 | .maxlen = sizeof(llc_partition[3]), | ||
83 | .extra1 = &llc_partition_min, | ||
84 | .extra2 = &llc_partition_max, | ||
85 | }, | ||
86 | { | ||
87 | .procname = "C2_LA_color", | ||
88 | .mode = 0666, | ||
89 | .proc_handler = llc_partition_handler, | ||
90 | .data = &llc_partition[4], | ||
91 | .maxlen = sizeof(llc_partition[4]), | ||
92 | .extra1 = &llc_partition_min, | ||
93 | .extra2 = &llc_partition_max, | ||
94 | }, | ||
95 | { | ||
96 | .procname = "C2_LB_color", | ||
97 | .mode = 0666, | ||
98 | .proc_handler = llc_partition_handler, | ||
99 | .data = &llc_partition[5], | ||
100 | .maxlen = sizeof(llc_partition[5]), | ||
101 | .extra1 = &llc_partition_min, | ||
102 | .extra2 = &llc_partition_max, | ||
103 | }, | ||
104 | { | ||
105 | .procname = "C3_LA_color", | ||
106 | .mode = 0666, | ||
107 | .proc_handler = llc_partition_handler, | ||
108 | .data = &llc_partition[6], | ||
109 | .maxlen = sizeof(llc_partition[6]), | ||
110 | .extra1 = &llc_partition_min, | ||
111 | .extra2 = &llc_partition_max, | ||
112 | }, | ||
113 | { | ||
114 | .procname = "C3_LB_color", | ||
115 | .mode = 0666, | ||
116 | .proc_handler = llc_partition_handler, | ||
117 | .data = &llc_partition[7], | ||
118 | .maxlen = sizeof(llc_partition[7]), | ||
119 | .extra1 = &llc_partition_min, | ||
120 | .extra2 = &llc_partition_max, | ||
121 | }, | ||
122 | { | ||
123 | .procname = "Call_LC_color", | ||
124 | .mode = 0666, | ||
125 | .proc_handler = llc_partition_handler, | ||
126 | .data = &llc_partition[8], | ||
127 | .maxlen = sizeof(llc_partition[8]), | ||
128 | .extra1 = &llc_partition_min, | ||
129 | .extra2 = &llc_partition_max, | ||
130 | }, | ||
131 | { | ||
132 | .procname = "C0_LA_dram", | ||
133 | .mode = 0666, | ||
134 | .proc_handler = dram_partition_handler, | ||
135 | .data = &dram_partition[0], | ||
136 | .maxlen = sizeof(llc_partition[0]), | ||
137 | .extra1 = &dram_partition_min, | ||
138 | .extra2 = &dram_partition_max, | ||
139 | }, | ||
140 | { | ||
141 | .procname = "C0_LB_dram", | ||
142 | .mode = 0666, | ||
143 | .proc_handler = dram_partition_handler, | ||
144 | .data = &dram_partition[1], | ||
145 | .maxlen = sizeof(llc_partition[1]), | ||
146 | .extra1 = &dram_partition_min, | ||
147 | .extra2 = &dram_partition_max, | ||
148 | }, | ||
149 | { | ||
150 | .procname = "C1_LA_dram", | ||
151 | .mode = 0666, | ||
152 | .proc_handler = dram_partition_handler, | ||
153 | .data = &dram_partition[2], | ||
154 | .maxlen = sizeof(llc_partition[2]), | ||
155 | .extra1 = &dram_partition_min, | ||
156 | .extra2 = &dram_partition_max, | ||
157 | }, | ||
158 | { | ||
159 | .procname = "C1_LB_dram", | ||
160 | .mode = 0666, | ||
161 | .proc_handler = dram_partition_handler, | ||
162 | .data = &dram_partition[3], | ||
163 | .maxlen = sizeof(llc_partition[3]), | ||
164 | .extra1 = &dram_partition_min, | ||
165 | .extra2 = &dram_partition_max, | ||
166 | }, | ||
167 | { | ||
168 | .procname = "C2_LA_dram", | ||
169 | .mode = 0666, | ||
170 | .proc_handler = dram_partition_handler, | ||
171 | .data = &dram_partition[4], | ||
172 | .maxlen = sizeof(llc_partition[4]), | ||
173 | .extra1 = &dram_partition_min, | ||
174 | .extra2 = &dram_partition_max, | ||
175 | }, | ||
176 | { | ||
177 | .procname = "C2_LB_dram", | ||
178 | .mode = 0666, | ||
179 | .proc_handler = dram_partition_handler, | ||
180 | .data = &dram_partition[5], | ||
181 | .maxlen = sizeof(llc_partition[5]), | ||
182 | .extra1 = &dram_partition_min, | ||
183 | .extra2 = &dram_partition_max, | ||
184 | }, | ||
185 | { | ||
186 | .procname = "C3_LA_dram", | ||
187 | .mode = 0666, | ||
188 | .proc_handler = dram_partition_handler, | ||
189 | .data = &dram_partition[6], | ||
190 | .maxlen = sizeof(llc_partition[6]), | ||
191 | .extra1 = &dram_partition_min, | ||
192 | .extra2 = &dram_partition_max, | ||
193 | }, | ||
194 | { | ||
195 | .procname = "C3_LB_dram", | ||
196 | .mode = 0666, | ||
197 | .proc_handler = dram_partition_handler, | ||
198 | .data = &dram_partition[7], | ||
199 | .maxlen = sizeof(llc_partition[7]), | ||
200 | .extra1 = &dram_partition_min, | ||
201 | .extra2 = &dram_partition_max, | ||
202 | }, | ||
203 | { | ||
204 | .procname = "Call_LC_dram", | ||
205 | .mode = 0666, | ||
206 | .proc_handler = dram_partition_handler, | ||
207 | .data = &dram_partition[8], | ||
208 | .maxlen = sizeof(llc_partition[8]), | ||
209 | .extra1 = &dram_partition_min, | ||
210 | .extra2 = &dram_partition_max, | ||
211 | }, | ||
212 | { } | ||
213 | }; | ||
214 | |||
215 | static struct ctl_table litmus_dir_table[] = { | ||
216 | { | ||
217 | .procname = "litmus", | ||
218 | .mode = 0555, | ||
219 | .child = partition_table, | ||
220 | }, | ||
221 | { } | ||
222 | }; | ||
223 | |||
224 | static struct ctl_table_header *litmus_sysctls; | ||
225 | |||
226 | int llc_partition_handler(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) | ||
227 | { | ||
228 | int ret = 0, i; | ||
229 | mutex_lock(&dev_mutex); | ||
230 | ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); | ||
231 | if (ret) | ||
232 | goto out; | ||
233 | if (write) { | ||
234 | printk("New LLC Partition : \n"); | ||
235 | for(i = 0; i < NR_PARTITIONS; i++) { | ||
236 | printk("llc_partition[%d] = %x\n", i, llc_partition[i]); | ||
237 | } | ||
238 | } | ||
239 | out: | ||
240 | mutex_unlock(&dev_mutex); | ||
241 | return ret; | ||
242 | } | ||
243 | |||
244 | int dram_partition_handler(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) | ||
245 | { | ||
246 | int ret = 0, i; | ||
247 | mutex_lock(&dev_mutex); | ||
248 | ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); | ||
249 | if (ret) | ||
250 | goto out; | ||
251 | if (write) { | ||
252 | for(i = 0; i < NR_PARTITIONS; i++) { | ||
253 | printk("dram_partition[%d] = %x\n", i, dram_partition[i]); | ||
254 | } | ||
255 | } | ||
256 | out: | ||
257 | mutex_unlock(&dev_mutex); | ||
258 | return ret; | ||
259 | } | ||
260 | |||
261 | /* | ||
262 | * Initialize this page_dev proc. | ||
263 | */ | ||
264 | static int __init init_litmus_page_dev(void) | ||
265 | { | ||
266 | int err = 0; | ||
267 | |||
268 | printk("Initialize page_dev.c\n"); | ||
269 | |||
270 | mutex_init(&dev_mutex); | ||
271 | |||
272 | printk(KERN_INFO "Registering LITMUS^RT proc page_dev sysctl.\n"); | ||
273 | |||
274 | litmus_sysctls = register_sysctl_table(litmus_dir_table); | ||
275 | if (!litmus_sysctls) { | ||
276 | printk(KERN_WARNING "Could not register LITMUS^RT page_dev sysctl.\n"); | ||
277 | err = -EFAULT; | ||
278 | goto out; | ||
279 | } | ||
280 | |||
281 | printk(KERN_INFO "Registering LITMUS^RT page_dev proc.\n"); | ||
282 | out: | ||
283 | return err; | ||
284 | } | ||
285 | |||
286 | static void __exit exit_litmus_page_dev(void) | ||
287 | { | ||
288 | mutex_destroy(&dev_mutex); | ||
289 | } | ||
290 | |||
291 | module_init(init_litmus_page_dev); | ||
292 | 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 @@ | |||
65 | #include <asm/sections.h> | 65 | #include <asm/sections.h> |
66 | 66 | ||
67 | #include <litmus/litmus.h> /* for is_realtime() */ | 67 | #include <litmus/litmus.h> /* for is_realtime() */ |
68 | #include <litmus/page_dev.h> /* for coloring pages */ | ||
68 | 69 | ||
69 | #include <asm/tlbflush.h> | 70 | #include <asm/tlbflush.h> |
70 | #include <asm/div64.h> | 71 | #include <asm/div64.h> |