aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChengYang Fu <chengyangfu@gmail.com>2015-03-02 15:56:14 -0500
committerChengYang Fu <chengyangfu@gmail.com>2015-03-02 15:56:14 -0500
commitdec614745fc38feed5f6032a336967e65cc5f007 (patch)
tree58171b45e6567261aae5f02213be6e32558817e8
parentb98917d2acc10c98d846a674ecb2443fb64206df (diff)
Add multiple interfaces for bank_proc.cchengyangfu
-rw-r--r--litmus/bank_proc.c185
1 files changed, 119 insertions, 66 deletions
diff --git a/litmus/bank_proc.c b/litmus/bank_proc.c
index ec04626b43ec..295c450bfbe2 100644
--- a/litmus/bank_proc.c
+++ b/litmus/bank_proc.c
@@ -1,3 +1,9 @@
1/*
2 * bank_proc.c -- Implementation of the page coloring for cache and bank partition.
3 * The file will keep a pool of colored pages. Users can require pages with
4 * specific color or bank number.
5 * Part of the code is modified from Jonathan Herman's code
6 */
1#include <linux/init.h> 7#include <linux/init.h>
2#include <linux/types.h> 8#include <linux/types.h>
3#include <linux/kernel.h> 9#include <linux/kernel.h>
@@ -14,16 +20,23 @@
14 20
15#define LITMUS_LOCKDEP_NAME_MAX_LEN 50 21#define LITMUS_LOCKDEP_NAME_MAX_LEN 50
16 22
17// This is Address Decoding for imx6-sabredsd board 23// This Address Decoding is used in imx6-sabredsd platform
18#define CACHE_MASK 0x0000f000 24#define CACHE_MASK 0x0000f000
19#define BANK_MASK 0x00007000 25#define BANK_MASK 0x00007000
20#define OFFSET_SHIFT 12 26#define OFFSET_SHIFT 12
21 27
22#define PAGES_PER_COLOR 1024 28#define PAGES_PER_COLOR 1024
23 29
30unsigned long used_cachecolor;
31unsigned long curr_cachecolor;
32
33
24unsigned long number_banks; 34unsigned long number_banks;
25unsigned long number_cachecolors; 35unsigned long number_cachecolors;
26 36
37/*
38 * Every page list should contain a lock, a list, and a number recording how many pages it store
39 */
27struct color_group { 40struct color_group {
28 spinlock_t lock; 41 spinlock_t lock;
29 char _lock_name[LITMUS_LOCKDEP_NAME_MAX_LEN]; 42 char _lock_name[LITMUS_LOCKDEP_NAME_MAX_LEN];
@@ -31,6 +44,10 @@ struct color_group {
31 atomic_t nr_pages; 44 atomic_t nr_pages;
32}; 45};
33 46
47/*
48 * This is old code which is not used in current version
49 */
50/*
34static struct alloced_pages { 51static struct alloced_pages {
35 spinlock_t lock; 52 spinlock_t lock;
36 struct list_head list; 53 struct list_head list;
@@ -41,6 +58,7 @@ struct alloced_page {
41 struct vm_area_struct *vma; 58 struct vm_area_struct *vma;
42 struct list_head list; 59 struct list_head list;
43}; 60};
61*/
44 62
45static struct color_group *color_groups; 63static struct color_group *color_groups;
46static struct lock_class_key color_lock_keys[16]; 64static struct lock_class_key color_lock_keys[16];
@@ -59,6 +77,9 @@ static inline unsigned long page_bank(struct page *page)
59 return ((page_to_phys(page)& BANK_MASK) >> PAGE_SHIFT); 77 return ((page_to_phys(page)& BANK_MASK) >> PAGE_SHIFT);
60} 78}
61 79
80/*
81 * It is used to determine the smallest number of page lists.
82 */
62static unsigned long smallest_nr_pages(void) 83static unsigned long smallest_nr_pages(void)
63{ 84{
64 unsigned long i, min_pages = -1; 85 unsigned long i, min_pages = -1;
@@ -70,8 +91,9 @@ static unsigned long smallest_nr_pages(void)
70 } 91 }
71 return min_pages; 92 return min_pages;
72} 93}
94
73/* 95/*
74 * Page's count should be one, it sould not be on any LRU list. 96 * Add a page to current pool.
75 */ 97 */
76void add_page_to_color_list(struct page *page) 98void add_page_to_color_list(struct page *page)
77{ 99{
@@ -82,10 +104,14 @@ void add_page_to_color_list(struct page *page)
82 spin_lock(&cgroup->lock); 104 spin_lock(&cgroup->lock);
83 list_add_tail(&page->lru, &cgroup->list); 105 list_add_tail(&page->lru, &cgroup->list);
84 atomic_inc(&cgroup->nr_pages); 106 atomic_inc(&cgroup->nr_pages);
85// SetPageLRU(page);
86 spin_unlock(&cgroup->lock); 107 spin_unlock(&cgroup->lock);
87} 108}
88 109
110/*
111 * Replenish the page pool.
112 * If the newly allocate page is what we want, it will be pushed to the correct page list
113 * otherwise, it will be freed.
114 */
89static int do_add_pages(void) 115static int do_add_pages(void)
90{ 116{
91 printk("LITMUS do add pages\n"); 117 printk("LITMUS do add pages\n");
@@ -95,9 +121,9 @@ static int do_add_pages(void)
95 unsigned long color; 121 unsigned long color;
96 int ret = 0; 122 int ret = 0;
97 123
124 // until all the page lists contain enough pages
98 while (smallest_nr_pages() < PAGES_PER_COLOR) { 125 while (smallest_nr_pages() < PAGES_PER_COLOR) {
99 126
100 //page = alloc_page(GFP_HIGHUSER | __GFP_MOVABLE);
101 page = alloc_page(GFP_HIGHUSER_MOVABLE); 127 page = alloc_page(GFP_HIGHUSER_MOVABLE);
102 128
103 if (unlikely(!page)) { 129 if (unlikely(!page)) {
@@ -107,24 +133,63 @@ static int do_add_pages(void)
107 } 133 }
108 color = page_color(page); 134 color = page_color(page);
109 if (atomic_read(&color_groups[color].nr_pages) < PAGES_PER_COLOR) { 135 if (atomic_read(&color_groups[color].nr_pages) < PAGES_PER_COLOR) {
110 // SetPageReserved(page);
111 add_page_to_color_list(page); 136 add_page_to_color_list(page);
112 } else 137 } else{
138 // Pages here will be freed later
113 list_add_tail(&page->lru, &free_later); 139 list_add_tail(&page->lru, &free_later);
140 }
114 } 141 }
142 // Free the unwanted pages
115 list_for_each_entry_safe(page, page_tmp, &free_later, lru) { 143 list_for_each_entry_safe(page, page_tmp, &free_later, lru) {
116 list_del(&page->lru); 144 list_del(&page->lru);
117 __free_page(page); 145 __free_page(page);
118 } 146 }
119 /* setup the color queue stuff */
120// ret = setup_flusher_array();
121out: 147out:
122 return ret; 148 return ret;
123} 149}
124 150
151/*
152 * Provide pages for replacement according cache color
153 * This should be the only implementation here
154 * This function should not be accessed by others directly.
155 *
156 */
157static struct page *new_alloc_page_color( unsigned long color)
158{
159 printk("allocate new page color = %d\n", color);
160 struct color_group *cgroup;
161 struct page *rPage = NULL;
162
163 if( (color <0) || (color)>15) {
164 TRACE_CUR("Wrong color %lu\n", color);
165 printk(KERN_WARNING "Wrong color %lu\n", color);
166 goto out_unlock;
167 }
168
169
170 cgroup = &color_groups[color];
171 spin_lock(&cgroup->lock);
172 if (unlikely(!atomic_read(&cgroup->nr_pages))) {
173 TRACE_CUR("No free %lu colored pages.\n", color);
174 printk(KERN_WARNING "no free %lu colored pages.\n", color);
175 goto out_unlock;
176 }
177 rPage = list_first_entry(&cgroup->list, struct page, lru);
178 BUG_ON(page_count(rPage) > 1);
179 get_page(rPage);
180 list_del(&rPage->lru);
181 atomic_dec(&cgroup->nr_pages);
182// ClearPageLRU(rPage);
183out_unlock:
184 spin_unlock(&cgroup->lock);
185out:
186 do_add_pages();
187 return rPage;
188}
189
125 190
126/* 191/*
127 * provide pages for replacement 192 * provide pages for replacement according to
128 * node = 0 for Level A, B tasks in Cpu 0 193 * node = 0 for Level A, B tasks in Cpu 0
129 * node = 1 for Level A, B tasks in Cpu 1 194 * node = 1 for Level A, B tasks in Cpu 1
130 * node = 2 for Level A, B tasks in Cpu 2 195 * node = 2 for Level A, B tasks in Cpu 2
@@ -140,22 +205,7 @@ struct page *new_alloc_page(struct page *page, unsigned long node, int **x)
140 unsigned int color; 205 unsigned int color;
141 get_random_bytes(&color, sizeof(unsigned int)); 206 get_random_bytes(&color, sizeof(unsigned int));
142 207
143 /* 208 // Decode the node to decide what color pages we should provide
144 if(node ==0){
145 color = (color%2)*8+node;
146 }else if(node == 1){
147 color = (color%2)*8+node;
148 }else if(node == 2){
149 color = (color%2)*8+;
150 }else if(node == 3){
151 color = color%2 + 6;
152 }else if(node == 4){
153 color = color%8 + 8;
154 }else{
155 goto out;
156 }
157 */
158
159 switch(node ){ 209 switch(node ){
160 case 0: 210 case 0:
161 case 1: 211 case 1:
@@ -169,32 +219,22 @@ struct page *new_alloc_page(struct page *page, unsigned long node, int **x)
169 color+=4; 219 color+=4;
170 break; 220 break;
171 default: 221 default:
172 goto out; 222 TRACE_CUR("Wrong color %lu\n", color);
223 printk(KERN_WARNING "Wrong color %lu\n", color);
224 return rPage;
173 } 225 }
174 226
175 227
176 printk("allocate new page color = %d\n", color); 228 printk("allocate new page color = %d\n", color);
177 229
178 cgroup = &color_groups[color]; 230 rPage = new_alloc_page_color(color);
179 spin_lock(&cgroup->lock); 231 return rPage;
180 if (unlikely(!atomic_read(&cgroup->nr_pages))) {
181 TRACE_CUR("No free %lu colored pages.\n", color);
182 printk(KERN_WARNING "no free %lu colored pages.\n", color);
183 goto out_unlock;
184 }
185 rPage = list_first_entry(&cgroup->list, struct page, lru);
186 BUG_ON(page_count(rPage) > 1);
187 get_page(rPage);
188 list_del(&rPage->lru);
189 atomic_dec(&cgroup->nr_pages);
190// ClearPageLRU(rPage);
191out_unlock:
192 spin_unlock(&cgroup->lock);
193out:
194 do_add_pages();
195 return rPage;
196} 232}
197 233
234/*
235 * Provide pages for replacement according to bank number.
236 * This is used in cache way partition
237 */
198struct page *new_alloc_page_banknr(struct page *page, unsigned long banknr, int **x) 238struct page *new_alloc_page_banknr(struct page *page, unsigned long banknr, int **x)
199{ 239{
200 printk("allocate new page bank = %d\n", banknr); 240 printk("allocate new page bank = %d\n", banknr);
@@ -208,30 +248,43 @@ struct page *new_alloc_page_banknr(struct page *page, unsigned long banknr, int
208 }else{ 248 }else{
209 goto out; 249 goto out;
210 } 250 }
251
252 rPage = new_alloc_page_color(color);
211 253
212 cgroup = &color_groups[color];
213 spin_lock(&cgroup->lock);
214 if (unlikely(!atomic_read(&cgroup->nr_pages))) {
215 TRACE_CUR("No free %lu colored pages.\n", color);
216 printk(KERN_WARNING "no free %lu colored pages.\n", color);
217 goto out_unlock;
218 }
219 rPage = list_first_entry(&cgroup->list, struct page, lru);
220 BUG_ON(page_count(rPage) > 1);
221 get_page(rPage);
222 list_del(&rPage->lru);
223 atomic_dec(&cgroup->nr_pages);
224// ClearPageLRU(rPage);
225out_unlock:
226 spin_unlock(&cgroup->lock);
227out: 254out:
228 do_add_pages();
229 return rPage; 255 return rPage;
256}
257
230 258
259void set_number_of_colors(unsigned long colornr)
260{
261 used_cachecolor = colornr ;
262 curr_cachecolor = 0;
263}
231 264
232 265
266/*
267 * Provide pages for replacement
268 * This is used to generate experiments
269 */
270struct page *new_alloc_page_predefined(struct page *page, int **x)
271{
272 unsigned int color = curr_cachecolor;
273
274 printk("allocate new page color = %d\n", color);
275 struct color_group *cgroup;
276 struct page *rPage = NULL;
277
278 rPage = new_alloc_page_color(color);
279 color = (color + 1)% used_cachecolor;
280out:
281 return rPage;
233} 282}
234 283
284
285/*
286 * Initialize the numbers of banks and cache colors
287 */
235static int __init init_variables(void) 288static int __init init_variables(void)
236{ 289{
237 number_banks = 1+(BANK_MASK >> PAGE_SHIFT); 290 number_banks = 1+(BANK_MASK >> PAGE_SHIFT);
@@ -239,7 +292,9 @@ static int __init init_variables(void)
239} 292}
240 293
241 294
242 295/*
296 * Initialize the page pool
297 */
243static int __init init_color_groups(void) 298static int __init init_color_groups(void)
244{ 299{
245 struct color_group *cgroup; 300 struct color_group *cgroup;
@@ -258,22 +313,20 @@ static int __init init_color_groups(void)
258 atomic_set(&cgroup->nr_pages, 0); 313 atomic_set(&cgroup->nr_pages, 0);
259 INIT_LIST_HEAD(&cgroup->list); 314 INIT_LIST_HEAD(&cgroup->list);
260 spin_lock_init(&cgroup->lock); 315 spin_lock_init(&cgroup->lock);
261// LOCKDEP_DYNAMIC_ALLOC(&cgroup->lock, &color_lock_keys[i],
262// cgroup->_lock_name, "color%lu", i);
263 } 316 }
264 } 317 }
265 return err; 318 return err;
266} 319}
267 320
268/* 321/*
269 * Initialzie the this proc 322 * Initialzie this proc
270 */ 323 */
271static int __init litmus_color_init(void) 324static int __init litmus_color_init(void)
272{ 325{
273 int err=0; 326 int err=0;
274 327
275 INIT_LIST_HEAD(&alloced_pages.list); 328 //INIT_LIST_HEAD(&alloced_pages.list);
276 spin_lock_init(&alloced_pages.lock); 329 //spin_lock_init(&alloced_pages.lock);
277 init_variables(); 330 init_variables();
278 printk("Cache number = %d , Cache mask = 0x%lx\n", number_cachecolors, CACHE_MASK); 331 printk("Cache number = %d , Cache mask = 0x%lx\n", number_cachecolors, CACHE_MASK);
279 printk("Bank number = %d , Bank mask = 0x%lx\n", number_banks, BANK_MASK); 332 printk("Bank number = %d , Bank mask = 0x%lx\n", number_banks, BANK_MASK);