aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristopher Kenna <cjk@cs.unc.edu>2012-10-09 23:19:37 -0400
committerChristopher Kenna <cjk@cs.unc.edu>2012-10-11 18:30:57 -0400
commit549f0df67a3346fecc8bebe04d21a2c24045c093 (patch)
tree8a5a22d853e4a63c8c3407a9ff9eed7c69319840
parent559680d37afd399928fb70a21961d625af7d96bb (diff)
uncachable color control page
Signed-off-by: Christopher Kenna <cjk@cs.unc.edu>
-rw-r--r--arch/arm/mm/cache-l2x0.c2
-rw-r--r--include/litmus/color.h6
-rw-r--r--include/litmus/litmus.h4
-rw-r--r--include/litmus/rt_param.h3
-rw-r--r--litmus/color.c2
-rw-r--r--litmus/color_dev.c65
-rw-r--r--litmus/color_proc.c7
-rw-r--r--litmus/ctrldev.c15
-rw-r--r--litmus/litmus.c20
9 files changed, 93 insertions, 31 deletions
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 83a9c076931b..2cbd6ca0ce23 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -354,6 +354,8 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
354 color_cache_info.ways = l2x0_ways; 354 color_cache_info.ways = l2x0_ways;
355 color_cache_info.sets = l2x0_sets; 355 color_cache_info.sets = l2x0_sets;
356 356
357 litmus_setup_lockdown(l2x0_base);
358
357 printk(KERN_INFO "%s cache controller enabled\n", type); 359 printk(KERN_INFO "%s cache controller enabled\n", type);
358 printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x, Cache size: %d B\n", 360 printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x, Cache size: %d B\n",
359 ways, cache_id, aux, l2x0_size); 361 ways, cache_id, aux, l2x0_size);
diff --git a/include/litmus/color.h b/include/litmus/color.h
index eefb6c6dddf5..0e67028f8ea3 100644
--- a/include/litmus/color.h
+++ b/include/litmus/color.h
@@ -6,6 +6,12 @@
6#define ONE_COLOR_LEN 11 6#define ONE_COLOR_LEN 11
7#define ONE_COLOR_FMT "%4lu: %4d\n" 7#define ONE_COLOR_FMT "%4lu: %4d\n"
8 8
9#ifdef CONFIG_PHYS_ADDR_T_64BIT
10#define FMT_PA "llx"
11#else
12#define FMT_PA "lx"
13#endif
14
9struct color_cache_info { 15struct color_cache_info {
10 unsigned long size; 16 unsigned long size;
11 unsigned long line_size; 17 unsigned long line_size;
diff --git a/include/litmus/litmus.h b/include/litmus/litmus.h
index 93961d08efd5..91623528ad9e 100644
--- a/include/litmus/litmus.h
+++ b/include/litmus/litmus.h
@@ -14,6 +14,10 @@ extern atomic_t release_master_cpu;
14 14
15void litmus_schedule_deallocation(struct task_struct *t); 15void litmus_schedule_deallocation(struct task_struct *t);
16 16
17#ifdef CONFIG_ARCH_NEEDS_UNCACHED_CONTROL_PAGE
18void * remap_noncached(void *addr, size_t len);
19#endif
20
17/* in_list - is a given list_head queued on some list? 21/* in_list - is a given list_head queued on some list?
18 */ 22 */
19static inline int in_list(struct list_head* list) 23static inline int in_list(struct list_head* list)
diff --git a/include/litmus/rt_param.h b/include/litmus/rt_param.h
index 1ee65e19d7b7..e9e26faddcea 100644
--- a/include/litmus/rt_param.h
+++ b/include/litmus/rt_param.h
@@ -277,6 +277,9 @@ struct rt_param {
277 lt_t last_exec_time; 277 lt_t last_exec_time;
278 lt_t orig_cost; 278 lt_t orig_cost;
279 struct color_ctrl_page *color_ctrl_page; 279 struct color_ctrl_page *color_ctrl_page;
280#ifdef CONFIG_ARCH_NEEDS_UNCACHED_CONTROL_PAGE
281 void *color_ctrl_page_orig;
282#endif
280 struct dgl_group_req *req; 283 struct dgl_group_req *req;
281}; 284};
282 285
diff --git a/litmus/color.c b/litmus/color.c
index b2834b369396..976366e7e39c 100644
--- a/litmus/color.c
+++ b/litmus/color.c
@@ -198,7 +198,7 @@ void reclaim_pages(struct vm_area_struct *vma)
198 put_page(ap->page); 198 put_page(ap->page);
199 add_page_to_color_list(ap->page); 199 add_page_to_color_list(ap->page);
200 nr_reclaimed++; 200 nr_reclaimed++;
201 TRACE_CUR("reclaiming page (pa:0x%10llx, pfn:%8lu, " 201 TRACE_CUR("reclaiming page (pa:0x%10"FMT_PA", pfn:%8lu, "
202 "color:%3lu)\n", page_to_phys(ap->page), 202 "color:%3lu)\n", page_to_phys(ap->page),
203 page_to_pfn(ap->page), page_color(ap->page)); 203 page_to_pfn(ap->page), page_color(ap->page));
204 kfree(ap); 204 kfree(ap);
diff --git a/litmus/color_dev.c b/litmus/color_dev.c
index 3ed584ad7aff..6287d14405e8 100644
--- a/litmus/color_dev.c
+++ b/litmus/color_dev.c
@@ -7,6 +7,8 @@
7#include <linux/highmem.h> 7#include <linux/highmem.h>
8#include <asm/io.h> /* page_to_phys on SPARC */ 8#include <asm/io.h> /* page_to_phys on SPARC */
9 9
10#include <asm/glue-cache.h>
11
10#include <litmus/litmus.h> 12#include <litmus/litmus.h>
11#include <litmus/color.h> 13#include <litmus/color.h>
12 14
@@ -82,17 +84,35 @@ static struct vm_operations_struct litmus_color_ctrl_vm_ops = {
82 84
83static int alloc_color_ctrl_page(void) 85static int alloc_color_ctrl_page(void)
84{ 86{
87 void *mem;
88#ifdef CONFIG_ARCH_NEEDS_UNCACHED_CONTROL_PAGE
89 void *mem_remap;
90#endif
85 struct task_struct *t = current; 91 struct task_struct *t = current;
86 int err = 0; 92 int err = 0;
87 93
88 /* only allocate if the task doesn't have one yet */ 94 /* only allocate if the task doesn't have one yet */
89 if (!tsk_rt(t)->color_ctrl_page) { 95 if (!tsk_rt(t)->color_ctrl_page) {
90 tsk_rt(t)->color_ctrl_page = (void*) get_zeroed_page(GFP_KERNEL); 96 mem = (void*) get_zeroed_page(GFP_KERNEL);
91 if (!tsk_rt(t)->color_ctrl_page) { 97 if (!mem) {
92 TRACE_TASK(t, "could not allocate control page\n"); 98 TRACE_TASK(t, "cannot allocate color control page\n");
93 err = -ENOMEM; 99 err = -ENOMEM;
94 goto out; 100 goto out;
95 } 101 }
102
103#ifdef CONFIG_ARCH_NEEDS_UNCACHED_CONTROL_PAGE
104 mem_remap = remap_noncached(mem, PAGE_SIZE);
105 if (IS_ERR(mem_remap)) {
106 err = PTR_ERR(mem_remap);
107 free_page((unsigned long) mem);
108 goto out;
109 }
110 tsk_rt(t)->color_ctrl_page_orig = mem;
111 tsk_rt(t)->color_ctrl_page = mem_remap;
112#else
113 tsk_rt(t)->color_ctrl_page = mem;
114#endif
115
96 /* will get de-allocated in task teardown */ 116 /* will get de-allocated in task teardown */
97 TRACE_TASK(t, "color_ctrl_page = %p\n", 117 TRACE_TASK(t, "color_ctrl_page = %p\n",
98 tsk_rt(t)->color_ctrl_page); 118 tsk_rt(t)->color_ctrl_page);
@@ -105,7 +125,14 @@ static int map_color_ctrl_page(struct vm_area_struct *vma)
105{ 125{
106 int err = 0; 126 int err = 0;
107 struct task_struct *t = current; 127 struct task_struct *t = current;
108 struct page *color_ctrl = virt_to_page(tsk_rt(t)->color_ctrl_page); 128 struct page *color_ctrl;
129
130#ifdef CONFIG_ARCH_NEEDS_UNCACHED_CONTROL_PAGE
131 /* vm_insert_page() using the "real" vaddr, not the shadow mapping. */
132 color_ctrl = virt_to_page(tsk_rt(t)->color_ctrl_page_orig);
133#else
134 color_ctrl = virt_to_page(tsk_rt(t)->color_ctrl_page);
135#endif
109 136
110 TRACE_CUR("mapping %p (pfn:%lx) to 0x%lx (flags:%lx prot:%lx)\n", 137 TRACE_CUR("mapping %p (pfn:%lx) to 0x%lx (flags:%lx prot:%lx)\n",
111 tsk_rt(t)->color_ctrl_page, page_to_pfn(color_ctrl), 138 tsk_rt(t)->color_ctrl_page, page_to_pfn(color_ctrl),
@@ -139,6 +166,10 @@ static int litmus_color_ctrl_mmap(struct file *filp, struct vm_area_struct *vma)
139 vma->vm_ops = &litmus_color_ctrl_vm_ops; 166 vma->vm_ops = &litmus_color_ctrl_vm_ops;
140 mmap_common_vma_flags(vma); 167 mmap_common_vma_flags(vma);
141 168
169#ifdef CONFIG_ARCH_NEEDS_UNCACHED_CONTROL_PAGE
170 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
171#endif
172
142 err = alloc_color_ctrl_page(); 173 err = alloc_color_ctrl_page();
143 if (!err) 174 if (!err)
144 err = map_color_ctrl_page(vma); 175 err = map_color_ctrl_page(vma);
@@ -164,6 +195,9 @@ static int do_map_colored_page_set(struct vm_area_struct *vma,
164{ 195{
165 int i, err = 0; 196 int i, err = 0;
166 197
198 TRACE_CUR("vma: %p starting_at: 0x%10lx color_no: %lu nr_pages: %lu\n",
199 vma, starting_at, color_no, nr_pages);
200
167 for (i = 0; i < nr_pages; ++i) { 201 for (i = 0; i < nr_pages; ++i) {
168 const unsigned long addr = starting_at + (i << PAGE_SHIFT); 202 const unsigned long addr = starting_at + (i << PAGE_SHIFT);
169 struct page *page = get_colored_page(color_no); 203 struct page *page = get_colored_page(color_no);
@@ -176,16 +210,13 @@ static int do_map_colored_page_set(struct vm_area_struct *vma,
176 goto out; 210 goto out;
177 } 211 }
178 212
179 clear_user_highpage(page, addr); 213 /* TODO For some reason this causes problems on ARM. */
214 /* clear_user_highpage(page, addr); */
180 215
181 TRACE_CUR("insert page (pa:0x%10llx, pfn:%8lu, color:%3lu) " 216 TRACE_CUR("inserting page (pa: 0x%"FMT_PA") at vaddr: 0x%10lx "
182 "at 0x%lx vma:(flags:0x%16lx prot:0x%16lx)\n", 217 "flags: 0x%10lx prot: 0x%10lx\n",
183 page_to_phys(page), 218 page_to_phys(page), addr,
184 page_to_pfn(page), 219 vma->vm_flags, pgprot_val(vma->vm_page_prot));
185 color_no,
186 addr,
187 vma->vm_flags,
188 pgprot_val(vma->vm_page_prot));
189 220
190 err = vm_insert_page(vma, addr, page); 221 err = vm_insert_page(vma, addr, page);
191 if (err) { 222 if (err) {
@@ -207,14 +238,14 @@ static int do_map_colored_pages(struct vm_area_struct *vma)
207 unsigned long nr_mapped; 238 unsigned long nr_mapped;
208 int i, err = 0; 239 int i, err = 0;
209 240
210 TRACE_CUR("allocating %lu pages (flags:%lx prot:%lx)\n",
211 nr_pages, vma->vm_flags, pgprot_val(vma->vm_page_prot));
212
213#ifdef CONFIG_PLUGIN_COLOR_UNCACHABLE 241#ifdef CONFIG_PLUGIN_COLOR_UNCACHABLE
214 /* Adds non-cached on x86 */ 242 /* Adds non-cached on x86 */
215 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); 243 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
216#endif 244#endif
217 245
246 TRACE_CUR("allocating %lu pages (flags:%lx prot:%lx)\n",
247 nr_pages, vma->vm_flags, pgprot_val(vma->vm_page_prot));
248
218 for (i = 0, nr_mapped = 0; nr_mapped < nr_pages; ++i) { 249 for (i = 0, nr_mapped = 0; nr_mapped < nr_pages; ++i) {
219 const unsigned long color_no = color_ctrl->colors[i]; 250 const unsigned long color_no = color_ctrl->colors[i];
220 const unsigned long color_quantity = color_ctrl->pages[i]; 251 const unsigned long color_quantity = color_ctrl->pages[i];
@@ -231,7 +262,7 @@ static int do_map_colored_pages(struct vm_area_struct *vma)
231 goto out; 262 goto out;
232 } 263 }
233 264
234 TRACE_CUR("addr: %lu nr_mapped: %lu color number: %lu " 265 TRACE_CUR("addr: 0x%10lx nr_mapped: %lu color number: %lu "
235 "color quantity: %lu\n", 266 "color quantity: %lu\n",
236 addr, nr_mapped, color_no, 267 addr, nr_mapped, color_no,
237 color_quantity); 268 color_quantity);
diff --git a/litmus/color_proc.c b/litmus/color_proc.c
index 78657bd4c7ac..8ee624860d71 100644
--- a/litmus/color_proc.c
+++ b/litmus/color_proc.c
@@ -50,6 +50,13 @@ static struct ctl_table cache_table[] =
50 .data = &color_cache_info.line_size, 50 .data = &color_cache_info.line_size,
51 .maxlen = sizeof(color_cache_info.line_size), 51 .maxlen = sizeof(color_cache_info.line_size),
52 }, 52 },
53 {
54 .procname = "nr_colors",
55 .mode = 0444,
56 .proc_handler = proc_doulongvec_minmax,
57 .data = &color_cache_info.nr_colors,
58 .maxlen = sizeof(color_cache_info.nr_colors),
59 },
53 { } 60 { }
54}; 61};
55 62
diff --git a/litmus/ctrldev.c b/litmus/ctrldev.c
index 07c3a680ca6b..87c216099646 100644
--- a/litmus/ctrldev.c
+++ b/litmus/ctrldev.c
@@ -19,8 +19,10 @@ static struct workqueue_struct *wq_litmus_dealloc;
19struct litmus_dealloc_work { 19struct litmus_dealloc_work {
20 struct work_struct work_struct; 20 struct work_struct work_struct;
21 void *ctrl_page_mem; 21 void *ctrl_page_mem;
22 void *color_ctrl_page_mem;
22#ifdef CONFIG_ARCH_NEEDS_UNCACHED_CONTROL_PAGE 23#ifdef CONFIG_ARCH_NEEDS_UNCACHED_CONTROL_PAGE
23 void *ctrl_page_unmap; 24 void *ctrl_page_unmap;
25 void *color_ctrl_page_unmap;
24#endif 26#endif
25}; 27};
26 28
@@ -31,10 +33,16 @@ static void litmus_dealloc(struct work_struct *work_in)
31#ifdef CONFIG_ARCH_NEEDS_UNCACHED_CONTROL_PAGE 33#ifdef CONFIG_ARCH_NEEDS_UNCACHED_CONTROL_PAGE
32 TRACE("vunmap() control page %p.\n", work->ctrl_page_unmap); 34 TRACE("vunmap() control page %p.\n", work->ctrl_page_unmap);
33 vunmap(work->ctrl_page_unmap); 35 vunmap(work->ctrl_page_unmap);
36
37 TRACE("vunmap() color control page %p.\n", work->color_ctrl_page_unmap);
38 vunmap(work->color_ctrl_page_unmap);
34#endif 39#endif
35 TRACE("freeing ctrl_page %p\n", work->ctrl_page_mem); 40 TRACE("freeing ctrl_page %p\n", work->ctrl_page_mem);
36 free_page((unsigned long) work->ctrl_page_mem); 41 free_page((unsigned long) work->ctrl_page_mem);
37 42
43 TRACE("freeing color_ctrl_page %p\n", work->color_ctrl_page_mem);
44 free_page((unsigned long) work->color_ctrl_page_mem);
45
38 kfree((void*) work); 46 kfree((void*) work);
39} 47}
40 48
@@ -42,7 +50,7 @@ void litmus_schedule_deallocation(struct task_struct *t)
42{ 50{
43 struct litmus_dealloc_work *work; 51 struct litmus_dealloc_work *work;
44 52
45 if (NULL == tsk_rt(t)->ctrl_page) 53 if (NULL == tsk_rt(t)->ctrl_page && NULL == tsk_rt(t)->color_ctrl_page)
46 return; 54 return;
47 55
48 work = kmalloc(sizeof(*work), GFP_ATOMIC); 56 work = kmalloc(sizeof(*work), GFP_ATOMIC);
@@ -56,8 +64,11 @@ void litmus_schedule_deallocation(struct task_struct *t)
56#ifdef CONFIG_ARCH_NEEDS_UNCACHED_CONTROL_PAGE 64#ifdef CONFIG_ARCH_NEEDS_UNCACHED_CONTROL_PAGE
57 work->ctrl_page_mem = tsk_rt(t)->ctrl_page_orig; 65 work->ctrl_page_mem = tsk_rt(t)->ctrl_page_orig;
58 work->ctrl_page_unmap = tsk_rt(t)->ctrl_page; 66 work->ctrl_page_unmap = tsk_rt(t)->ctrl_page;
67 work->color_ctrl_page_mem = tsk_rt(t)->color_ctrl_page_orig;
68 work->color_ctrl_page_unmap = tsk_rt(t)->color_ctrl_page;
59#else 69#else
60 work->ctrl_page_mem = tsk_rt(t)->ctrl_page; 70 work->ctrl_page_mem = tsk_rt(t)->ctrl_page;
71 work->color_ctrl_page_mem = tsk_rt(t)->color_ctrl_page;
61#endif 72#endif
62 queue_work(wq_litmus_dealloc, &work->work_struct); 73 queue_work(wq_litmus_dealloc, &work->work_struct);
63} 74}
@@ -71,7 +82,7 @@ void litmus_schedule_deallocation(struct task_struct *t)
71 * The caller should vunmap(addr) when the mapping is no longer needed. 82 * The caller should vunmap(addr) when the mapping is no longer needed.
72 * The caller should also save the original @addr to free it later. 83 * The caller should also save the original @addr to free it later.
73 */ 84 */
74static void * remap_noncached(void *addr, size_t len) 85void * remap_noncached(void *addr, size_t len)
75{ 86{
76 void *vaddr; 87 void *vaddr;
77 int nr_pages = DIV_ROUND_UP(offset_in_page(addr) + len, PAGE_SIZE); 88 int nr_pages = DIV_ROUND_UP(offset_in_page(addr) + len, PAGE_SIZE);
diff --git a/litmus/litmus.c b/litmus/litmus.c
index f8397898ce0a..1bbad8db1a55 100644
--- a/litmus/litmus.c
+++ b/litmus/litmus.c
@@ -393,7 +393,10 @@ static void reinit_litmus_state(struct task_struct* p, int restore)
393 void * ctrl_page_orig = NULL; 393 void * ctrl_page_orig = NULL;
394#endif 394#endif
395 395
396 void* color_ctrl_page = NULL; 396 void *color_ctrl_page = NULL;
397#ifdef CONFIG_ARCH_NEEDS_UNCACHED_CONTROL_PAGE
398 void *color_ctrl_page_orig = NULL;
399#endif
397 400
398 if (restore) { 401 if (restore) {
399 /* Safe user-space provided configuration data. 402 /* Safe user-space provided configuration data.
@@ -403,6 +406,7 @@ static void reinit_litmus_state(struct task_struct* p, int restore)
403 color_ctrl_page = p->rt_param.color_ctrl_page; 406 color_ctrl_page = p->rt_param.color_ctrl_page;
404#ifdef CONFIG_ARCH_NEEDS_UNCACHED_CONTROL_PAGE 407#ifdef CONFIG_ARCH_NEEDS_UNCACHED_CONTROL_PAGE
405 ctrl_page_orig = p->rt_param.ctrl_page_orig; 408 ctrl_page_orig = p->rt_param.ctrl_page_orig;
409 color_ctrl_page_orig = p->rt_param.color_ctrl_page_orig;
406#endif 410#endif
407 } 411 }
408 412
@@ -421,6 +425,7 @@ static void reinit_litmus_state(struct task_struct* p, int restore)
421 p->rt_param.color_ctrl_page = color_ctrl_page; 425 p->rt_param.color_ctrl_page = color_ctrl_page;
422#ifdef CONFIG_ARCH_NEEDS_UNCACHED_CONTROL_PAGE 426#ifdef CONFIG_ARCH_NEEDS_UNCACHED_CONTROL_PAGE
423 p->rt_param.ctrl_page_orig = ctrl_page_orig; 427 p->rt_param.ctrl_page_orig = ctrl_page_orig;
428 p->rt_param.color_ctrl_page_orig = color_ctrl_page_orig;
424#endif 429#endif
425 } 430 }
426} 431}
@@ -573,6 +578,7 @@ void litmus_fork(struct task_struct* p)
573 tsk_rt(p)->color_ctrl_page = NULL; 578 tsk_rt(p)->color_ctrl_page = NULL;
574#ifdef CONFIG_ARCH_NEEDS_UNCACHED_CONTROL_PAGE 579#ifdef CONFIG_ARCH_NEEDS_UNCACHED_CONTROL_PAGE
575 tsk_rt(p)->ctrl_page_orig = NULL; 580 tsk_rt(p)->ctrl_page_orig = NULL;
581 tsk_rt(p)->color_ctrl_page_orig = NULL;
576#endif 582#endif
577 } 583 }
578 584
@@ -590,14 +596,12 @@ void litmus_exec(void)
590 596
591 if (is_realtime(p)) { 597 if (is_realtime(p)) {
592 WARN_ON(p->rt_param.inh_task); 598 WARN_ON(p->rt_param.inh_task);
593 if (tsk_rt(p)->color_ctrl_page) {
594 free_page((unsigned long) tsk_rt(p)->color_ctrl_page);
595 tsk_rt(p)->color_ctrl_page = NULL;
596 }
597 litmus_schedule_deallocation(p); 599 litmus_schedule_deallocation(p);
598 tsk_rt(p)->ctrl_page = NULL; 600 tsk_rt(p)->ctrl_page = NULL;
601 tsk_rt(p)->color_ctrl_page = NULL;
599#ifdef CONFIG_ARCH_NEEDS_UNCACHED_CONTROL_PAGE 602#ifdef CONFIG_ARCH_NEEDS_UNCACHED_CONTROL_PAGE
600 tsk_rt(p)->ctrl_page_orig = NULL; 603 tsk_rt(p)->ctrl_page_orig = NULL;
604 tsk_rt(p)->color_ctrl_page_orig = NULL;
601#endif 605#endif
602 } 606 }
603} 607}
@@ -611,12 +615,6 @@ void exit_litmus(struct task_struct *dead_tsk)
611 * So check if we need to free the page 615 * So check if we need to free the page
612 * in any case. 616 * in any case.
613 */ 617 */
614 if (tsk_rt(dead_tsk)->color_ctrl_page) {
615 TRACE_TASK(dead_tsk,
616 "freeing color_ctrl_page %p\n",
617 tsk_rt(dead_tsk)->color_ctrl_page);
618 free_page((unsigned long) tsk_rt(dead_tsk)->color_ctrl_page);
619 }
620 618
621#ifdef CONFIG_PLUGIN_MC 619#ifdef CONFIG_PLUGIN_MC
622 /* The MC-setup syscall might succeed and allocate mc_data, but the 620 /* The MC-setup syscall might succeed and allocate mc_data, but the