aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorBjoern B. Brandenburg <bbb@cs.unc.edu>2007-09-25 23:16:06 -0400
committerBjoern B. Brandenburg <bbb@cs.unc.edu>2007-09-25 23:16:06 -0400
commit60b88e745e4962476632861e4f29f25bc1aa48eb (patch)
tree238becc4a9604ce20ac74c7642805560b3dd132e /kernel
parente3245cf036c34e05801d05a246b474f56f688121 (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.c12
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?