diff options
author | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2010-09-22 23:20:18 -0400 |
---|---|---|
committer | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2010-09-22 23:20:18 -0400 |
commit | 5bcd520f1685aea2524c5653297b9011cb3161a9 (patch) | |
tree | 75ccb740c05723a68ab68ace42f43e5b2a039f64 | |
parent | 3aa64c84584432a5050c3bfb1d322f9bcdde1faa (diff) |
EDF-WM: handle race between wake_up() and schedule()
A job that temporarily blocked without being descheduled
might have its slices advanced to the next CPU. In this case,
we need to force a rescheduling + migration.
-rw-r--r-- | litmus/sched_edf_wm.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/litmus/sched_edf_wm.c b/litmus/sched_edf_wm.c index c3d241a42566..baf03f7ca6ac 100644 --- a/litmus/sched_edf_wm.c +++ b/litmus/sched_edf_wm.c | |||
@@ -323,8 +323,7 @@ static struct task_struct* wm_schedule(struct task_struct * prev) | |||
323 | rt_domain_t *edf = &dom->domain; | 323 | rt_domain_t *edf = &dom->domain; |
324 | struct task_struct *next, *migrate = NULL; | 324 | struct task_struct *next, *migrate = NULL; |
325 | 325 | ||
326 | int out_of_time, sleep, preempt, | 326 | int out_of_time, sleep, preempt, wrong_cpu, exists, blocks, resched; |
327 | exists, blocks, resched; | ||
328 | 327 | ||
329 | raw_spin_lock(&dom->slock); | 328 | raw_spin_lock(&dom->slock); |
330 | 329 | ||
@@ -336,6 +335,7 @@ static struct task_struct* wm_schedule(struct task_struct * prev) | |||
336 | 335 | ||
337 | /* (0) Determine state */ | 336 | /* (0) Determine state */ |
338 | exists = dom->scheduled != NULL; | 337 | exists = dom->scheduled != NULL; |
338 | wrong_cpu = exists && get_partition(dom->scheduled) != dom->cpu; | ||
339 | blocks = exists && !is_running(dom->scheduled); | 339 | blocks = exists && !is_running(dom->scheduled); |
340 | out_of_time = exists | 340 | out_of_time = exists |
341 | && budget_enforced(dom->scheduled) | 341 | && budget_enforced(dom->scheduled) |
@@ -349,11 +349,25 @@ static struct task_struct* wm_schedule(struct task_struct * prev) | |||
349 | */ | 349 | */ |
350 | resched = preempt; | 350 | resched = preempt; |
351 | 351 | ||
352 | |||
353 | if (exists) | ||
354 | TRACE_TASK(prev, | ||
355 | "blocks:%d out_of_time:%d sleep:%d preempt:%d " | ||
356 | "wrong_cpu:%d state:%d sig:%d\n", | ||
357 | blocks, out_of_time, sleep, preempt, wrong_cpu, | ||
358 | prev->state, signal_pending(prev)); | ||
359 | |||
352 | /* If a task blocks we have no choice but to reschedule. | 360 | /* If a task blocks we have no choice but to reschedule. |
353 | */ | 361 | */ |
354 | if (blocks) | 362 | if (blocks) |
355 | resched = 1; | 363 | resched = 1; |
356 | 364 | ||
365 | /* This can happen if sliced task was moved to the next slice | ||
366 | * by the wake_up() code path while still being scheduled. | ||
367 | */ | ||
368 | if (wrong_cpu) | ||
369 | resched = 1; | ||
370 | |||
357 | /* Any task that is preemptable and either exhausts its execution | 371 | /* Any task that is preemptable and either exhausts its execution |
358 | * budget or wants to sleep completes. We may have to reschedule after | 372 | * budget or wants to sleep completes. We may have to reschedule after |
359 | * this. | 373 | * this. |