aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjoern Brandenburg <bbb@mpi-sws.org>2012-05-31 03:06:33 -0400
committerBjoern Brandenburg <bbb@mpi-sws.org>2012-05-31 03:06:33 -0400
commitf141d730e91283a9bb5cfcb134fcead55d5da0c6 (patch)
treecb8b73c4ff4afa0b97621133ae495966d5601356
parentde76e27d43f69c6c143893b15eb1f830a11df053 (diff)
GSN-EDF: do not requeue jobs without budget
This patch changes how preemptions of jobs without budget work. Instead of requeuing them, they are now only added if they are not subject to budget enforcement or if they have non-zero budget. This allows us to process job completions that race with preemptions. This appears to fix a BUG in budget.c:65 reported by Giovani Gracioli.
-rw-r--r--include/litmus/budget.h8
-rw-r--r--litmus/sched_gsn_edf.c13
2 files changed, 14 insertions, 7 deletions
diff --git a/include/litmus/budget.h b/include/litmus/budget.h
index 96da960adccc..33344ee8d5f9 100644
--- a/include/litmus/budget.h
+++ b/include/litmus/budget.h
@@ -24,4 +24,12 @@ inline static lt_t budget_remaining(struct task_struct* t)
24#define budget_precisely_enforced(t) (tsk_rt(t)->task_params.budget_policy \ 24#define budget_precisely_enforced(t) (tsk_rt(t)->task_params.budget_policy \
25 == PRECISE_ENFORCEMENT) 25 == PRECISE_ENFORCEMENT)
26 26
27static inline int requeue_preempted_job(struct task_struct* t)
28{
29 /* Add task to ready queue only if not subject to budget enforcement or
30 * if the job has budget remaining. t may be NULL.
31 */
32 return t && (!budget_exhausted(t) || !budget_enforced(t));
33}
34
27#endif 35#endif
diff --git a/litmus/sched_gsn_edf.c b/litmus/sched_gsn_edf.c
index ea96a48b4185..c3344b9d288f 100644
--- a/litmus/sched_gsn_edf.c
+++ b/litmus/sched_gsn_edf.c
@@ -297,11 +297,11 @@ static void check_for_preemptions(void)
297 &per_cpu(gsnedf_cpu_entries, task_cpu(task))); 297 &per_cpu(gsnedf_cpu_entries, task_cpu(task)));
298 if (affinity) 298 if (affinity)
299 last = affinity; 299 last = affinity;
300 else if (last->linked) 300 else if (requeue_preempted_job(last->linked))
301 requeue(last->linked); 301 requeue(last->linked);
302 } 302 }
303#else 303#else
304 if (last->linked) 304 if (requeue_preempted_job(last->linked))
305 requeue(last->linked); 305 requeue(last->linked);
306#endif 306#endif
307 307
@@ -427,9 +427,8 @@ static struct task_struct* gsnedf_schedule(struct task_struct * prev)
427 /* (0) Determine state */ 427 /* (0) Determine state */
428 exists = entry->scheduled != NULL; 428 exists = entry->scheduled != NULL;
429 blocks = exists && !is_running(entry->scheduled); 429 blocks = exists && !is_running(entry->scheduled);
430 out_of_time = exists && 430 out_of_time = exists && budget_enforced(entry->scheduled)
431 budget_enforced(entry->scheduled) && 431 && budget_exhausted(entry->scheduled);
432 budget_exhausted(entry->scheduled);
433 np = exists && is_np(entry->scheduled); 432 np = exists && is_np(entry->scheduled);
434 sleep = exists && get_rt_flags(entry->scheduled) == RT_F_SLEEP; 433 sleep = exists && get_rt_flags(entry->scheduled) == RT_F_SLEEP;
435 preempt = entry->scheduled != entry->linked; 434 preempt = entry->scheduled != entry->linked;
@@ -467,9 +466,9 @@ static struct task_struct* gsnedf_schedule(struct task_struct * prev)
467 /* Any task that is preemptable and either exhausts its execution 466 /* Any task that is preemptable and either exhausts its execution
468 * budget or wants to sleep completes. We may have to reschedule after 467 * budget or wants to sleep completes. We may have to reschedule after
469 * this. Don't do a job completion if we block (can't have timers running 468 * this. Don't do a job completion if we block (can't have timers running
470 * for blocked jobs). Preemption go first for the same reason. 469 * for blocked jobs).
471 */ 470 */
472 if (!np && (out_of_time || sleep) && !blocks && !preempt) 471 if (!np && (out_of_time || sleep) && !blocks)
473 job_completion(entry->scheduled, !sleep); 472 job_completion(entry->scheduled, !sleep);
474 473
475 /* Link pending task if we became unlinked. 474 /* Link pending task if we became unlinked.