aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2013-04-05 18:51:39 -0400
committerGlenn Elliott <gelliott@cs.unc.edu>2013-04-05 18:51:39 -0400
commit5e70dfb03ed2e1bda96e7e8ab26084b2f5402296 (patch)
treed3c35e1f4a50740720e9bd00eb88bad9a552614d
parent472e2944b12226d9d4407fb702ce98bba76b1b7d (diff)
GEDF, PEDF, and PFP: fixed budget hooks
-rw-r--r--litmus/sched_cedf.c5
-rw-r--r--litmus/sched_gsn_edf.c47
-rw-r--r--litmus/sched_pfair.c18
-rw-r--r--litmus/sched_pfp.c27
-rw-r--r--litmus/sched_psn_edf.c27
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)
1001static void gsnedf_task_wake_up(struct task_struct *task) 999static 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
851static 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
861static long pfair_admit_task(struct task_struct* t) 851static 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 */