diff options
author | Bjoern Brandenburg <bbb@mpi-sws.org> | 2012-05-31 03:06:33 -0400 |
---|---|---|
committer | Bjoern Brandenburg <bbb@mpi-sws.org> | 2012-05-31 03:06:33 -0400 |
commit | f141d730e91283a9bb5cfcb134fcead55d5da0c6 (patch) | |
tree | cb8b73c4ff4afa0b97621133ae495966d5601356 | |
parent | de76e27d43f69c6c143893b15eb1f830a11df053 (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.h | 8 | ||||
-rw-r--r-- | litmus/sched_gsn_edf.c | 13 |
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 | ||
27 | static 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. |