diff options
author | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2007-09-25 23:16:06 -0400 |
---|---|---|
committer | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2007-09-25 23:16:06 -0400 |
commit | 60b88e745e4962476632861e4f29f25bc1aa48eb (patch) | |
tree | 238becc4a9604ce20ac74c7642805560b3dd132e /kernel | |
parent | e3245cf036c34e05801d05a246b474f56f688121 (diff) |
bugfix: don't use stale linked flag
When a job completion occured at the end of real-time mode it was possible
for unlink to be called with entry->linked == NULL. As a solution, don't
use a flag for linked, since it becomes stale too easily.
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/sched_gsn_edf.c | 12 |
1 files changed, 3 insertions, 9 deletions
diff --git a/kernel/sched_gsn_edf.c b/kernel/sched_gsn_edf.c index fc05daf114..25f21a7505 100644 --- a/kernel/sched_gsn_edf.c +++ b/kernel/sched_gsn_edf.c | |||
@@ -427,8 +427,7 @@ static int gsnedf_schedule(struct task_struct * prev, | |||
427 | runqueue_t * rq) | 427 | runqueue_t * rq) |
428 | { | 428 | { |
429 | cpu_entry_t* entry = &__get_cpu_var(gsnedf_cpu_entries); | 429 | cpu_entry_t* entry = &__get_cpu_var(gsnedf_cpu_entries); |
430 | int out_of_time, sleep, preempt, np, exists, rt, linked, | 430 | int out_of_time, sleep, preempt, np, exists, rt, blocks; |
431 | blocks; | ||
432 | 431 | ||
433 | /* Will be released in finish_switch. */ | 432 | /* Will be released in finish_switch. */ |
434 | queue_lock(&gsnedf_lock); | 433 | queue_lock(&gsnedf_lock); |
@@ -440,7 +439,6 @@ static int gsnedf_schedule(struct task_struct * prev, | |||
440 | 439 | ||
441 | /* (0) Determine state */ | 440 | /* (0) Determine state */ |
442 | exists = entry->scheduled != NULL; | 441 | exists = entry->scheduled != NULL; |
443 | linked = entry->linked != NULL; | ||
444 | blocks = exists && !is_running(entry->scheduled); | 442 | blocks = exists && !is_running(entry->scheduled); |
445 | out_of_time = exists && !entry->scheduled->time_slice; | 443 | out_of_time = exists && !entry->scheduled->time_slice; |
446 | np = exists && is_np(entry->scheduled); | 444 | np = exists && is_np(entry->scheduled); |
@@ -472,19 +470,15 @@ static int gsnedf_schedule(struct task_struct * prev, | |||
472 | 470 | ||
473 | /* Stop real-time tasks when we leave real-time mode | 471 | /* Stop real-time tasks when we leave real-time mode |
474 | */ | 472 | */ |
475 | if (!rt && linked) | 473 | if (!rt && entry->linked) |
476 | /* task will be preempted once it is preemptable | 474 | /* task will be preempted once it is preemptable |
477 | * (which it may be now already) | 475 | * (which it may be now already) |
478 | */ | 476 | */ |
479 | unlink(entry->linked); | 477 | unlink(entry->linked); |
480 | 478 | ||
481 | /* Reevaluate linked in case we changed it. | ||
482 | */ | ||
483 | linked = entry->linked != NULL; | ||
484 | |||
485 | /* Link pending task if we became unlinked. | 479 | /* Link pending task if we became unlinked. |
486 | */ | 480 | */ |
487 | if (rt && !linked) | 481 | if (rt && !entry->linked) |
488 | link_task_to_cpu(__take_ready(&gsnedf), entry); | 482 | link_task_to_cpu(__take_ready(&gsnedf), entry); |
489 | 483 | ||
490 | /* The final scheduling decision. Do we need to switch for some reason? | 484 | /* The final scheduling decision. Do we need to switch for some reason? |