diff options
author | Joshua Bakita <jbakita@cs.unc.edu> | 2020-03-02 13:28:46 -0500 |
---|---|---|
committer | Joshua Bakita <jbakita@cs.unc.edu> | 2020-03-02 13:28:46 -0500 |
commit | fcbd5c7694ad5fb64cde74d3b7d95c0333dc4970 (patch) | |
tree | c5e7b653930252f9b1a0faf75c018a85d056ae48 | |
parent | 4b2acf9638fbc91a4caf7ef8004fc590b30f3cfb (diff) |
Fix logic in gschedule and cschedule when prev is non-realtime
-rw-r--r-- | litmus/sched_edfsc.c | 20 |
1 files changed, 11 insertions, 9 deletions
diff --git a/litmus/sched_edfsc.c b/litmus/sched_edfsc.c index 01a13f6a85c1..ab143d9a15f8 100644 --- a/litmus/sched_edfsc.c +++ b/litmus/sched_edfsc.c | |||
@@ -484,10 +484,10 @@ static struct task_struct* edfsc_cschedule(cont_domain_t* cedf, struct task_stru | |||
484 | * differently from gedf, when a task exits (dead) | 484 | * differently from gedf, when a task exits (dead) |
485 | * cedf->schedule may be null and prev _is_ realtime | 485 | * cedf->schedule may be null and prev _is_ realtime |
486 | */ | 486 | */ |
487 | printk("%p\n", cedf->scheduled); | 487 | ////printk("%p\n", cedf->scheduled); |
488 | BUG_ON(cedf->scheduled && cedf->scheduled != prev); | 488 | BUG_ON(cedf->scheduled && cedf->scheduled != prev && is_realtime(prev)); |
489 | BUG_ON(cedf->scheduled && !is_realtime(prev)); | 489 | // XXX: Is this okay with background scheduling??? |
490 | BUG_ON(is_migrating(cedf->scheduled)); | 490 | BUG_ON(cedf->scheduled && is_migrating(cedf->scheduled)); |
491 | 491 | ||
492 | /* (0) Determine state */ | 492 | /* (0) Determine state */ |
493 | exists = cedf->scheduled != NULL; | 493 | exists = cedf->scheduled != NULL; |
@@ -496,7 +496,7 @@ static struct task_struct* edfsc_cschedule(cont_domain_t* cedf, struct task_stru | |||
496 | && budget_exhausted(cedf->scheduled); | 496 | && budget_exhausted(cedf->scheduled); |
497 | np = exists && is_np(cedf->scheduled); | 497 | np = exists && is_np(cedf->scheduled); |
498 | sleep = exists && is_completed(cedf->scheduled); | 498 | sleep = exists && is_completed(cedf->scheduled); |
499 | preempt = is_migrating(prev) || edf_preemption_needed(edf, prev); | 499 | preempt = !is_realtime(prev) || is_migrating(prev) || edf_preemption_needed(edf, prev); |
500 | 500 | ||
501 | /* If we need to preempt do so. | 501 | /* If we need to preempt do so. |
502 | * The following checks set resched to 1 in case of special | 502 | * The following checks set resched to 1 in case of special |
@@ -726,6 +726,8 @@ static struct task_struct *edfsc_gschedule(struct task_struct *prev) | |||
726 | if (entry->linked) { | 726 | if (entry->linked) { |
727 | entry->linked->rt_param.scheduled_on = entry->cpu; | 727 | entry->linked->rt_param.scheduled_on = entry->cpu; |
728 | next = entry->linked; | 728 | next = entry->linked; |
729 | if (is_container(next)) | ||
730 | next = edfsc_cschedule(tsk_rt(next)->edfsc_params.domain, prev); | ||
729 | TRACE_TASK(next, "scheduled_on = P%d\n", smp_processor_id()); | 731 | TRACE_TASK(next, "scheduled_on = P%d\n", smp_processor_id()); |
730 | } | 732 | } |
731 | if (entry->scheduled) { | 733 | if (entry->scheduled) { |
@@ -733,18 +735,17 @@ static struct task_struct *edfsc_gschedule(struct task_struct *prev) | |||
733 | entry->scheduled->rt_param.scheduled_on = NO_CPU; | 735 | entry->scheduled->rt_param.scheduled_on = NO_CPU; |
734 | TRACE_TASK(entry->scheduled, "scheduled_on = NO_CPU\n"); | 736 | TRACE_TASK(entry->scheduled, "scheduled_on = NO_CPU\n"); |
735 | } | 737 | } |
736 | if (is_container(entry->scheduled)) | 738 | } else { |
737 | next = edfsc_cschedule(tsk_rt(next)->edfsc_params.domain, prev); | ||
738 | } else | ||
739 | // When a fixed task is released, it causes gschedule to be called | 739 | // When a fixed task is released, it causes gschedule to be called |
740 | // however, when entry->scheduled is a previously empty container, | 740 | // however, when entry->scheduled is a previously empty container, |
741 | // prev can be a non-rt task. In which case, we can only set next = prev | 741 | // prev can be a non-rt task. In which case, we can only set next = prev |
742 | // when cschedule finds nothing to schedule on the container | 742 | // when cschedule finds nothing to schedule on the container |
743 | BUG_ON(entry->linked != entry->scheduled); | 743 | BUG_ON(entry->linked != entry->scheduled); |
744 | if (is_container(entry->scheduled)) | 744 | if (is_container(entry->scheduled)) |
745 | next = edfsc_cschedule(tsk_rt(entry->scheduled)->edfsc_params.domain, entry->scheduled); | 745 | next = edfsc_cschedule(tsk_rt(entry->scheduled)->edfsc_params.domain, prev); |
746 | if (exists && is_container(next)) | 746 | if (exists && is_container(next)) |
747 | next = prev; | 747 | next = prev; |
748 | } | ||
748 | 749 | ||
749 | sched_state_task_picked(); | 750 | sched_state_task_picked(); |
750 | 751 | ||
@@ -765,6 +766,7 @@ static struct task_struct *edfsc_gschedule(struct task_struct *prev) | |||
765 | manage_idle_enforcement_timer(next); | 766 | manage_idle_enforcement_timer(next); |
766 | return NULL; | 767 | return NULL; |
767 | } | 768 | } |
769 | // XXX: Maybe this should be entry->linked | ||
768 | else if (next == prev && is_container(entry->scheduled)) { | 770 | else if (next == prev && is_container(entry->scheduled)) { |
769 | manage_idle_enforcement_timer(entry->scheduled); | 771 | manage_idle_enforcement_timer(entry->scheduled); |
770 | return next; | 772 | return next; |