aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNamhoon Kim <namhoonk@cs.unc.edu>2017-05-17 13:27:24 -0400
committerNamhoon Kim <namhoonk@cs.unc.edu>2017-05-17 13:27:24 -0400
commitfa0a28ee893e8e698263b0bbddee8d541d4c86a6 (patch)
treed173c5d8e35c88d8f96786ce06e9ca11d207b1bc
parent66efd4423f46259c73f25ff36b35bf69b48ae30b (diff)
bank_proc patch
-rw-r--r--litmus/bank_proc.c250
1 files changed, 150 insertions, 100 deletions
diff --git a/litmus/bank_proc.c b/litmus/bank_proc.c
index 2fac8d06f242..097cff177a2d 100644
--- a/litmus/bank_proc.c
+++ b/litmus/bank_proc.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * bank_proc.c -- Implementation of the page coloring for cache and bank partition. 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 3 * The file will keep a pool of colored pages. Users can require pages with
4 * specific color or bank number. 4 * specific color or bank number.
5 * Part of the code is modified from Jonathan Herman's code 5 * Part of the code is modified from Jonathan Herman's code
6 */ 6 */
7#include <linux/init.h> 7#include <linux/init.h>
@@ -24,12 +24,13 @@
24// This Address Decoding is used in imx6-sabredsd platform 24// This Address Decoding is used in imx6-sabredsd platform
25#define BANK_MASK 0x38000000 25#define BANK_MASK 0x38000000
26#define BANK_SHIFT 27 26#define BANK_SHIFT 27
27
28#define CACHE_MASK 0x0000f000 27#define CACHE_MASK 0x0000f000
29#define CACHE_SHIFT 12 28#define CACHE_SHIFT 12
30 29
31#define PAGES_PER_COLOR 2000 30#define PAGES_PER_COLOR 2000
32#define PAGES_PER_COLOR_HALF 1000 31#define NUM_BANKS 8
32#define NUM_COLORS 16
33
33unsigned int NUM_PAGE_LIST; //8*16 34unsigned int NUM_PAGE_LIST; //8*16
34 35
35unsigned int number_banks; 36unsigned int number_banks;
@@ -45,15 +46,15 @@ int refill_page_pool = 0;
45spinlock_t reclaim_lock; 46spinlock_t reclaim_lock;
46 47
47unsigned int set_partition[9] = { 48unsigned int set_partition[9] = {
48 0x0000000f, /* Core 0, and Level A*/ 49 0x00000003, /* Core 0, and Level A*/
49 0x0000000f, /* Core 0, and Level B*/ 50 0x00000003, /* Core 0, and Level B*/
50 0x000000f0, /* Core 1, and Level A*/ 51 0x0000000C, /* Core 1, and Level A*/
51 0x000000f0, /* Core 1, and Level B*/ 52 0x0000000C, /* Core 1, and Level B*/
52 0x00000f00, /* Core 2, and Level A*/ 53 0x00000030, /* Core 2, and Level A*/
53 0x00000f00, /* Core 2, and Level B*/ 54 0x00000030, /* Core 2, and Level B*/
54 0x0000f000, /* Core 3, and Level A*/ 55 0x000000C0, /* Core 3, and Level A*/
55 0x0000f000, /* Core 3, and Level B*/ 56 0x000000C0, /* Core 3, and Level B*/
56 0x0000ffff, /* Level C */ 57 0x0000ff00, /* Level C */
57}; 58};
58 59
59unsigned int bank_partition[9] = { 60unsigned int bank_partition[9] = {
@@ -76,8 +77,11 @@ unsigned int bank_index[9] = {
76 0, 0, 0, 0, 0, 0, 0, 0, 0 77 0, 0, 0, 0, 0, 0, 0, 0, 0
77}; 78};
78 79
79struct mutex void_lockdown_proc; 80int node_index[9] = {
81 -1, -1, -1, -1, -1, -1, -1, -1, -1
82};
80 83
84struct mutex void_lockdown_proc;
81 85
82/* 86/*
83 * Every page list should contain a lock, a list, and a number recording how many pages it store 87 * Every page list should contain a lock, a list, and a number recording how many pages it store
@@ -97,7 +101,6 @@ static struct color_group *color_groups;
97 */ 101 */
98unsigned int counting_one_set(unsigned int v) 102unsigned int counting_one_set(unsigned int v)
99{ 103{
100// unsigned int v; // count the number of bits set in v
101 unsigned int c; // c accumulates the total bits set in v 104 unsigned int c; // c accumulates the total bits set in v
102 105
103 for (c = 0; v; v >>= 1) 106 for (c = 0; v; v >>= 1)
@@ -137,7 +140,101 @@ unsigned int num_by_bitmask_index(unsigned int bitmask, unsigned int index)
137 return pos; 140 return pos;
138} 141}
139 142
143/* helper functions to find the next colored pool index */
144static inline unsigned int first_index(unsigned long node)
145{
146 unsigned int bank_no = 0, color_no = 0;
147
148 while(bank_no < NUM_BANKS) {
149 if ((bank_partition[node]>>bank_no) & 0x1)
150 break;
151 bank_no++;
152 }
153 while(color_no < NUM_COLORS) {
154 if ((set_partition[node]>>color_no) & 0x1)
155 break;
156 color_no++;
157 }
158 return NUM_COLORS*bank_no + color_no;
159}
160
161static inline unsigned int last_index(unsigned long node)
162{
163 unsigned int bank_no = 7, color_no = 15;
164
165 while(bank_no >= 0) {
166 if ((bank_partition[node]>>bank_no) & 0x1)
167 break;
168 bank_no--;
169 }
170 while(color_no >= 0) {
171 if ((set_partition[node]>>color_no) & 0x1)
172 break;
173 color_no--;
174 }
175 return NUM_COLORS*bank_no + color_no;
176}
140 177
178static inline unsigned int next_color(unsigned long node, unsigned int current_color)
179{
180 int try = 0, ret = 0;
181 current_color++;
182 if (current_color == NUM_COLORS) {
183 current_color = 0;
184 ret = 1;
185 }
186
187 while (try < NUM_COLORS) {
188 if ((set_partition[node]>>current_color)&0x1)
189 break;
190 current_color++;
191 if (current_color == NUM_COLORS) {
192 current_color = 0;
193 ret = 1;
194 }
195 try++;
196 }
197 if (!ret)
198 return current_color;
199 else
200 return current_color + NUM_COLORS;
201}
202
203static inline unsigned int next_bank(unsigned long node, unsigned int current_bank)
204{
205 int try = 0;
206 current_bank++;
207 if (current_bank == NUM_BANKS) {
208 current_bank = 0;
209 }
210
211 while (try < NUM_BANKS) {
212 if ((bank_partition[node]>>current_bank)&0x1)
213 break;
214 current_bank++;
215 if (current_bank == NUM_BANKS) {
216 current_bank = 0;
217 }
218 try++;
219 }
220 return current_bank;
221}
222
223static inline unsigned int get_next_index(unsigned long node, unsigned int current_index)
224{
225 unsigned int bank_no, color_no, color_ret, bank_ret;
226 bank_no = current_index>>4; // 2^4 = 16 colors
227 color_no = current_index - bank_no*NUM_COLORS;
228 bank_ret = bank_no;
229 color_ret = next_color(node, color_no);
230 if (color_ret >= NUM_COLORS) {
231 // next bank
232 color_ret -= NUM_COLORS;
233 bank_ret = next_bank(node, bank_no);
234 }
235
236 return bank_ret * NUM_COLORS + color_ret;
237}
141 238
142/* Decoding page color, 0~15 */ 239/* Decoding page color, 0~15 */
143static inline unsigned int page_color(struct page *page) 240static inline unsigned int page_color(struct page *page)
@@ -155,8 +252,6 @@ static inline unsigned int page_list_index(struct page *page)
155{ 252{
156 unsigned int idx; 253 unsigned int idx;
157 idx = (page_color(page) + page_bank(page)*(number_cachecolors)); 254 idx = (page_color(page) + page_bank(page)*(number_cachecolors));
158// printk("address = %lx, ", page_to_phys(page));
159// printk("color(%d), bank(%d), indx = %d\n", page_color(page), page_bank(page), idx);
160 255
161 return idx; 256 return idx;
162} 257}
@@ -187,10 +282,10 @@ static void show_nr_pages(void)
187 printk("show nr pages***************************************\n"); 282 printk("show nr pages***************************************\n");
188 for (i = 0; i < NUM_PAGE_LIST; ++i) { 283 for (i = 0; i < NUM_PAGE_LIST; ++i) {
189 cgroup = &color_groups[i]; 284 cgroup = &color_groups[i];
190 printk("(%03d) = %03d, ", i, atomic_read(&cgroup->nr_pages)); 285 printk("(%03ld) = %03d, ", i, atomic_read(&cgroup->nr_pages));
191 if((i % 8) ==7){ 286 if((i % 8) ==7) {
192 printk("\n"); 287 printk("\n");
193 } 288 }
194 } 289 }
195} 290}
196 291
@@ -214,11 +309,10 @@ void add_page_to_color_list(struct page *page)
214 * Replenish the page pool. 309 * Replenish the page pool.
215 * If the newly allocate page is what we want, it will be pushed to the correct page list 310 * If the newly allocate page is what we want, it will be pushed to the correct page list
216 * otherwise, it will be freed. 311 * otherwise, it will be freed.
312 * A user needs to invoke this function until the page pool has enough pages.
217 */ 313 */
218static int do_add_pages(void) 314static int do_add_pages(void)
219{ 315{
220 //printk("LITMUS do add pages\n");
221
222 struct page *page, *page_tmp; 316 struct page *page, *page_tmp;
223 LIST_HEAD(free_later); 317 LIST_HEAD(free_later);
224 unsigned long color; 318 unsigned long color;
@@ -227,16 +321,9 @@ static int do_add_pages(void)
227 int free_counter = 0; 321 int free_counter = 0;
228 unsigned long counter[128]= {0}; 322 unsigned long counter[128]= {0};
229 323
230 //printk("Before refill : \n");
231 //show_nr_pages();
232
233 // until all the page lists contain enough pages 324 // until all the page lists contain enough pages
234 //for (i =0; i<5; i++) { 325 for (i=0; i< 1024*20;i++) {
235 for (i=0; i< 1024*100;i++) {
236 //while (smallest_nr_pages() < PAGES_PER_COLOR) {
237 // printk("smallest = %d\n", smallest_nr_pages());
238 page = alloc_page(GFP_HIGHUSER_MOVABLE); 326 page = alloc_page(GFP_HIGHUSER_MOVABLE);
239 // page = alloc_pages_exact_node(0, GFP_HIGHUSER_MOVABLE, 0);
240 327
241 if (unlikely(!page)) { 328 if (unlikely(!page)) {
242 printk(KERN_WARNING "Could not allocate pages.\n"); 329 printk(KERN_WARNING "Could not allocate pages.\n");
@@ -245,57 +332,20 @@ static int do_add_pages(void)
245 } 332 }
246 color = page_list_index(page); 333 color = page_list_index(page);
247 counter[color]++; 334 counter[color]++;
248 // printk("page(%d) = color %x, bank %x, [color] =%d \n", color, page_color(page), page_bank(page), atomic_read(&color_groups[color].nr_pages)); 335 if (atomic_read(&color_groups[color].nr_pages) < PAGES_PER_COLOR && color>=0) {
249 //show_nr_pages();
250 //if (atomic_read(&color_groups[color].nr_pages) < PAGES_PER_COLOR && color>=32) {
251 //if (atomic_read(&color_groups[color].nr_pages) < PAGES_PER_COLOR) {
252 //if ( PAGES_PER_COLOR && color>=16*2) {
253 //if (color>=32) {
254 if (color>=16) {
255 add_page_to_color_list(page); 336 add_page_to_color_list(page);
256 // printk("add page(%d) = color %x, bank %x\n", color, page_color(page), page_bank(page)); 337 } else {
257 } else{
258 // Pages here will be freed later 338 // Pages here will be freed later
259 list_add_tail(&page->lru, &free_later); 339 list_add_tail(&page->lru, &free_later);
260 free_counter++; 340 free_counter++;
261 //list_del(&page->lru);
262 // __free_page(page);
263 // printk("useless page(%d) = color %x, bank %x\n", color, page_color(page), page_bank(page));
264 } 341 }
265 //show_nr_pages(); 342 }
266 /*
267 if(free_counter >= PAGES_PER_COLOR)
268 {
269 printk("free unwanted page list eariler");
270 free_counter = 0;
271 list_for_each_entry_safe(page, page_tmp, &free_later, lru) {
272 list_del(&page->lru);
273 __free_page(page);
274 }
275
276 show_nr_pages();
277 }
278 */
279 }
280/* printk("page counter = \n");
281 for (i=0; i<128; i++)
282 {
283 printk("(%03d) = %4d, ", i , counter[i]);
284 if(i%8 == 7){
285 printk("\n");
286 }
287 343
288 }
289*/
290 //printk("After refill : \n");
291 //show_nr_pages();
292#if 1
293 // Free the unwanted pages 344 // Free the unwanted pages
294 list_for_each_entry_safe(page, page_tmp, &free_later, lru) { 345 list_for_each_entry_safe(page, page_tmp, &free_later, lru) {
295 list_del(&page->lru); 346 list_del(&page->lru);
296 __free_page(page); 347 __free_page(page);
297 } 348 }
298#endif
299out: 349out:
300 return ret; 350 return ret;
301} 351}
@@ -306,7 +356,7 @@ out:
306 * This function should not be accessed by others directly. 356 * This function should not be accessed by others directly.
307 * 357 *
308 */ 358 */
309static struct page *new_alloc_page_color( unsigned long color, int do_refill) 359static struct page *new_alloc_page_color( unsigned long color)
310{ 360{
311// printk("allocate new page color = %d\n", color); 361// printk("allocate new page color = %d\n", color);
312 struct color_group *cgroup; 362 struct color_group *cgroup;
@@ -314,7 +364,6 @@ static struct page *new_alloc_page_color( unsigned long color, int do_refill)
314 364
315 if( (color <0) || (color)>(number_cachecolors*number_banks -1)) { 365 if( (color <0) || (color)>(number_cachecolors*number_banks -1)) {
316 TRACE_CUR("Wrong color %lu\n", color); 366 TRACE_CUR("Wrong color %lu\n", color);
317// printk(KERN_WARNING "Wrong color %lu\n", color);
318 goto out; 367 goto out;
319 } 368 }
320 369
@@ -323,7 +372,6 @@ static struct page *new_alloc_page_color( unsigned long color, int do_refill)
323 spin_lock(&cgroup->lock); 372 spin_lock(&cgroup->lock);
324 if (unlikely(!atomic_read(&cgroup->nr_pages))) { 373 if (unlikely(!atomic_read(&cgroup->nr_pages))) {
325 TRACE_CUR("No free %lu colored pages.\n", color); 374 TRACE_CUR("No free %lu colored pages.\n", color);
326// printk(KERN_WARNING "no free %lu colored pages.\n", color);
327 goto out_unlock; 375 goto out_unlock;
328 } 376 }
329 rPage = list_first_entry(&cgroup->list, struct page, lru); 377 rPage = list_first_entry(&cgroup->list, struct page, lru);
@@ -335,19 +383,12 @@ static struct page *new_alloc_page_color( unsigned long color, int do_refill)
335out_unlock: 383out_unlock:
336 spin_unlock(&cgroup->lock); 384 spin_unlock(&cgroup->lock);
337out: 385out:
338 if( smallest_nr_pages() == 0 && do_refill == 1)
339 {
340 do_add_pages();
341 // printk("ERROR(bank_proc.c) = We don't have enough pages in bank_proc.c\n");
342
343 }
344
345 return rPage; 386 return rPage;
346} 387}
347 388
348struct page* get_colored_page(unsigned long color) 389struct page* get_colored_page(unsigned long color)
349{ 390{
350 return new_alloc_page_color(color, 1); 391 return new_alloc_page_color(color);
351} 392}
352 393
353/* 394/*
@@ -364,23 +405,32 @@ struct page* get_colored_page(unsigned long color)
364 */ 405 */
365struct page *new_alloc_page(struct page *page, unsigned long node, int **x) 406struct page *new_alloc_page(struct page *page, unsigned long node, int **x)
366{ 407{
367// printk("allocate new page node = %d\n", node);
368// return alloc_pages_exact_node(node, GFP_HIGHUSER_MOVABLE, 0);
369 struct color_group *cgroup;
370 struct page *rPage = NULL; 408 struct page *rPage = NULL;
371 unsigned int color; 409 int try = 0;
410 unsigned int idx;
372 411
373 412 if (node_index[node] == -1)
374 unsigned int idx = 0; 413 idx = first_index(node);
375 do { 414 else
376 idx += num_by_bitmask_index(set_partition[node], set_index[node]); 415 idx = node_index[node];
377 idx += number_cachecolors* num_by_bitmask_index(bank_partition[node], bank_index[node]); 416
378 rPage = new_alloc_page_color(idx, 0); 417 BUG_ON(idx<0 || idx>127);
379 } while (rPage == NULL); 418 rPage = new_alloc_page_color(idx);
380 419 if (node_index[node] == last_index(node))
381 420 node_index[node] = first_index(node);
382 set_index[node] = (set_index[node]+1) % counting_one_set(set_partition[node]); 421 else
383 bank_index[node] = (bank_index[node]+1) % counting_one_set(bank_partition[node]); 422 node_index[node]++;
423
424 while (!rPage) {
425 try++;
426 if (try>=256)
427 break;
428 idx = get_next_index(node, idx);
429 printk(KERN_ALERT "try = %d out of page! requesting node = %ld, idx = %d\n", try, node, idx);
430 BUG_ON(idx<0 || idx>127);
431 rPage = new_alloc_page_color(idx);
432 }
433 node_index[node] = idx;
384 return rPage; 434 return rPage;
385} 435}
386 436
@@ -391,20 +441,19 @@ struct page *new_alloc_page(struct page *page, unsigned long node, int **x)
391void reclaim_page(struct page *page) 441void reclaim_page(struct page *page)
392{ 442{
393 const unsigned long color = page_list_index(page); 443 const unsigned long color = page_list_index(page);
394 unsigned long nr_reclaimed = 0;
395 spin_lock(&reclaim_lock); 444 spin_lock(&reclaim_lock);
396 put_page(page); 445 put_page(page);
397 add_page_to_color_list(page); 446 add_page_to_color_list(page);
398 447
399 spin_unlock(&reclaim_lock); 448 spin_unlock(&reclaim_lock);
400 printk("Reclaimed page(%d) = color %x, bank %x, [color] =%d \n", color, page_color(page), page_bank(page), atomic_read(&color_groups[color].nr_pages)); 449 printk("Reclaimed page(%ld) = color %x, bank %x, [color] =%d \n", color, page_color(page), page_bank(page), atomic_read(&color_groups[color].nr_pages));
401} 450}
402 451
403 452
404/* 453/*
405 * Initialize the numbers of banks and cache colors 454 * Initialize the numbers of banks and cache colors
406 */ 455 */
407static int __init init_variables(void) 456static void __init init_variables(void)
408{ 457{
409 number_banks = counting_one_set(BANK_MASK); 458 number_banks = counting_one_set(BANK_MASK);
410 number_banks = two_exp(number_banks); 459 number_banks = two_exp(number_banks);
@@ -489,7 +538,7 @@ out:
489int show_page_pool_handler(struct ctl_table *table, int write, void __user *buffer, 538int show_page_pool_handler(struct ctl_table *table, int write, void __user *buffer,
490 size_t *lenp, loff_t *ppos) 539 size_t *lenp, loff_t *ppos)
491{ 540{
492 int ret = 0, i = 0; 541 int ret = 0;
493 mutex_lock(&void_lockdown_proc); 542 mutex_lock(&void_lockdown_proc);
494 ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); 543 ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
495 if (ret) 544 if (ret)
@@ -505,13 +554,14 @@ out:
505int refill_page_pool_handler(struct ctl_table *table, int write, void __user *buffer, 554int refill_page_pool_handler(struct ctl_table *table, int write, void __user *buffer,
506 size_t *lenp, loff_t *ppos) 555 size_t *lenp, loff_t *ppos)
507{ 556{
508 int ret = 0, i = 0; 557 int ret = 0;
509 mutex_lock(&void_lockdown_proc); 558 mutex_lock(&void_lockdown_proc);
510 ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); 559 ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
511 if (ret) 560 if (ret)
512 goto out; 561 goto out;
513 if (write) { 562 if (write) {
514 do_add_pages(); 563 do_add_pages();
564 show_nr_pages();
515 } 565 }
516out: 566out:
517 mutex_unlock(&void_lockdown_proc); 567 mutex_unlock(&void_lockdown_proc);