aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristopher Kenna <cjk@cs.unc.edu>2012-10-18 19:47:16 -0400
committerChristopher Kenna <cjk@cs.unc.edu>2012-10-18 19:51:43 -0400
commit76b433993134ed1cd467dfbd99e907816eac1ad9 (patch)
tree66ba00a577dc7b9f26f4ecfae6faa9c1e6d29d80
parente371352875eae24b984ae6675969ad1dfb7b9599 (diff)
Add debugging to Color Queue and fix a bug in color_info_free.
Signed-off-by: Christopher Kenna <cjk@cs.unc.edu>
-rw-r--r--include/litmus/color_queue.h20
-rw-r--r--litmus/color_queue.c53
2 files changed, 51 insertions, 22 deletions
diff --git a/include/litmus/color_queue.h b/include/litmus/color_queue.h
index 80976c539b1..7386b0f569d 100644
--- a/include/litmus/color_queue.h
+++ b/include/litmus/color_queue.h
@@ -11,26 +11,6 @@
11 */ 11 */
12#define COLOR_QUEUE_REQ_SIZE 2048 12#define COLOR_QUEUE_REQ_SIZE 2048
13 13
14struct color_queue {
15 struct list_head queue;
16 /* the queue of work */
17
18 int nr_cpus;
19 /* number of CPUs that have outstanding requests */
20
21 int at_barrier;
22 /* number of CPUs that are currently waiting at the barrier */
23
24 int way;
25 /* which way the queue is currently reading in */
26
27 u64 phase;
28 /* monotonically increasing phase. use 64 bits so it doesn't wrap. */
29
30 raw_spinlock_t lock;
31 /* protects the above members */
32};
33
34enum color_queue_request_type { 14enum color_queue_request_type {
35 COLOR_QUEUE_IDLE, 15 COLOR_QUEUE_IDLE,
36 /* Not in the queue. */ 16 /* Not in the queue. */
diff --git a/litmus/color_queue.c b/litmus/color_queue.c
index c266e3aa0da..6543811fd06 100644
--- a/litmus/color_queue.c
+++ b/litmus/color_queue.c
@@ -8,6 +8,36 @@
8#include <litmus/color.h> 8#include <litmus/color.h>
9#include <litmus/litmus.h> 9#include <litmus/litmus.h>
10 10
11/* Uncomment to debug. */
12#define QTRACE(q, fmt, args...) TRACE_CUR("q.phase: %llu q.way: %d " \
13 "q.nr_cpus: %d q.at_barrier: %d " fmt, \
14 q.phase, q.way, q.nr_cpus, q.at_barrier, \
15 ## args)
16
17#ifndef QTRACE
18#define QTRACE(q, fmt, args...) do { } while (0)
19#endif
20
21struct color_queue {
22 struct list_head queue;
23 /* the queue of work */
24
25 int nr_cpus;
26 /* number of CPUs that have outstanding requests */
27
28 int at_barrier;
29 /* number of CPUs that are currently waiting at the barrier */
30
31 int way;
32 /* which way the queue is currently reading in */
33
34 u64 phase;
35 /* monotonically increasing phase. use 64 bits so it doesn't wrap. */
36
37 raw_spinlock_t lock;
38 /* protects the above members */
39};
40
11struct cpu_entry { 41struct cpu_entry {
12 int phase; 42 int phase;
13 /* what phase a CPU is in */ 43 /* what phase a CPU is in */
@@ -53,6 +83,8 @@ static void cpu_add_work(struct color_queue_request *req)
53 struct list_head *new = &req->list; 83 struct list_head *new = &req->list;
54 list_add_tail(new, &entry->enqueue); 84 list_add_tail(new, &entry->enqueue);
55 entry->nr_work++; 85 entry->nr_work++;
86 TRACE_CUR("cpu->nr_work: %d added work request pointer %p\n",
87 entry->nr_work, req);
56} 88}
57 89
58/* 90/*
@@ -154,9 +186,11 @@ static void do_work_son(struct color_queue_request *request)
154 186
155 switch (request->request_type) { 187 switch (request->request_type) {
156 case COLOR_QUEUE_IDLE: 188 case COLOR_QUEUE_IDLE:
189 TRACE_CUR("idle work in the queue!\n");
157 WARN(1, "Idle work in the queue!\n"); 190 WARN(1, "Idle work in the queue!\n");
158 break; 191 break;
159 case COLOR_QUEUE_READ: 192 case COLOR_QUEUE_READ:
193 TRACE_CUR("doing work for CPU %d\n", request->cpu);
160 do_work_read(request); 194 do_work_read(request);
161 break; 195 break;
162 } 196 }
@@ -165,6 +199,7 @@ static void do_work_son(struct color_queue_request *request)
165 entry = &per_cpu(cpu_entries, request->cpu); 199 entry = &per_cpu(cpu_entries, request->cpu);
166 raw_spin_lock(&entry->lock); 200 raw_spin_lock(&entry->lock);
167 entry->nr_work--; 201 entry->nr_work--;
202 TRACE_CUR("after doing work, cpu->nr_work: %d\n", entry->nr_work);
168 raw_spin_unlock(&entry->lock); 203 raw_spin_unlock(&entry->lock);
169 204
170 /* work is done, set it idle */ 205 /* work is done, set it idle */
@@ -183,6 +218,7 @@ static void wait_next_phase(void)
183 * set up the lockdown value and updated the queue phase. 218 * set up the lockdown value and updated the queue phase.
184 */ 219 */
185 entry->phase = color_queue.phase; 220 entry->phase = color_queue.phase;
221 QTRACE(color_queue, "moving on to next phase\n");
186 raw_spin_unlock(&color_queue.lock); 222 raw_spin_unlock(&color_queue.lock);
187 return; 223 return;
188 } 224 }
@@ -190,8 +226,11 @@ static void wait_next_phase(void)
190 if (color_queue.nr_cpus == color_queue.at_barrier) { 226 if (color_queue.nr_cpus == color_queue.at_barrier) {
191 int next_way; 227 int next_way;
192 228
229 QTRACE(color_queue, "everyone reached the barrier\n");
230
193 /* Ready to start the next phase. */ 231 /* Ready to start the next phase. */
194 if (unlikely(list_empty(&color_queue.queue))) { 232 if (unlikely(list_empty(&color_queue.queue))) {
233 QTRACE(color_queue, "The queue was empty (bad)\n");
195 /* This should not happen! Will loop forever? */ 234 /* This should not happen! Will loop forever? */
196 WARN(1, "color queue list was empty!\n"); 235 WARN(1, "color queue list was empty!\n");
197 raw_spin_unlock(&color_queue.lock); 236 raw_spin_unlock(&color_queue.lock);
@@ -204,10 +243,12 @@ static void wait_next_phase(void)
204 color_queue.way = next_way; 243 color_queue.way = next_way;
205 color_queue.at_barrier = 0; 244 color_queue.at_barrier = 0;
206 color_queue.phase++; 245 color_queue.phase++;
246 QTRACE(color_queue, "moving on to start on the next way\n");
207 raw_spin_unlock(&color_queue.lock); 247 raw_spin_unlock(&color_queue.lock);
208 return; 248 return;
209 } else { 249 } else {
210 /* Wait for work from the last phase to complete. */ 250 /* Wait for work from the last phase to complete. */
251 QTRACE(color_queue, "still waiting for others\n");
211 raw_spin_unlock(&color_queue.lock); 252 raw_spin_unlock(&color_queue.lock);
212 cpu_relax(); 253 cpu_relax();
213 } 254 }
@@ -230,9 +271,11 @@ static void color_queue_loop(void)
230 raw_spin_lock(&color_queue.lock); 271 raw_spin_lock(&color_queue.lock);
231 color_queue.nr_cpus--; 272 color_queue.nr_cpus--;
232 if (0 == color_queue.nr_cpus) { 273 if (0 == color_queue.nr_cpus) {
233 /* Queue is going idle. Restore lockdown state. */ 274 /* Queue is going idle. Restore lockdown. */
234 set_lockdown(lockdown_value_idle); 275 set_lockdown(lockdown_value_idle);
276 QTRACE(color_queue, "last CPU in queue.\n");
235 } 277 }
278 QTRACE(color_queue, "just left the queue\n");
236 raw_spin_unlock(&color_queue.lock); 279 raw_spin_unlock(&color_queue.lock);
237 return; 280 return;
238 } 281 }
@@ -242,6 +285,7 @@ static void color_queue_loop(void)
242 raw_spin_lock(&color_queue.lock); 285 raw_spin_lock(&color_queue.lock);
243 if (unlikely(list_empty(&color_queue.queue))) { 286 if (unlikely(list_empty(&color_queue.queue))) {
244 /* can this happen? */ 287 /* can this happen? */
288 QTRACE(color_queue, "color queue was empty?\n");
245 WARN(1, "color queue list was empty...\n"); 289 WARN(1, "color queue list was empty...\n");
246 raw_spin_unlock(&color_queue.lock); 290 raw_spin_unlock(&color_queue.lock);
247 continue; 291 continue;
@@ -251,11 +295,13 @@ static void color_queue_loop(void)
251 if (color_queue.way == request->color_page_info->way) { 295 if (color_queue.way == request->color_page_info->way) {
252 /* we're going to do this work */ 296 /* we're going to do this work */
253 list_del(&request->list); 297 list_del(&request->list);
298 QTRACE(color_queue, "found a piece of work to do: %p\n", request);
254 raw_spin_unlock(&color_queue.lock); 299 raw_spin_unlock(&color_queue.lock);
255 do_work_son(request); 300 do_work_son(request);
256 } else { 301 } else {
257 /* we need to wait for the next phase */ 302 /* we need to wait for the next phase */
258 color_queue.at_barrier++; 303 color_queue.at_barrier++;
304 QTRACE(color_queue, "begins to wait at barrier...\n");
259 raw_spin_unlock(&color_queue.lock); 305 raw_spin_unlock(&color_queue.lock);
260 wait_next_phase(); 306 wait_next_phase();
261 } 307 }
@@ -269,10 +315,13 @@ static void color_queue_submit_work(void)
269{ 315{
270 struct cpu_entry *entry = &__get_cpu_var(cpu_entries); 316 struct cpu_entry *entry = &__get_cpu_var(cpu_entries);
271 317
318
272 raw_spin_lock(&color_queue.lock); 319 raw_spin_lock(&color_queue.lock);
320 QTRACE(color_queue, "start submit work\n");
273 entry->phase = color_queue.phase; 321 entry->phase = color_queue.phase;
274 color_queue.nr_cpus++; 322 color_queue.nr_cpus++;
275 list_splice_tail_init(&entry->enqueue, &color_queue.queue); 323 list_splice_tail_init(&entry->enqueue, &color_queue.queue);
324 QTRACE(color_queue, "end submit work\n");
276 raw_spin_unlock(&color_queue.lock); 325 raw_spin_unlock(&color_queue.lock);
277 color_queue_loop(); 326 color_queue_loop();
278} 327}
@@ -293,7 +342,7 @@ void cleanup_color_page_infos(struct list_head *head)
293 342
294 list_for_each_entry_safe(cur, tmp, head, list) { 343 list_for_each_entry_safe(cur, tmp, head, list) {
295 TRACE_CUR("cleanup color_queue_info %p\n", cur); 344 TRACE_CUR("cleanup color_queue_info %p\n", cur);
296 list_del(cur); 345 list_del(&cur->list);
297 kfree(cur); 346 kfree(cur);
298 } 347 }
299} 348}