From 5b2b006507f91f9beeb9538698018fb61d36caf0 Mon Sep 17 00:00:00 2001 From: Jonathan Herman Date: Tue, 15 May 2012 12:19:02 -0400 Subject: Chunking for locking protocol --- include/litmus/budget.h | 1 + include/litmus/color.h | 1 + include/litmus/rt_param.h | 1 + litmus/budget.c | 2 +- litmus/color_proc.c | 9 ++++++++ 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); void arm_enforcement_timer(struct enforcement_timer* et, struct task_struct* t); void cancel_enforcement_timer(struct enforcement_timer* et); + #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 { /* defined in litmus/color.c */ extern struct color_cache_info color_cache_info; +extern unsigned long color_chunk; struct page* get_colored_page(unsigned long); 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 { #ifdef CONFIG_PLUGIN_COLOR lt_t max_exec_time; lt_t tot_exec_time; + lt_t last_exec_time; struct color_ctrl_page *color_ctrl_page; struct dgl_group_req *req; #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 @@ DEFINE_PER_CPU(struct enforcement_timer, budget_timer); -static enum hrtimer_restart on_enforcement_timeout(struct hrtimer *timer) +enum hrtimer_restart on_enforcement_timeout(struct hrtimer *timer) { struct enforcement_timer* et = container_of(timer, 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]; /* the + 1 is for the sentinel element */ static struct ctl_table color_cpu_tables[NR_CPUS + 1]; +unsigned long color_chunk; + #define INFO_BUFFER_SIZE 100 static char info_buffer[100]; @@ -63,6 +65,13 @@ static struct ctl_table color_table[] = .data = info_buffer, .maxlen = INFO_BUFFER_SIZE, }, + { + .procname = "chunk_size", + .mode = 0666, + .proc_handler = proc_doulongvec_minmax, + .data = &color_chunk, + .maxlen = sizeof(color_chunk), + }, { } }; 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 { rt_domain_t rm_domain; struct task_struct* scheduled; struct fifo_server fifo_server; + struct hrtimer chunk_timer; }; DEFINE_PER_CPU(struct cpu_entry, color_cpus); @@ -70,8 +71,6 @@ static raw_spinlock_t dgl_lock; #define has_resources(t, c) (1) #endif - - /* * Requeue onto domain's release or ready queue based on task state. */ @@ -94,6 +93,34 @@ static void requeue(rt_domain_t *dom, struct task_struct* t) add_release(dom, t); } +enum hrtimer_restart chunk_fire(struct hrtimer *timer) +{ + unsigned long flags; + local_irq_save(flags); + TRACE("Chunk timer fired.\n"); + litmus_reschedule_local(); + local_irq_restore(flags); + return HRTIMER_NORESTART; +} + +void chunk_arm(struct cpu_entry *entry) +{ + unsigned long fire; + if (color_chunk) { + fire = litmus_clock() + color_chunk; + TRACE("Arming chunk timer for %llu\n", fire); + __hrtimer_start_range_ns(&entry->chunk_timer, + ns_to_ktime(fire), 0, + HRTIMER_MODE_ABS_PINNED, 0); + } +} + +void chunk_cancel(struct cpu_entry *entry) +{ + TRACE("Cancelling chunk timer\n"); + hrtimer_try_to_cancel(&entry->chunk_timer); +} + /* * Relinquish resources held by @t (or its children). */ @@ -312,21 +339,28 @@ static void job_completion(struct rt_server *server) */ static void update_task(struct rt_server *server) { - int oot, sleep, block, np; + int oot, sleep, block, np, chunked; struct task_struct *t = server->linked; + lt_t last = tsk_rt(t)->last_exec_time; block = !is_running(t); oot = budget_enforced(t) && budget_exhausted(t); np = is_kernel_np(t); sleep = get_rt_flags(t) == RT_F_SLEEP; - TRACE_TASK(t, "Updating task, block: %d, oot: %d, np: %d, sleep: %d\n", - block, oot, np, sleep); + chunked = color_chunk && last && (lt_after(litmus_clock() - last, color_chunk)); + + TRACE_TASK(t, "Updating task, block: %d, oot: %d, np: %d, sleep: %d, chunk: %d\n", + block, oot, np, sleep, chunked); if (block) unlink(server); else if (oot || sleep) job_completion(server); + else if (chunked) { + unlink(server); + job_arrival(t); + } } /* @@ -498,10 +532,16 @@ static struct task_struct* color_schedule(struct task_struct *prev) entry->fifo_server.start_time = litmus_clock(); } - if (prev) + if (prev) { tsk_rt(prev)->scheduled_on = NO_CPU; - if (next) + tsk_rt(prev)->last_exec_time = 0; + chunk_cancel(entry); + } + if (next) { tsk_rt(next)->scheduled_on = entry->server.cpu; + tsk_rt(next)->last_exec_time = litmus_clock(); + chunk_arm(entry); + } entry->scheduled = next; sched_state_task_picked(); @@ -527,6 +567,7 @@ static void color_task_new(struct task_struct *t, int on_rq, int running) tsk_rt(t)->tot_exec_time = 0; tsk_rt(t)->max_exec_time = 0; tsk_rt(t)->ctrl_page->colors_updated = 1; + tsk_rt(t)->last_exec_time = 0; release_at(t, litmus_clock()); @@ -662,6 +703,8 @@ static long color_activate_plugin(void) struct task_struct *server_task; struct cpu_entry *entry; + color_chunk = 0; + for_each_online_cpu(cpu) { entry = remote_entry(cpu); server_task = entry->fifo_server.task; @@ -809,6 +852,8 @@ static int __init init_color(void) cpu_server->running = 1; init_enforcement_timer(&fifo_server->timer); + hrtimer_init(&entry->chunk_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); + entry->chunk_timer.function = chunk_fire; } fifo_domain_init(&fifo_domain, NULL, color_fifo_release); -- cgit v1.2.2