diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2012-05-15 12:19:02 -0400 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2012-05-15 12:19:02 -0400 |
commit | 5b2b006507f91f9beeb9538698018fb61d36caf0 (patch) | |
tree | 4f69139693bbe290d1e0fe0d19d918aa950f3850 | |
parent | 480a2018363a3ef87e4b2cc93c83d007fef565e1 (diff) |
Chunking for locking protocol
-rw-r--r-- | include/litmus/budget.h | 1 | ||||
-rw-r--r-- | include/litmus/color.h | 1 | ||||
-rw-r--r-- | include/litmus/rt_param.h | 1 | ||||
-rw-r--r-- | litmus/budget.c | 2 | ||||
-rw-r--r-- | litmus/color_proc.c | 9 | ||||
-rw-r--r-- | litmus/sched_color.c | 59 |
6 files changed, 65 insertions, 8 deletions
diff --git a/include/litmus/budget.h b/include/litmus/budget.h index 6ef0e44effb1..a5a276e16c51 100644 --- a/include/litmus/budget.h +++ b/include/litmus/budget.h | |||
@@ -21,4 +21,5 @@ void init_enforcement_timer(struct enforcement_timer *et); | |||
21 | void arm_enforcement_timer(struct enforcement_timer* et, struct task_struct* t); | 21 | void arm_enforcement_timer(struct enforcement_timer* et, struct task_struct* t); |
22 | 22 | ||
23 | void cancel_enforcement_timer(struct enforcement_timer* et); | 23 | void cancel_enforcement_timer(struct enforcement_timer* et); |
24 | |||
24 | #endif | 25 | #endif |
diff --git a/include/litmus/color.h b/include/litmus/color.h index 970585927145..eefb6c6dddf5 100644 --- a/include/litmus/color.h +++ b/include/litmus/color.h | |||
@@ -16,6 +16,7 @@ struct color_cache_info { | |||
16 | 16 | ||
17 | /* defined in litmus/color.c */ | 17 | /* defined in litmus/color.c */ |
18 | extern struct color_cache_info color_cache_info; | 18 | extern struct color_cache_info color_cache_info; |
19 | extern unsigned long color_chunk; | ||
19 | 20 | ||
20 | struct page* get_colored_page(unsigned long); | 21 | struct page* get_colored_page(unsigned long); |
21 | void add_page_to_color_list(struct page*); | 22 | void add_page_to_color_list(struct page*); |
diff --git a/include/litmus/rt_param.h b/include/litmus/rt_param.h index 91fa107cafb5..003eaf32aa7f 100644 --- a/include/litmus/rt_param.h +++ b/include/litmus/rt_param.h | |||
@@ -231,6 +231,7 @@ struct rt_param { | |||
231 | #ifdef CONFIG_PLUGIN_COLOR | 231 | #ifdef CONFIG_PLUGIN_COLOR |
232 | lt_t max_exec_time; | 232 | lt_t max_exec_time; |
233 | lt_t tot_exec_time; | 233 | lt_t tot_exec_time; |
234 | lt_t last_exec_time; | ||
234 | struct color_ctrl_page *color_ctrl_page; | 235 | struct color_ctrl_page *color_ctrl_page; |
235 | struct dgl_group_req *req; | 236 | struct dgl_group_req *req; |
236 | #endif | 237 | #endif |
diff --git a/litmus/budget.c b/litmus/budget.c index 84f3f22770b1..b1c0a4b84c02 100644 --- a/litmus/budget.c +++ b/litmus/budget.c | |||
@@ -9,7 +9,7 @@ | |||
9 | 9 | ||
10 | DEFINE_PER_CPU(struct enforcement_timer, budget_timer); | 10 | DEFINE_PER_CPU(struct enforcement_timer, budget_timer); |
11 | 11 | ||
12 | static enum hrtimer_restart on_enforcement_timeout(struct hrtimer *timer) | 12 | enum hrtimer_restart on_enforcement_timeout(struct hrtimer *timer) |
13 | { | 13 | { |
14 | struct enforcement_timer* et = container_of(timer, | 14 | struct enforcement_timer* et = container_of(timer, |
15 | struct enforcement_timer, | 15 | struct enforcement_timer, |
diff --git a/litmus/color_proc.c b/litmus/color_proc.c index 76c540adad37..d770123c5f02 100644 --- a/litmus/color_proc.c +++ b/litmus/color_proc.c | |||
@@ -28,6 +28,8 @@ static struct color_cpu_server color_cpu_servers[NR_CPUS]; | |||
28 | /* the + 1 is for the sentinel element */ | 28 | /* the + 1 is for the sentinel element */ |
29 | static struct ctl_table color_cpu_tables[NR_CPUS + 1]; | 29 | static struct ctl_table color_cpu_tables[NR_CPUS + 1]; |
30 | 30 | ||
31 | unsigned long color_chunk; | ||
32 | |||
31 | #define INFO_BUFFER_SIZE 100 | 33 | #define INFO_BUFFER_SIZE 100 |
32 | static char info_buffer[100]; | 34 | static char info_buffer[100]; |
33 | 35 | ||
@@ -63,6 +65,13 @@ static struct ctl_table color_table[] = | |||
63 | .data = info_buffer, | 65 | .data = info_buffer, |
64 | .maxlen = INFO_BUFFER_SIZE, | 66 | .maxlen = INFO_BUFFER_SIZE, |
65 | }, | 67 | }, |
68 | { | ||
69 | .procname = "chunk_size", | ||
70 | .mode = 0666, | ||
71 | .proc_handler = proc_doulongvec_minmax, | ||
72 | .data = &color_chunk, | ||
73 | .maxlen = sizeof(color_chunk), | ||
74 | }, | ||
66 | { } | 75 | { } |
67 | }; | 76 | }; |
68 | 77 | ||
diff --git a/litmus/sched_color.c b/litmus/sched_color.c index e67681fb2d24..e72fdc3bb7d1 100644 --- a/litmus/sched_color.c +++ b/litmus/sched_color.c | |||
@@ -41,6 +41,7 @@ struct cpu_entry { | |||
41 | rt_domain_t rm_domain; | 41 | rt_domain_t rm_domain; |
42 | struct task_struct* scheduled; | 42 | struct task_struct* scheduled; |
43 | struct fifo_server fifo_server; | 43 | struct fifo_server fifo_server; |
44 | struct hrtimer chunk_timer; | ||
44 | }; | 45 | }; |
45 | 46 | ||
46 | DEFINE_PER_CPU(struct cpu_entry, color_cpus); | 47 | DEFINE_PER_CPU(struct cpu_entry, color_cpus); |
@@ -70,8 +71,6 @@ static raw_spinlock_t dgl_lock; | |||
70 | #define has_resources(t, c) (1) | 71 | #define has_resources(t, c) (1) |
71 | #endif | 72 | #endif |
72 | 73 | ||
73 | |||
74 | |||
75 | /* | 74 | /* |
76 | * Requeue onto domain's release or ready queue based on task state. | 75 | * Requeue onto domain's release or ready queue based on task state. |
77 | */ | 76 | */ |
@@ -94,6 +93,34 @@ static void requeue(rt_domain_t *dom, struct task_struct* t) | |||
94 | add_release(dom, t); | 93 | add_release(dom, t); |
95 | } | 94 | } |
96 | 95 | ||
96 | enum hrtimer_restart chunk_fire(struct hrtimer *timer) | ||
97 | { | ||
98 | unsigned long flags; | ||
99 | local_irq_save(flags); | ||
100 | TRACE("Chunk timer fired.\n"); | ||
101 | litmus_reschedule_local(); | ||
102 | local_irq_restore(flags); | ||
103 | return HRTIMER_NORESTART; | ||
104 | } | ||
105 | |||
106 | void chunk_arm(struct cpu_entry *entry) | ||
107 | { | ||
108 | unsigned long fire; | ||
109 | if (color_chunk) { | ||
110 | fire = litmus_clock() + color_chunk; | ||
111 | TRACE("Arming chunk timer for %llu\n", fire); | ||
112 | __hrtimer_start_range_ns(&entry->chunk_timer, | ||
113 | ns_to_ktime(fire), 0, | ||
114 | HRTIMER_MODE_ABS_PINNED, 0); | ||
115 | } | ||
116 | } | ||
117 | |||
118 | void chunk_cancel(struct cpu_entry *entry) | ||
119 | { | ||
120 | TRACE("Cancelling chunk timer\n"); | ||
121 | hrtimer_try_to_cancel(&entry->chunk_timer); | ||
122 | } | ||
123 | |||
97 | /* | 124 | /* |
98 | * Relinquish resources held by @t (or its children). | 125 | * Relinquish resources held by @t (or its children). |
99 | */ | 126 | */ |
@@ -312,21 +339,28 @@ static void job_completion(struct rt_server *server) | |||
312 | */ | 339 | */ |
313 | static void update_task(struct rt_server *server) | 340 | static void update_task(struct rt_server *server) |
314 | { | 341 | { |
315 | int oot, sleep, block, np; | 342 | int oot, sleep, block, np, chunked; |
316 | struct task_struct *t = server->linked; | 343 | struct task_struct *t = server->linked; |
344 | lt_t last = tsk_rt(t)->last_exec_time; | ||
317 | 345 | ||
318 | block = !is_running(t); | 346 | block = !is_running(t); |
319 | oot = budget_enforced(t) && budget_exhausted(t); | 347 | oot = budget_enforced(t) && budget_exhausted(t); |
320 | np = is_kernel_np(t); | 348 | np = is_kernel_np(t); |
321 | sleep = get_rt_flags(t) == RT_F_SLEEP; | 349 | sleep = get_rt_flags(t) == RT_F_SLEEP; |
322 | 350 | ||
323 | TRACE_TASK(t, "Updating task, block: %d, oot: %d, np: %d, sleep: %d\n", | 351 | chunked = color_chunk && last && (lt_after(litmus_clock() - last, color_chunk)); |
324 | block, oot, np, sleep); | 352 | |
353 | TRACE_TASK(t, "Updating task, block: %d, oot: %d, np: %d, sleep: %d, chunk: %d\n", | ||
354 | block, oot, np, sleep, chunked); | ||
325 | 355 | ||
326 | if (block) | 356 | if (block) |
327 | unlink(server); | 357 | unlink(server); |
328 | else if (oot || sleep) | 358 | else if (oot || sleep) |
329 | job_completion(server); | 359 | job_completion(server); |
360 | else if (chunked) { | ||
361 | unlink(server); | ||
362 | job_arrival(t); | ||
363 | } | ||
330 | } | 364 | } |
331 | 365 | ||
332 | /* | 366 | /* |
@@ -498,10 +532,16 @@ static struct task_struct* color_schedule(struct task_struct *prev) | |||
498 | entry->fifo_server.start_time = litmus_clock(); | 532 | entry->fifo_server.start_time = litmus_clock(); |
499 | } | 533 | } |
500 | 534 | ||
501 | if (prev) | 535 | if (prev) { |
502 | tsk_rt(prev)->scheduled_on = NO_CPU; | 536 | tsk_rt(prev)->scheduled_on = NO_CPU; |
503 | if (next) | 537 | tsk_rt(prev)->last_exec_time = 0; |
538 | chunk_cancel(entry); | ||
539 | } | ||
540 | if (next) { | ||
504 | tsk_rt(next)->scheduled_on = entry->server.cpu; | 541 | tsk_rt(next)->scheduled_on = entry->server.cpu; |
542 | tsk_rt(next)->last_exec_time = litmus_clock(); | ||
543 | chunk_arm(entry); | ||
544 | } | ||
505 | 545 | ||
506 | entry->scheduled = next; | 546 | entry->scheduled = next; |
507 | sched_state_task_picked(); | 547 | sched_state_task_picked(); |
@@ -527,6 +567,7 @@ static void color_task_new(struct task_struct *t, int on_rq, int running) | |||
527 | tsk_rt(t)->tot_exec_time = 0; | 567 | tsk_rt(t)->tot_exec_time = 0; |
528 | tsk_rt(t)->max_exec_time = 0; | 568 | tsk_rt(t)->max_exec_time = 0; |
529 | tsk_rt(t)->ctrl_page->colors_updated = 1; | 569 | tsk_rt(t)->ctrl_page->colors_updated = 1; |
570 | tsk_rt(t)->last_exec_time = 0; | ||
530 | 571 | ||
531 | release_at(t, litmus_clock()); | 572 | release_at(t, litmus_clock()); |
532 | 573 | ||
@@ -662,6 +703,8 @@ static long color_activate_plugin(void) | |||
662 | struct task_struct *server_task; | 703 | struct task_struct *server_task; |
663 | struct cpu_entry *entry; | 704 | struct cpu_entry *entry; |
664 | 705 | ||
706 | color_chunk = 0; | ||
707 | |||
665 | for_each_online_cpu(cpu) { | 708 | for_each_online_cpu(cpu) { |
666 | entry = remote_entry(cpu); | 709 | entry = remote_entry(cpu); |
667 | server_task = entry->fifo_server.task; | 710 | server_task = entry->fifo_server.task; |
@@ -809,6 +852,8 @@ static int __init init_color(void) | |||
809 | cpu_server->running = 1; | 852 | cpu_server->running = 1; |
810 | 853 | ||
811 | init_enforcement_timer(&fifo_server->timer); | 854 | init_enforcement_timer(&fifo_server->timer); |
855 | hrtimer_init(&entry->chunk_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); | ||
856 | entry->chunk_timer.function = chunk_fire; | ||
812 | } | 857 | } |
813 | 858 | ||
814 | fifo_domain_init(&fifo_domain, NULL, color_fifo_release); | 859 | fifo_domain_init(&fifo_domain, NULL, color_fifo_release); |