aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZelin Tong <ztong@ludwig.cs.unc.edu>2020-02-26 18:14:07 -0500
committerZelin Tong <ztong@ludwig.cs.unc.edu>2020-02-26 18:14:07 -0500
commit25fb933628b3f3953fb8b6d206a0c53855a8bae9 (patch)
treea336bda4a391b855d2bc966ae2575332fda5574f
parent72e55e5c572abe93440829702592acb5334a052e (diff)
End of day commit 2/26/2020
changed edfsc_cschedule found no fixed task to be next, it will now return the container instead of null To explain the other changes, first I must explain the problem. When a container has no fixed tasks, but still has budget, there is nothing in litmus that enforces its budget or updates its exec_time in job_params. This means we will have to enforce the container budget in this case ourselves with an enforcement timer. Furthermore, we also have to update the exec_time ourselves since only actual task have their exec_time updated automatically by litmus the new functions are added and gschedule changed to fix the above problem
-rw-r--r--litmus/sched_edfsc.c62
1 files changed, 60 insertions, 2 deletions
diff --git a/litmus/sched_edfsc.c b/litmus/sched_edfsc.c
index 125b2e314176..449d6b3431a2 100644
--- a/litmus/sched_edfsc.c
+++ b/litmus/sched_edfsc.c
@@ -32,6 +32,8 @@ typedef struct cont_domain {
32 lt_t changed_budget; //change to scheduled task's exec time due to container budget constraints 32 lt_t changed_budget; //change to scheduled task's exec time due to container budget constraints
33 u64 f_util, future_f_util; 33 u64 f_util, future_f_util;
34 struct bheap_node *hn; 34 struct bheap_node *hn;
35 struct hrtimer idle_enforcement_timer;
36 int timer_armed;
35} cont_domain_t; 37} cont_domain_t;
36 38
37typedef struct { 39typedef struct {
@@ -458,6 +460,7 @@ static int fifo_prio(struct bheap_node* _a, struct bheap_node* _b)
458// takes in the container_domain pointer in container task_struct 460// takes in the container_domain pointer in container task_struct
459// assuming prev is previous task running on the processor before calling schedule 461// assuming prev is previous task running on the processor before calling schedule
460// global lock in effect 462// global lock in effect
463// returns container if no fixed task is next
461static struct task_struct* edfsc_cschedule(cont_domain_t* cedf, struct task_struct * prev) 464static struct task_struct* edfsc_cschedule(cont_domain_t* cedf, struct task_struct * prev)
462{ 465{
463 rt_domain_t *edf = &cedf->domain; 466 rt_domain_t *edf = &cedf->domain;
@@ -576,7 +579,31 @@ static struct task_struct* edfsc_cschedule(cont_domain_t* cedf, struct task_stru
576 579
577 printk("/edfsc_cschedule\n"); 580 printk("/edfsc_cschedule\n");
578 581
579 return next; 582 return (next) ? next : cedf->container;
583}
584
585void manage_idle_enforcement_timer(struct task_struct* t)
586{
587 lt_t now;
588
589 cont_domain_t* domain = tsk_rt(t)->edfsc_params.domain;
590 if (t && budget_precisely_enforced(t)) {
591 BUG_ON(budget_exhausted(t) && !is_np(t));
592 if (likely(!is_np(t))) {
593 now = litmus_clock();
594 //hrtimer_start cancels the timer so don't have to check
595 //if it is already armed
596 hrtimer_start(&(domain->idle_enforcement_timer),
597 ns_to_ktime(now + budget_remaining(t)),
598 HRTIMER_MODE_ABS_PINNED);
599 domain->timer_armed = 1;
600 domain->scheduled_last_exec_time = now;
601 }
602 }
603 else if (domain->timer_armed) {
604 hrtimer_try_to_cancel(&(domain->idle_enforcement_timer));
605 domain->timer_armed = 0;
606 }
580} 607}
581 608
582//assuming prev is previous task running on the processor before calling schedule 609//assuming prev is previous task running on the processor before calling schedule
@@ -603,6 +630,12 @@ static struct task_struct *edfsc_gschedule(struct task_struct *prev)
603 BUG_ON(entry->scheduled && !is_realtime(prev)); 630 BUG_ON(entry->scheduled && !is_realtime(prev));
604 BUG_ON(is_realtime(prev) && !entry->scheduled); 631 BUG_ON(is_realtime(prev) && !entry->scheduled);
605 632
633 //TODO
634 // condition when a container is "scheduled" but there are no realtime tasks
635 if (is_container(entry->scheduled) && (!prev || !is_realtime(prev)))
636 tsk_rt(entry->scheduled)->job_params.exec_time += litmus_clock()
637 - tsk_rt(entry->scheduled)->edfsc_params.domain->scheduled_last_exec_time;
638
606 // update container budget if prev was a fixed or background scheduled task 639 // update container budget if prev was a fixed or background scheduled task
607 if (entry->scheduled && prev && is_realtime(prev) && prev != entry->scheduled) { 640 if (entry->scheduled && prev && is_realtime(prev) && prev != entry->scheduled) {
608 // FIXME prev or entry->scheduled can be NULL, right? 641 // FIXME prev or entry->scheduled can be NULL, right?
@@ -723,7 +756,14 @@ static struct task_struct *edfsc_gschedule(struct task_struct *prev)
723 TRACE("becomes idle at %llu.\n", litmus_clock()); 756 TRACE("becomes idle at %llu.\n", litmus_clock());
724#endif 757#endif
725 758
726 return next; 759 if (is_container(next)) {
760 if (budget_precisely_enforced(next)) {
761 manage_idle_enforcement_timer(next);
762 }
763 return NULL;
764 }
765 else
766 return next;
727} 767}
728 768
729/* 769/*
@@ -940,6 +980,7 @@ static void edfsc_task_new(struct task_struct* t, int on_rq, int is_scheduled)
940 * nothing was running before, update our state, and then reschedule. 980 * nothing was running before, update our state, and then reschedule.
941 * The task will be fixed to a container during the reschedule. 981 * The task will be fixed to a container during the reschedule.
942 */ 982 */
983 //Something needs fixing here
943 BUG_ON(entry->scheduled); 984 BUG_ON(entry->scheduled);
944 entry->scheduled = t; 985 entry->scheduled = t;
945 preempt(entry); 986 preempt(entry);
@@ -1111,6 +1152,20 @@ static struct sched_plugin edfsc_plugin __cacheline_aligned_in_smp = {
1111 .get_domain_proc_info = edfsc_get_domain_proc_info, 1152 .get_domain_proc_info = edfsc_get_domain_proc_info,
1112}; 1153};
1113 1154
1155//timeout for timer enforcing budget of empty container
1156static enum hrtimer_restart on_idle_enforcement_timeout(struct hrtimer *timer)
1157{
1158 cont_domain_t* domain = container_of(timer, cont_domain_t, idle_enforcement_timer);
1159
1160 unsigned long flags;
1161
1162 local_irq_save(flags);
1163 domain->timer_armed = 0;
1164 litmus_reschedule_local();
1165 local_irq_restore(flags);
1166
1167 return HRTIMER_NORESTART;
1168}
1114 1169
1115static int __init init_edfsc(void) 1170static int __init init_edfsc(void)
1116{ 1171{
@@ -1141,6 +1196,8 @@ static int __init init_edfsc(void)
1141 edf_domain_init(&container_domains[i].domain, c_check_resched, NULL); 1196 edf_domain_init(&container_domains[i].domain, c_check_resched, NULL);
1142 container_domains[i].scheduled = NULL; 1197 container_domains[i].scheduled = NULL;
1143 container_domains[i].container = &container_tasks[i]; 1198 container_domains[i].container = &container_tasks[i];
1199 hrtimer_init(&(container_domains[i].idle_enforcement_timer), CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
1200 container_domains[i].idle_enforcement_timer.function = on_idle_enforcement_timeout;
1144 1201
1145 container_tasks[i].policy = SCHED_LITMUS; 1202 container_tasks[i].policy = SCHED_LITMUS;
1146 tsk_rt(&container_tasks[i])->scheduled_on = NO_CPU; 1203 tsk_rt(&container_tasks[i])->scheduled_on = NO_CPU;
@@ -1149,6 +1206,7 @@ static int __init init_edfsc(void)
1149 LITMUS_QUANTUM_LENGTH_NS; 1206 LITMUS_QUANTUM_LENGTH_NS;
1150 tsk_rt(&container_tasks[i])->task_params.relative_deadline = 1207 tsk_rt(&container_tasks[i])->task_params.relative_deadline =
1151 LITMUS_QUANTUM_LENGTH_NS; 1208 LITMUS_QUANTUM_LENGTH_NS;
1209 tsk_rt(&container_tasks[i])->task_params.budget_policy == PRECISE_ENFORCEMENT;
1152 tsk_rt(&container_tasks[i])->edfsc_params.container_task = NULL; 1210 tsk_rt(&container_tasks[i])->edfsc_params.container_task = NULL;
1153 tsk_rt(&container_tasks[i])->domain = &gsched_domain; 1211 tsk_rt(&container_tasks[i])->domain = &gsched_domain;
1154 tsk_rt(&container_tasks[i])->edfsc_params.domain = &container_domains[i]; 1212 tsk_rt(&container_tasks[i])->edfsc_params.domain = &container_domains[i];