diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2013-04-05 18:51:39 -0400 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2013-04-05 18:51:39 -0400 |
commit | 5e70dfb03ed2e1bda96e7e8ab26084b2f5402296 (patch) | |
tree | d3c35e1f4a50740720e9bd00eb88bad9a552614d | |
parent | 472e2944b12226d9d4407fb702ce98bba76b1b7d (diff) |
GEDF, PEDF, and PFP: fixed budget hooks
-rw-r--r-- | litmus/sched_cedf.c | 5 | ||||
-rw-r--r-- | litmus/sched_gsn_edf.c | 47 | ||||
-rw-r--r-- | litmus/sched_pfair.c | 18 | ||||
-rw-r--r-- | litmus/sched_pfp.c | 27 | ||||
-rw-r--r-- | litmus/sched_psn_edf.c | 27 |
5 files changed, 63 insertions, 61 deletions
diff --git a/litmus/sched_cedf.c b/litmus/sched_cedf.c index e8de5dd18b7f..1bfdef17e519 100644 --- a/litmus/sched_cedf.c +++ b/litmus/sched_cedf.c | |||
@@ -860,7 +860,7 @@ static void cedf_tick(struct task_struct* t) | |||
860 | if (is_realtime(t) && | 860 | if (is_realtime(t) && |
861 | tsk_rt(t)->budget.ops && budget_quantum_tracked(t) && | 861 | tsk_rt(t)->budget.ops && budget_quantum_tracked(t) && |
862 | budget_exhausted(t)) { | 862 | budget_exhausted(t)) { |
863 | TRACE_TASK(t, "budget exhausted\n"); | 863 | TRACE_TASK(t, "budget exhausted\n"); |
864 | budget_state_machine(t,on_exhausted); | 864 | budget_state_machine(t,on_exhausted); |
865 | } | 865 | } |
866 | } | 866 | } |
@@ -1499,8 +1499,7 @@ static void cedf_task_exit(struct task_struct * t) | |||
1499 | 1499 | ||
1500 | /* disable budget enforcement */ | 1500 | /* disable budget enforcement */ |
1501 | cedf_untrack_in_top_m(t); | 1501 | cedf_untrack_in_top_m(t); |
1502 | if (tsk_rt(t)->budget.ops) | 1502 | budget_state_machine(t,on_exit); |
1503 | budget_state_machine(t,on_exit); | ||
1504 | 1503 | ||
1505 | #ifdef CONFIG_REALTIME_AUX_TASKS | 1504 | #ifdef CONFIG_REALTIME_AUX_TASKS |
1506 | /* make sure we clean up on our way out */ | 1505 | /* make sure we clean up on our way out */ |
diff --git a/litmus/sched_gsn_edf.c b/litmus/sched_gsn_edf.c index 3084f377a5f1..cad6210d844d 100644 --- a/litmus/sched_gsn_edf.c +++ b/litmus/sched_gsn_edf.c | |||
@@ -462,7 +462,7 @@ static void gsnedf_tick(struct task_struct* t) | |||
462 | tsk_rt(t)->budget.ops && budget_quantum_tracked(t) && | 462 | tsk_rt(t)->budget.ops && budget_quantum_tracked(t) && |
463 | budget_exhausted(t)) { | 463 | budget_exhausted(t)) { |
464 | TRACE_TASK(t, "budget exhausted\n"); | 464 | TRACE_TASK(t, "budget exhausted\n"); |
465 | tsk_rt(t)->budget.ops->on_exhausted(t); | 465 | budget_state_machine(t,on_exhausted); |
466 | } | 466 | } |
467 | } | 467 | } |
468 | 468 | ||
@@ -848,14 +848,12 @@ static struct task_struct* gsnedf_schedule(struct task_struct * prev) | |||
848 | entry->linked->comm, entry->linked->pid); | 848 | entry->linked->comm, entry->linked->pid); |
849 | 849 | ||
850 | /* Do budget stuff */ | 850 | /* Do budget stuff */ |
851 | if (tsk_rt(prev)->budget.ops) { | 851 | if (blocks) |
852 | if (blocks) | 852 | budget_state_machine(prev,on_blocked); |
853 | tsk_rt(prev)->budget.ops->on_blocked(prev); | 853 | else if (sleep) |
854 | else if (sleep) | 854 | budget_state_machine(prev,on_sleep); |
855 | tsk_rt(prev)->budget.ops->on_sleep(prev); | 855 | else if (preempt) |
856 | else if (preempt) | 856 | budget_state_machine(prev,on_preempt); |
857 | tsk_rt(prev)->budget.ops->on_preempt(prev); | ||
858 | } | ||
859 | 857 | ||
860 | /* If a task blocks we have no choice but to reschedule. | 858 | /* If a task blocks we have no choice but to reschedule. |
861 | */ | 859 | */ |
@@ -1001,13 +999,12 @@ static void gsnedf_task_new(struct task_struct * t, int on_rq, int running) | |||
1001 | static void gsnedf_task_wake_up(struct task_struct *task) | 999 | static void gsnedf_task_wake_up(struct task_struct *task) |
1002 | { | 1000 | { |
1003 | unsigned long flags; | 1001 | unsigned long flags; |
1004 | //lt_t now; | 1002 | lt_t now; |
1005 | 1003 | ||
1006 | TRACE_TASK(task, "wake_up at %llu\n", litmus_clock()); | 1004 | TRACE_TASK(task, "wake_up at %llu\n", litmus_clock()); |
1007 | 1005 | ||
1008 | raw_readyq_lock_irqsave(&gsnedf_lock, flags); | 1006 | raw_readyq_lock_irqsave(&gsnedf_lock, flags); |
1009 | 1007 | ||
1010 | #if 0 | ||
1011 | /* sporadic task model. will increment job numbers automatically */ | 1008 | /* sporadic task model. will increment job numbers automatically */ |
1012 | now = litmus_clock(); | 1009 | now = litmus_clock(); |
1013 | if (is_sporadic(task) && is_tardy(task, now)) { | 1010 | if (is_sporadic(task) && is_tardy(task, now)) { |
@@ -1016,16 +1013,8 @@ static void gsnedf_task_wake_up(struct task_struct *task) | |||
1016 | sched_trace_task_release(task); | 1013 | sched_trace_task_release(task); |
1017 | } | 1014 | } |
1018 | else { | 1015 | else { |
1019 | if (task->rt.time_slice) { | 1016 | tsk_rt(task)->completed = 0; |
1020 | /* came back in time before deadline | ||
1021 | */ | ||
1022 | tsk_rt(task)->completed = 0; | ||
1023 | } | ||
1024 | } | 1017 | } |
1025 | #else | ||
1026 | /* don't force job to end. rely on user to say when jobs complete */ | ||
1027 | tsk_rt(task)->completed = 0; | ||
1028 | #endif | ||
1029 | 1018 | ||
1030 | #ifdef CONFIG_REALTIME_AUX_TASKS | 1019 | #ifdef CONFIG_REALTIME_AUX_TASKS |
1031 | if (tsk_rt(task)->has_aux_tasks && !tsk_rt(task)->hide_from_aux_tasks) { | 1020 | if (tsk_rt(task)->has_aux_tasks && !tsk_rt(task)->hide_from_aux_tasks) { |
@@ -1041,6 +1030,8 @@ static void gsnedf_task_wake_up(struct task_struct *task) | |||
1041 | } | 1030 | } |
1042 | #endif | 1031 | #endif |
1043 | 1032 | ||
1033 | budget_state_machine(task,on_wakeup); | ||
1034 | |||
1044 | gsnedf_job_arrival(task); | 1035 | gsnedf_job_arrival(task); |
1045 | raw_readyq_unlock_irqrestore(&gsnedf_lock, flags); | 1036 | raw_readyq_unlock_irqrestore(&gsnedf_lock, flags); |
1046 | } | 1037 | } |
@@ -1090,8 +1081,7 @@ static void gsnedf_task_exit(struct task_struct * t) | |||
1090 | raw_readyq_lock_irqsave(&gsnedf_lock, flags); | 1081 | raw_readyq_lock_irqsave(&gsnedf_lock, flags); |
1091 | 1082 | ||
1092 | /* disable budget enforcement */ | 1083 | /* disable budget enforcement */ |
1093 | if (tsk_rt(t)->budget.ops) | 1084 | budget_state_machine(t,on_exit); |
1094 | tsk_rt(t)->budget.ops->on_exit(t); | ||
1095 | 1085 | ||
1096 | #ifdef CONFIG_REALTIME_AUX_TASKS | 1086 | #ifdef CONFIG_REALTIME_AUX_TASKS |
1097 | /* make sure we clean up on our way out */ | 1087 | /* make sure we clean up on our way out */ |
@@ -1181,10 +1171,16 @@ static int __increase_priority_inheritance(struct task_struct* t, | |||
1181 | /* this sanity check allows for weaker locking in protocols */ | 1171 | /* this sanity check allows for weaker locking in protocols */ |
1182 | if(__edf_higher_prio(prio_inh, BASE, t, EFFECTIVE)) { | 1172 | if(__edf_higher_prio(prio_inh, BASE, t, EFFECTIVE)) { |
1183 | #endif | 1173 | #endif |
1174 | if (tsk_rt(t)->inh_task) | ||
1175 | budget_state_machine2(t,tsk_rt(t)->inh_task,on_disinherit); | ||
1176 | |||
1184 | TRACE_TASK(t, "inherits priority from %s/%d\n", | 1177 | TRACE_TASK(t, "inherits priority from %s/%d\n", |
1185 | prio_inh->comm, prio_inh->pid); | 1178 | prio_inh->comm, prio_inh->pid); |
1186 | tsk_rt(t)->inh_task = prio_inh; | 1179 | tsk_rt(t)->inh_task = prio_inh; |
1187 | 1180 | ||
1181 | if (prio_inh) | ||
1182 | budget_state_machine2(t,prio_inh,on_inherit); | ||
1183 | |||
1188 | linked_on = tsk_rt(t)->linked_on; | 1184 | linked_on = tsk_rt(t)->linked_on; |
1189 | 1185 | ||
1190 | /* If it is scheduled, then we need to reorder the CPU heap. */ | 1186 | /* If it is scheduled, then we need to reorder the CPU heap. */ |
@@ -1312,6 +1308,10 @@ static int __decrease_priority_inheritance(struct task_struct* t, | |||
1312 | #ifdef CONFIG_LITMUS_NESTED_LOCKING | 1308 | #ifdef CONFIG_LITMUS_NESTED_LOCKING |
1313 | if(budget_triggered || __edf_higher_prio(t, EFFECTIVE, prio_inh, BASE)) { | 1309 | if(budget_triggered || __edf_higher_prio(t, EFFECTIVE, prio_inh, BASE)) { |
1314 | #endif | 1310 | #endif |
1311 | |||
1312 | if (tsk_rt(t)->inh_task) | ||
1313 | budget_state_machine2(t,tsk_rt(t)->inh_task,on_disinherit); | ||
1314 | |||
1315 | /* A job only stops inheriting a priority when it releases a | 1315 | /* A job only stops inheriting a priority when it releases a |
1316 | * resource. Thus we can make the following assumption.*/ | 1316 | * resource. Thus we can make the following assumption.*/ |
1317 | if(prio_inh) | 1317 | if(prio_inh) |
@@ -1322,6 +1322,9 @@ static int __decrease_priority_inheritance(struct task_struct* t, | |||
1322 | 1322 | ||
1323 | tsk_rt(t)->inh_task = prio_inh; | 1323 | tsk_rt(t)->inh_task = prio_inh; |
1324 | 1324 | ||
1325 | if (prio_inh) | ||
1326 | budget_state_machine2(t,prio_inh,on_inherit); | ||
1327 | |||
1325 | if(tsk_rt(t)->scheduled_on != NO_CPU) { | 1328 | if(tsk_rt(t)->scheduled_on != NO_CPU) { |
1326 | TRACE_TASK(t, "is scheduled.\n"); | 1329 | TRACE_TASK(t, "is scheduled.\n"); |
1327 | 1330 | ||
diff --git a/litmus/sched_pfair.c b/litmus/sched_pfair.c index 707e6b6f2483..a7281348fd97 100644 --- a/litmus/sched_pfair.c +++ b/litmus/sched_pfair.c | |||
@@ -848,16 +848,6 @@ static void dump_subtasks(struct task_struct* t) | |||
848 | t->rt_param.pfair->subtasks[i].group_deadline); | 848 | t->rt_param.pfair->subtasks[i].group_deadline); |
849 | } | 849 | } |
850 | 850 | ||
851 | static struct budget_tracker_ops pfair_drain_simple_ops = | ||
852 | { | ||
853 | .on_scheduled = simple_on_scheduled, | ||
854 | .on_blocked = simple_on_blocked, | ||
855 | .on_preempt_or_sleep = simple_on_preempt_or_sleep, | ||
856 | .on_exit = simple_on_exit, | ||
857 | |||
858 | .on_exhausted = pfair_simple_on_exhausted, | ||
859 | }; | ||
860 | |||
861 | static long pfair_admit_task(struct task_struct* t) | 851 | static long pfair_admit_task(struct task_struct* t) |
862 | { | 852 | { |
863 | lt_t quanta; | 853 | lt_t quanta; |
@@ -925,6 +915,14 @@ static long pfair_admit_task(struct task_struct* t) | |||
925 | 915 | ||
926 | t->rt_param.pfair = param; | 916 | t->rt_param.pfair = param; |
927 | 917 | ||
918 | if (budget_enforced(t) || budget_signalled(t)) { | ||
919 | switch(get_drain_policy(t)) { | ||
920 | default: | ||
921 | TRACE_TASK(t, "Unsupported budget draining mode.\n"); | ||
922 | return -EINVAL; | ||
923 | } | ||
924 | } | ||
925 | |||
928 | /* spew out some debug info */ | 926 | /* spew out some debug info */ |
929 | dump_subtasks(t); | 927 | dump_subtasks(t); |
930 | 928 | ||
diff --git a/litmus/sched_pfp.c b/litmus/sched_pfp.c index ad2b8d81f29f..891469054ab4 100644 --- a/litmus/sched_pfp.c +++ b/litmus/sched_pfp.c | |||
@@ -175,7 +175,7 @@ static void pfp_tick(struct task_struct *t) | |||
175 | tsk_rt(t)->budget.ops && budget_quantum_tracked(t) && | 175 | tsk_rt(t)->budget.ops && budget_quantum_tracked(t) && |
176 | budget_exhausted(t)) { | 176 | budget_exhausted(t)) { |
177 | TRACE_TASK(t, "budget exhausted\n"); | 177 | TRACE_TASK(t, "budget exhausted\n"); |
178 | tsk_rt(t)->budget.ops->on_exhausted(t); | 178 | budget_state_machine(t,on_exhausted); |
179 | } | 179 | } |
180 | } | 180 | } |
181 | 181 | ||
@@ -213,14 +213,12 @@ static struct task_struct* pfp_schedule(struct task_struct * prev) | |||
213 | resched = preempt; | 213 | resched = preempt; |
214 | 214 | ||
215 | /* Do budget stuff */ | 215 | /* Do budget stuff */ |
216 | if (tsk_rt(prev)->budget.ops) { | 216 | if (blocks) |
217 | if (blocks) | 217 | budget_state_machine(prev,on_blocked); |
218 | tsk_rt(prev)->budget.ops->on_blocked(prev); | 218 | else if (sleep) |
219 | else if (sleep) | 219 | budget_state_machine(prev,on_sleep); |
220 | tsk_rt(prev)->budget.ops->on_sleep(prev); | 220 | else if (preempt) |
221 | else if (preempt) | 221 | budget_state_machine(prev,on_preempt); |
222 | tsk_rt(prev)->budget.ops->on_preempt(prev); | ||
223 | } | ||
224 | 222 | ||
225 | /* If a task blocks we have no choice but to reschedule. | 223 | /* If a task blocks we have no choice but to reschedule. |
226 | */ | 224 | */ |
@@ -389,6 +387,8 @@ static void pfp_task_wake_up(struct task_struct *task) | |||
389 | sched_trace_task_release(task); | 387 | sched_trace_task_release(task); |
390 | } | 388 | } |
391 | 389 | ||
390 | budget_state_machine(task,on_wakeup); | ||
391 | |||
392 | /* Only add to ready queue if it is not the currently-scheduled | 392 | /* Only add to ready queue if it is not the currently-scheduled |
393 | * task. This could be the case if a task was woken up concurrently | 393 | * task. This could be the case if a task was woken up concurrently |
394 | * on a remote CPU before the executing CPU got around to actually | 394 | * on a remote CPU before the executing CPU got around to actually |
@@ -436,8 +436,7 @@ static void pfp_task_exit(struct task_struct * t) | |||
436 | raw_readyq_lock_irqsave(&pfp->slock, flags); | 436 | raw_readyq_lock_irqsave(&pfp->slock, flags); |
437 | 437 | ||
438 | /* disable budget enforcement */ | 438 | /* disable budget enforcement */ |
439 | if (tsk_rt(t)->budget.ops) | 439 | budget_state_machine(t,on_exit); |
440 | tsk_rt(t)->budget.ops->on_exit(t); | ||
441 | 440 | ||
442 | if (is_queued(t)) { | 441 | if (is_queued(t)) { |
443 | BUG(); /* This currently doesn't work. */ | 442 | BUG(); /* This currently doesn't work. */ |
@@ -485,8 +484,14 @@ static void fp_set_prio_inh(pfp_domain_t* pfp, struct task_struct* t, | |||
485 | /* first remove */ | 484 | /* first remove */ |
486 | fp_dequeue(pfp, t); | 485 | fp_dequeue(pfp, t); |
487 | 486 | ||
487 | if (t->rt_param.inh_task) | ||
488 | budget_state_machine2(t,t->rt_param.inh_task,on_disinherit); | ||
489 | |||
488 | t->rt_param.inh_task = prio_inh; | 490 | t->rt_param.inh_task = prio_inh; |
489 | 491 | ||
492 | if (prio_inh) | ||
493 | budget_state_machine2(t,prio_inh,on_inherit); | ||
494 | |||
490 | if (requeue) | 495 | if (requeue) |
491 | /* add again to the right queue */ | 496 | /* add again to the right queue */ |
492 | fp_prio_add(&pfp->ready_queue, t, priority_index(t)); | 497 | fp_prio_add(&pfp->ready_queue, t, priority_index(t)); |
diff --git a/litmus/sched_psn_edf.c b/litmus/sched_psn_edf.c index dffaeb425abf..b8246acacaa9 100644 --- a/litmus/sched_psn_edf.c +++ b/litmus/sched_psn_edf.c | |||
@@ -179,12 +179,10 @@ static enum hrtimer_restart psnedf_simple_on_exhausted(struct task_struct *t) | |||
179 | * preemptable again | 179 | * preemptable again |
180 | */ | 180 | */ |
181 | litmus_reschedule_local(); | 181 | litmus_reschedule_local(); |
182 | TRACE("cedf_scheduler_tick: " | 182 | TRACE("%d is preemptable " |
183 | "%d is preemptable " | ||
184 | " => FORCE_RESCHED\n", t->pid); | 183 | " => FORCE_RESCHED\n", t->pid); |
185 | } else if (is_user_np(t)) { | 184 | } else if (is_user_np(t)) { |
186 | TRACE("cedf_scheduler_tick: " | 185 | TRACE("%d is non-preemptable, " |
187 | "%d is non-preemptable, " | ||
188 | "preemption delayed.\n", t->pid); | 186 | "preemption delayed.\n", t->pid); |
189 | request_exit_np(t); | 187 | request_exit_np(t); |
190 | } | 188 | } |
@@ -207,7 +205,7 @@ static void psnedf_tick(struct task_struct *t) | |||
207 | tsk_rt(t)->budget.ops && budget_quantum_tracked(t) && | 205 | tsk_rt(t)->budget.ops && budget_quantum_tracked(t) && |
208 | budget_exhausted(t)) { | 206 | budget_exhausted(t)) { |
209 | TRACE_TASK(t, "budget exhausted\n"); | 207 | TRACE_TASK(t, "budget exhausted\n"); |
210 | tsk_rt(t)->budget.ops->on_exhausted(t); | 208 | budget_state_machine(t,on_exhausted); |
211 | } | 209 | } |
212 | } | 210 | } |
213 | 211 | ||
@@ -245,14 +243,12 @@ static struct task_struct* psnedf_schedule(struct task_struct * prev) | |||
245 | resched = preempt; | 243 | resched = preempt; |
246 | 244 | ||
247 | /* Do budget stuff */ | 245 | /* Do budget stuff */ |
248 | if (tsk_rt(prev)->budget.ops) { | 246 | if (blocks) |
249 | if (blocks) | 247 | budget_state_machine(prev,on_blocked); |
250 | tsk_rt(prev)->budget.ops->on_blocked(prev); | 248 | else if (sleep) |
251 | else if (sleep) | 249 | budget_state_machine(prev,on_sleep); |
252 | tsk_rt(prev)->budget.ops->on_sleep(prev); | 250 | else if (preempt) |
253 | else if (preempt) | 251 | budget_state_machine(prev,on_preempt); |
254 | tsk_rt(prev)->budget.ops->on_preempt(prev); | ||
255 | } | ||
256 | 252 | ||
257 | /* If a task blocks we have no choice but to reschedule. | 253 | /* If a task blocks we have no choice but to reschedule. |
258 | */ | 254 | */ |
@@ -365,6 +361,8 @@ static void psnedf_task_wake_up(struct task_struct *task) | |||
365 | sched_trace_task_release(task); | 361 | sched_trace_task_release(task); |
366 | } | 362 | } |
367 | 363 | ||
364 | budget_state_machine(task,on_wakeup); | ||
365 | |||
368 | /* Only add to ready queue if it is not the currently-scheduled | 366 | /* Only add to ready queue if it is not the currently-scheduled |
369 | * task. This could be the case if a task was woken up concurrently | 367 | * task. This could be the case if a task was woken up concurrently |
370 | * on a remote CPU before the executing CPU got around to actually | 368 | * on a remote CPU before the executing CPU got around to actually |
@@ -398,8 +396,7 @@ static void psnedf_task_exit(struct task_struct * t) | |||
398 | raw_readyq_lock_irqsave(&pedf->slock, flags); | 396 | raw_readyq_lock_irqsave(&pedf->slock, flags); |
399 | 397 | ||
400 | /* disable budget enforcement */ | 398 | /* disable budget enforcement */ |
401 | if (tsk_rt(t)->budget.ops) | 399 | budget_state_machine(t,on_exit); |
402 | tsk_rt(t)->budget.ops->on_exit(t); | ||
403 | 400 | ||
404 | if (is_queued(t)) { | 401 | if (is_queued(t)) { |
405 | /* dequeue */ | 402 | /* dequeue */ |