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 = colo