aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2012-10-12 01:54:33 -0400
committerJonathan Herman <hermanjl@cs.unc.edu>2012-10-12 01:54:33 -0400
commitbc4e46db66fc4470806f570d02982eedae140c4c (patch)
tree297d453ca325a700d0989b0a45f53733f64e8043
parentfbbd0ae9f4589d35265a9b85e5b2e4614b432525 (diff)
parent592f6c45ea37e2d76ba3e34c31e55070ce00966c (diff)
Merge branch 'wip-mc' of ssh://rtsrv.cs.unc.edu/home/litmus/litmus-rt into wip-mc
-rw-r--r--arch/arm/include/asm/glue-cache.h16
-rw-r--r--arch/arm/include/asm/hardware/cache-l2x0.h9
-rw-r--r--arch/arm/mm/cache-l2x0.c21
-rw-r--r--include/litmus/color.h9
-rw-r--r--include/litmus/fpmath.h4
-rw-r--r--include/litmus/litmus.h4
-rw-r--r--include/litmus/rt_param.h3
-rw-r--r--include/litmus/trace_irq.h1
-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
13 files changed, 134 insertions, 42 deletions
diff --git a/arch/arm/include/asm/glue-cache.h b/arch/arm/include/asm/glue-cache.h
index 7e30874377e..4f8d2c0dc44 100644
--- a/arch/arm/include/asm/glue-cache.h
+++ b/arch/arm/include/asm/glue-cache.h
@@ -110,19 +110,19 @@
110#endif 110#endif
111 111
112#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) 112#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K)
113//# ifdef _CACHE 113# ifdef _CACHE
114# define MULTI_CACHE 1 114# define MULTI_CACHE 1
115//# else 115# else
116//# define _CACHE v6 116# define _CACHE v6
117//# endif 117# endif
118#endif 118#endif
119 119
120#if defined(CONFIG_CPU_V7) 120#if defined(CONFIG_CPU_V7)
121//# ifdef _CACHE 121# ifdef _CACHE
122# define MULTI_CACHE 1 122# define MULTI_CACHE 1
123//# else 123# else
124//# define _CACHE v7 124# define _CACHE v7
125//# endif 125# endif
126#endif 126#endif
127 127
128#if !defined(_CACHE) && !defined(MULTI_CACHE) 128#if !defined(_CACHE) && !defined(MULTI_CACHE)
diff --git a/arch/arm/include/asm/hardware/cache-l2x0.h b/arch/arm/include/asm/hardware/cache-l2x0.h
index 16bd4803158..9e2fd1889b6 100644
--- a/arch/arm/include/asm/hardware/cache-l2x0.h
+++ b/arch/arm/include/asm/hardware/cache-l2x0.h
@@ -45,8 +45,13 @@
45#define L2X0_CLEAN_INV_LINE_PA 0x7F0 45#define L2X0_CLEAN_INV_LINE_PA 0x7F0
46#define L2X0_CLEAN_INV_LINE_IDX 0x7F8 46#define L2X0_CLEAN_INV_LINE_IDX 0x7F8
47#define L2X0_CLEAN_INV_WAY 0x7FC 47#define L2X0_CLEAN_INV_WAY 0x7FC
48#define L2X0_LOCKDOWN_WAY_D 0x900 48/*
49#define L2X0_LOCKDOWN_WAY_I 0x904 49 * The lockdown registers repeat 8 times for L310, the L210 has only one
50 * D and one I lockdown register at 0x0900 and 0x0904.
51 */
52#define L2X0_LOCKDOWN_WAY_D_BASE 0x900
53#define L2X0_LOCKDOWN_WAY_I_BASE 0x904
54#define L2X0_LOCKDOWN_STRIDE 0x08
50#define L2X0_TEST_OPERATION 0xF00 55#define L2X0_TEST_OPERATION 0xF00
51#define L2X0_LINE_DATA 0xF10 56#define L2X0_LINE_DATA 0xF10
52#define L2X0_LINE_TAG 0xF30 57#define L2X0_LINE_TAG 0xF30
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 83a9c076931..4f98e8e0783 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -279,6 +279,25 @@ static void l2x0_disable(void)
279 spin_unlock_irqrestore(&l2x0_lock, flags); 279 spin_unlock_irqrestore(&l2x0_lock, flags);
280} 280}
281 281
282static void __init l2x0_unlock(__u32 cache_id)
283{
284 int lockregs;
285 int i;
286
287 if (cache_id == L2X0_CACHE_ID_PART_L310)
288 lockregs = 8;
289 else
290 /* L210 and unknown types */
291 lockregs = 1;
292
293 for (i = 0; i < lockregs; i++) {
294 writel_relaxed(0x0, l2x0_base + L2X0_LOCKDOWN_WAY_D_BASE +
295 i * L2X0_LOCKDOWN_STRIDE);
296 writel_relaxed(0x0, l2x0_base + L2X0_LOCKDOWN_WAY_I_BASE +
297 i * L2X0_LOCKDOWN_STRIDE);
298 }
299}
300
282void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask) 301void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
283{ 302{
284 __u32 aux; 303 __u32 aux;
@@ -330,6 +349,8 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
330 * accessing the below registers will fault. 349 * accessing the below registers will fault.
331 */ 350 */
332 if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & 1)) { 351 if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & 1)) {
352 /* Make sure that I&D is not locked down when starting */
353 l2x0_unlock(l2x0_cache_id);
333 354
334 /* l2x0 controller is disabled */ 355 /* l2x0 controller is disabled */
335 writel_relaxed(aux, l2x0_base + L2X0_AUX_CTRL); 356 writel_relaxed(aux, l2x0_base + L2X0_AUX_CTRL);
diff --git a/include/litmus/color.h b/include/litmus/color.h
index eefb6c6dddf..615ebd80703 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;
@@ -18,6 +24,9 @@ struct color_cache_info {
18extern struct color_cache_info color_cache_info; 24extern struct color_cache_info color_cache_info;
19extern unsigned long color_chunk; 25extern unsigned long color_chunk;
20 26
27struct vm_area_struct;
28struct ctl_table;
29
21struct page* get_colored_page(unsigned long); 30struct page* get_colored_page(unsigned long);
22void add_page_to_color_list(struct page*); 31void add_page_to_color_list(struct page*);
23void add_page_to_alloced_list(struct page*, struct vm_area_struct*); 32void add_page_to_alloced_list(struct page*, struct vm_area_struct*);
diff --git a/include/litmus/fpmath.h b/include/litmus/fpmath.h
index 04d4bcaeae9..642de98542c 100644
--- a/include/litmus/fpmath.h
+++ b/include/litmus/fpmath.h
@@ -1,6 +1,8 @@
1#ifndef __FP_MATH_H__ 1#ifndef __FP_MATH_H__
2#define __FP_MATH_H__ 2#define __FP_MATH_H__
3 3
4#include <linux/math64.h>
5
4#ifndef __KERNEL__ 6#ifndef __KERNEL__
5#include <stdint.h> 7#include <stdint.h>
6#define abs(x) (((x) < 0) ? -(x) : x) 8#define abs(x) (((x) < 0) ? -(x) : x)
@@ -32,7 +34,7 @@ static inline fp_t FP(fpbuf_t x)
32/* divide two integers to obtain a fixed point value */ 34/* divide two integers to obtain a fixed point value */
33static inline fp_t _frac(fpbuf_t a, fpbuf_t b) 35static inline fp_t _frac(fpbuf_t a, fpbuf_t b)
34{ 36{
35 return _fp(FP(a).val / (b)); 37 return _fp(div64_s64(FP(a).val, (b)));
36} 38}
37 39
38static inline fpbuf_t _point(fp_t x) 40static inline fpbuf_t _point(fp_t x)
diff --git a/include/litmus/litmus.h b/include/litmus/litmus.h
index a78f7f94344..b273618fb83 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 1ee65e19d7b..e9e26faddce 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/include/litmus/trace_irq.h b/include/litmus/trace_irq.h
index b717b1d5539..01e4b98fc3e 100644
--- a/include/litmus/trace_irq.h
+++ b/include/litmus/trace_irq.h
@@ -3,6 +3,7 @@
3 3
4#ifdef CONFIG_SCHED_OVERHEAD_TRACE 4#ifdef CONFIG_SCHED_OVERHEAD_TRACE
5 5
6#include <asm/atomic.h>
6#include <linux/percpu.h> 7#include <linux/percpu.h>
7 8
8extern DEFINE_PER_CPU(atomic_t, irq_fired_count); 9extern DEFINE_PER_CPU(atomic_t, irq_fired_count);
diff --git a/litmus/color.c b/litmus/color.c
index b2834b36939..976366e7e39 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 3ed584ad7af..6287d14405e 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 78657bd4c7a..8ee624860d7 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 07c3a680ca6..87c21609964 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 f8397898ce0..1bbad8db1a5 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