diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2012-10-09 21:59:25 -0400 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2012-10-09 21:59:25 -0400 |
commit | 1b6e7d3a78db7ea7eb0e20f1bca5b49079739a7c (patch) | |
tree | cb630040484d93c86a819bc61d9e0822df664793 /litmus/sched_mc.c | |
parent | a744599d42a19e0b74c95a77abec6ee79f869b0f (diff) |
Moved budget accounting into MC plugin.
This commit is broken as it allows locking tasks to early release.
Diffstat (limited to 'litmus/sched_mc.c')
-rw-r--r-- | litmus/sched_mc.c | 61 |
1 files changed, 19 insertions, 42 deletions
diff --git a/litmus/sched_mc.c b/litmus/sched_mc.c index 76479fd08d3a..3fb223255792 100644 --- a/litmus/sched_mc.c +++ b/litmus/sched_mc.c | |||
@@ -281,21 +281,19 @@ static inline void start_crit(struct crit_entry *ce) | |||
281 | * Time accounting for ghost tasks. | 281 | * Time accounting for ghost tasks. |
282 | * Must be called before a decision is made involving the task's budget. | 282 | * Must be called before a decision is made involving the task's budget. |
283 | */ | 283 | */ |
284 | static void update_ghost_time(struct task_struct *p) | 284 | static void update_server_time(struct task_struct *p) |
285 | { | 285 | { |
286 | u64 clock = litmus_clock(); | 286 | u64 clock = litmus_clock(); |
287 | u64 delta = clock - p->se.exec_start; | 287 | u64 delta = clock - p->rt_param.last_exec_time; |
288 | BUG_ON(!is_ghost(p)); | ||
289 | if (unlikely ((s64)delta < 0)) { | 288 | if (unlikely ((s64)delta < 0)) { |
290 | delta = 0; | 289 | delta = 0; |
291 | } | 290 | } |
292 | if (budget_remaining(p) <= delta) { | 291 | if (budget_remaining(p) <= delta) { |
293 | tsk_rt(p)->job_params.exec_time = get_exec_cost(p); | 292 | tsk_rt(p)->job_params.exec_time = get_exec_cost(p); |
294 | p->se.exec_start = clock; | ||
295 | } else { | 293 | } else { |
296 | tsk_rt(p)->job_params.exec_time += delta; | 294 | tsk_rt(p)->job_params.exec_time += delta; |
297 | p->se.exec_start = clock; | ||
298 | } | 295 | } |
296 | p->rt_param.last_exec_time = clock; | ||
299 | } | 297 | } |
300 | 298 | ||
301 | /** | 299 | /** |
@@ -305,8 +303,6 @@ static void update_ghost_time(struct task_struct *p) | |||
305 | static void link_task_to_crit(struct crit_entry *ce, | 303 | static void link_task_to_crit(struct crit_entry *ce, |
306 | struct task_struct *task) | 304 | struct task_struct *task) |
307 | { | 305 | { |
308 | lt_t when_to_fire; | ||
309 | |||
310 | TRACE_CRIT_ENTRY(ce, "Linking " TS "\n", TA(task)); | 306 | TRACE_CRIT_ENTRY(ce, "Linking " TS "\n", TA(task)); |
311 | BUG_ON(!can_use(ce) && task); | 307 | BUG_ON(!can_use(ce) && task); |
312 | BUG_ON(task && tsk_rt(task)->linked_on != NO_CPU); | 308 | BUG_ON(task && tsk_rt(task)->linked_on != NO_CPU); |
@@ -323,7 +319,7 @@ static void link_task_to_crit(struct crit_entry *ce, | |||
323 | cancel_ghost(ce); | 319 | cancel_ghost(ce); |
324 | if (!budget_exhausted(ce->linked)) { | 320 | if (!budget_exhausted(ce->linked)) { |
325 | /* Job isn't finished, so do accounting */ | 321 | /* Job isn't finished, so do accounting */ |
326 | update_ghost_time(ce->linked); | 322 | update_server_time(ce->linked); |
327 | } | 323 | } |
328 | } | 324 | } |
329 | sched_trace_server_switch_away(ce_sid(ce), 0, -ce->linked->pid, | 325 | sched_trace_server_switch_away(ce_sid(ce), 0, -ce->linked->pid, |
@@ -683,6 +679,7 @@ static void job_completion(struct task_struct *task, int forced) | |||
683 | TRACE_MC_TASK(task, "Completed\n"); | 679 | TRACE_MC_TASK(task, "Completed\n"); |
684 | 680 | ||
685 | /* Logically stop the task execution */ | 681 | /* Logically stop the task execution */ |
682 | remove_from_all(task); | ||
686 | set_rt_flags(task, RT_F_SLEEP); | 683 | set_rt_flags(task, RT_F_SLEEP); |
687 | 684 | ||
688 | if (!forced) { | 685 | if (!forced) { |
@@ -715,15 +712,10 @@ static void job_completion(struct task_struct *task, int forced) | |||
715 | set_rt_flags(task, RT_F_RUNNING); | 712 | set_rt_flags(task, RT_F_RUNNING); |
716 | } | 713 | } |
717 | 714 | ||
718 | /* If the server was not released, then the task's priority remains | 715 | |
719 | * unchanged and it should be left where it is | 716 | if (is_running(task)) { |
720 | */ | 717 | /* Requeue non-blocking tasks */ |
721 | if (release_server) { | 718 | job_arrival(task); |
722 | remove_from_all(task); | ||
723 | if (is_running(task)) { | ||
724 | /* Requeue non-blocking tasks */ | ||
725 | job_arrival(task); | ||
726 | } | ||
727 | } | 719 | } |
728 | } | 720 | } |
729 | 721 | ||
@@ -739,31 +731,10 @@ static enum hrtimer_restart mc_ghost_exhausted(struct hrtimer *timer) | |||
739 | { | 731 | { |
740 | struct crit_entry *ce = container_of(timer, struct crit_entry, timer); | 732 | struct crit_entry *ce = container_of(timer, struct crit_entry, timer); |
741 | #endif | 733 | #endif |
742 | |||
743 | unsigned long flags; | ||
744 | struct task_struct *tmp = NULL; | ||
745 | |||
746 | local_irq_save(flags); | ||
747 | TRACE_CRIT_ENTRY(ce, "Firing here at %llu\n", litmus_clock()); | 734 | TRACE_CRIT_ENTRY(ce, "Firing here at %llu\n", litmus_clock()); |
748 | 735 | ||
749 | /* Due to race conditions, we cannot just set the linked | 736 | litmus_reschedule(crit_cpu(ce)->cpu); |
750 | * task's budget to 0 as it may no longer be the task | ||
751 | * for which this timer was armed. Instead, update the running | ||
752 | * task time and see if this causes exhaustion. | ||
753 | */ | ||
754 | raw_spin_lock(&crit_cpu(ce)->lock); | ||
755 | if (ce->linked && is_ghost(ce->linked)) { | ||
756 | update_ghost_time(ce->linked); | ||
757 | if (budget_exhausted(ce->linked)) { | ||
758 | tmp = ce->linked; | ||
759 | } | ||
760 | } | ||
761 | raw_spin_unlock(&crit_cpu(ce)->lock); | ||
762 | |||
763 | if (tmp) | ||
764 | job_completion(tmp, 1); | ||
765 | 737 | ||
766 | local_irq_restore(flags); | ||
767 | #ifndef CONFIG_MERGE_TIMERS | 738 | #ifndef CONFIG_MERGE_TIMERS |
768 | return HRTIMER_NORESTART; | 739 | return HRTIMER_NORESTART; |
769 | #endif | 740 | #endif |
@@ -924,6 +895,7 @@ static void mc_task_new(struct task_struct *t, int on_rq, int running) | |||
924 | BUG_ON(entry->scheduled); | 895 | BUG_ON(entry->scheduled); |
925 | entry->scheduled = t; | 896 | entry->scheduled = t; |
926 | tsk_rt(t)->scheduled_on = entry->cpu; | 897 | tsk_rt(t)->scheduled_on = entry->cpu; |
898 | tsk_rt(t)->last_exec_time = litmus_clock(); | ||
927 | } else { | 899 | } else { |
928 | t->rt_param.scheduled_on = NO_CPU; | 900 | t->rt_param.scheduled_on = NO_CPU; |
929 | } | 901 | } |
@@ -1101,6 +1073,11 @@ static struct task_struct* mc_schedule(struct task_struct* prev) | |||
1101 | BUG_ON(entry->scheduled && !is_realtime(prev)); | 1073 | BUG_ON(entry->scheduled && !is_realtime(prev)); |
1102 | BUG_ON(is_realtime(prev) && !entry->scheduled); | 1074 | BUG_ON(is_realtime(prev) && !entry->scheduled); |
1103 | 1075 | ||
1076 | if (entry->scheduled != NULL) { | ||
1077 | prev->rt_param.scheduled_on = NO_CPU; | ||
1078 | update_server_time(prev); | ||
1079 | } | ||
1080 | |||
1104 | /* Determine state */ | 1081 | /* Determine state */ |
1105 | exists = entry->scheduled != NULL; | 1082 | exists = entry->scheduled != NULL; |
1106 | blocks = exists && !is_running(entry->scheduled); | 1083 | blocks = exists && !is_running(entry->scheduled); |
@@ -1114,8 +1091,6 @@ static struct task_struct* mc_schedule(struct task_struct* prev) | |||
1114 | TRACE(TS " block:%d oot:%d sleep:%d preempt:%d, now: %llu\n", | 1091 | TRACE(TS " block:%d oot:%d sleep:%d preempt:%d, now: %llu\n", |
1115 | TA(prev), blocks, out_of_time, sleep, preempt, litmus_clock()); | 1092 | TA(prev), blocks, out_of_time, sleep, preempt, litmus_clock()); |
1116 | 1093 | ||
1117 | if (exists) | ||
1118 | prev->rt_param.scheduled_on = NO_CPU; | ||
1119 | 1094 | ||
1120 | raw_spin_unlock(&entry->lock); | 1095 | raw_spin_unlock(&entry->lock); |
1121 | 1096 | ||
@@ -1169,7 +1144,9 @@ static struct task_struct* mc_schedule(struct task_struct* prev) | |||
1169 | raw_spin_unlock_irqrestore(&entry->lock, flags); | 1144 | raw_spin_unlock_irqrestore(&entry->lock, flags); |
1170 | 1145 | ||
1171 | if (next) { | 1146 | if (next) { |
1172 | BUG_ON(!is_released(next, litmus_clock())); | 1147 | tsk_rt(next)->last_exec_time = litmus_clock(); |
1148 | BUG_ON(!is_released(next, tsk_rt(next)->last_exec_time)); | ||
1149 | BUG_ON(is_ghost(next)); | ||
1173 | TRACE_MC_TASK(next, "Picked this task\n"); | 1150 | TRACE_MC_TASK(next, "Picked this task\n"); |
1174 | } else if (exists && !next) | 1151 | } else if (exists && !next) |
1175 | STRACE("CPU %d becomes idle at %llu\n", | 1152 | STRACE("CPU %d becomes idle at %llu\n", |