aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorztong <ztong@cs.unc.edu>2021-06-12 17:10:39 -0400
committerztong <ztong@cs.unc.edu>2021-06-12 17:10:39 -0400
commitd81563a019782d03b27f12034a42f5e58040a622 (patch)
tree8b7bcea31f34a4d88a8e0f63a9f6bbdb6e9760b8
parent445fda17c6f68e6185b05e07cbd6632bfc1b21c3 (diff)
fixes for RTSSbudgeting
-rw-r--r--include/litmus/reservations/gedf_reservation.h5
-rw-r--r--litmus/reservations/gedf_reservation.c69
2 files changed, 48 insertions, 26 deletions
diff --git a/include/litmus/reservations/gedf_reservation.h b/include/litmus/reservations/gedf_reservation.h
index 8f4d99f7c922..faf481a1ab6f 100644
--- a/include/litmus/reservations/gedf_reservation.h
+++ b/include/litmus/reservations/gedf_reservation.h
@@ -64,7 +64,10 @@ struct gedf_reservation_environment {
64 struct list_head all_reservations; 64 struct list_head all_reservations;
65 65
66 /* number of active cpus in reservation */ 66 /* number of active cpus in reservation */
67 volatile int num_cpus; 67 int num_cpus;
68
69 /* numbers of cpus reservation is active on */
70 int num_active_cpus;
68 71
69 /* array of gedf cpu entries */ 72 /* array of gedf cpu entries */
70 struct gedf_cpu_entry* cpu_entries; 73 struct gedf_cpu_entry* cpu_entries;
diff --git a/litmus/reservations/gedf_reservation.c b/litmus/reservations/gedf_reservation.c
index 41a4feeb6680..1c604212acf2 100644
--- a/litmus/reservations/gedf_reservation.c
+++ b/litmus/reservations/gedf_reservation.c
@@ -201,7 +201,7 @@ static void check_for_preemptions(struct gedf_reservation_environment* gedf_env)
201 } 201 }
202 } 202 }
203 203
204 if (last->linked && last->linked->res.cur_budget) 204 if (last->linked)
205 requeue(gedf_env, last->linked); 205 requeue(gedf_env, last->linked);
206 206
207 link_task_to_cpu(gedf_env, gedf_res, last); 207 link_task_to_cpu(gedf_env, gedf_res, last);
@@ -685,6 +685,8 @@ static void gedf_env_resume(
685 /* adds cpu back to scheduling consideration */ 685 /* adds cpu back to scheduling consideration */
686 bheap_insert(cpu_lower_prio, &gedf_env->cpu_heap, entry->hn); 686 bheap_insert(cpu_lower_prio, &gedf_env->cpu_heap, entry->hn);
687 gedf_env->num_cpus++; 687 gedf_env->num_cpus++;
688 gedf_env->num_active_cpus = (gedf_env->num_cpus > gedf_env->num_active_cpus) ?
689 gedf_env->num_cpus : gedf_env->num_active_cpus;
688 690
689 raw_spin_unlock_irqrestore(&gedf_env->domain.ready_lock, flags); 691 raw_spin_unlock_irqrestore(&gedf_env->domain.ready_lock, flags);
690 692
@@ -715,7 +717,15 @@ static struct task_struct* gedf_env_dispatch(
715 if (entry->scheduled) 717 if (entry->scheduled)
716 np = entry->scheduled->res.ops->is_np(&entry->scheduled->res, cpu); 718 np = entry->scheduled->res.ops->is_np(&entry->scheduled->res, cpu);
717 719
720 /* if flagged for removal from environment, invoke shutdown callback */
721 if (entry->scheduled && entry->scheduled->will_remove) {
722 /* assumed to already been unlinked by whatever set will_remove */
723 entry->scheduled->res.ops->shutdown(&entry->scheduled->res);
724 entry->scheduled = NULL;
725 }
726
718 raw_spin_lock_irqsave(&gedf_env->domain.ready_lock, flags); 727 raw_spin_lock_irqsave(&gedf_env->domain.ready_lock, flags);
728
719 /* Budget replenishment has to happen under a lock, otherwise 729 /* Budget replenishment has to happen under a lock, otherwise
720 * check_for_preemptions() may be called concurrently, and try to link and 730 * check_for_preemptions() may be called concurrently, and try to link and
721 * schedule our now-out-of-budget task on another CPU. This would result in 731 * schedule our now-out-of-budget task on another CPU. This would result in
@@ -727,7 +737,8 @@ static struct task_struct* gedf_env_dispatch(
727 entry->scheduled->res.ops->replenish_budget(&entry->scheduled->res, cpu); 737 entry->scheduled->res.ops->replenish_budget(&entry->scheduled->res, cpu);
728 /* unlink and requeue if not blocked and not np*/ 738 /* unlink and requeue if not blocked and not np*/
729 if (!entry->scheduled->blocked && 739 if (!entry->scheduled->blocked &&
730 !entry->scheduled->res.ops->is_np(&entry->scheduled->res, cpu)) { 740 !entry->scheduled->res.ops->is_np(&entry->scheduled->res, cpu) &&
741 !entry->scheduled->will_remove) {
731 unlink(gedf_env, entry->scheduled); 742 unlink(gedf_env, entry->scheduled);
732 requeue(gedf_env, entry->scheduled); 743 requeue(gedf_env, entry->scheduled);
733 check_for_preemptions(gedf_env); 744 check_for_preemptions(gedf_env);
@@ -798,13 +809,6 @@ static void gedf_env_update_time(
798 * Therefore, no lock is needed for this operation 809 * Therefore, no lock is needed for this operation
799 */ 810 */
800 entry->scheduled->res.ops->drain_budget(&entry->scheduled->res, how_much, cpu); 811 entry->scheduled->res.ops->drain_budget(&entry->scheduled->res, how_much, cpu);
801
802 /* if flagged for removal from environment, invoke shutdown callback */
803 if (entry->scheduled->will_remove) {
804 /* assumed to already been unlinked by whatever set will_remove */
805 entry->scheduled->res.ops->shutdown(&entry->scheduled->res);
806 entry->scheduled = NULL;
807 }
808} 812}
809 813
810/* callback for how the domain will release jobs */ 814/* callback for how the domain will release jobs */
@@ -990,8 +994,12 @@ static struct task_struct* omlp_dequeue(struct omlp_semaphore *sem)
990{ 994{
991 struct task_struct* first = __waitqueue_remove_first(&sem->fifo_wait); 995 struct task_struct* first = __waitqueue_remove_first(&sem->fifo_wait);
992 996
993 if (first && !omlp_move(sem)) 997 /* don't replace tmp with omlp_move! shortcircuiting will break omlp for m=1 */
998 int tmp = omlp_move(sem);
999 if (first && !tmp)
994 sem->num_free++; 1000 sem->num_free++;
1001 if (!first && tmp)
1002 first = __waitqueue_remove_first(&sem->fifo_wait);
995 1003
996 return first; 1004 return first;
997} 1005}
@@ -1119,6 +1127,7 @@ static enum hrtimer_restart wake_fz_waiter(struct hrtimer* timer)
1119{ 1127{
1120 struct omlp_semaphore* sem = container_of(timer, struct omlp_semaphore, wake_timer); 1128 struct omlp_semaphore* sem = container_of(timer, struct omlp_semaphore, wake_timer);
1121 sem->policed = 0; 1129 sem->policed = 0;
1130 BUG_ON(!sem->owner);
1122 wake_up_process(sem->owner); 1131 wake_up_process(sem->owner);
1123 1132
1124 return HRTIMER_NORESTART; 1133 return HRTIMER_NORESTART;
@@ -1129,6 +1138,7 @@ static lt_t next_component_start(struct mtd_reservation* mtd_res, int cpu)
1129 int i_index; 1138 int i_index;
1130 lt_t resume_time; 1139 lt_t resume_time;
1131 1140
1141 BUG_ON(mtd_res->major_cycle_start[cpu] + mtd_res->intervals[cpu][mtd_res->interval_index[cpu]].start > litmus_clock());
1132 i_index = (mtd_res->interval_index[cpu] + 1) % mtd_res->num_intervals[cpu]; 1142 i_index = (mtd_res->interval_index[cpu] + 1) % mtd_res->num_intervals[cpu];
1133 resume_time = mtd_res->major_cycle_start[cpu]; 1143 resume_time = mtd_res->major_cycle_start[cpu];
1134 if (!i_index) 1144 if (!i_index)
@@ -1169,10 +1179,10 @@ int gedf_env_omlp_lock_cs(struct litmus_lock* l, lt_t cs_len)
1169 init_prio_waitqueue_entry(&wait, t, ULLONG_MAX - t_res->priority); 1179 init_prio_waitqueue_entry(&wait, t, ULLONG_MAX - t_res->priority);
1170 wait.wq.cs_len = cs_len; 1180 wait.wq.cs_len = cs_len;
1171 1181
1172 set_current_state(TASK_UNINTERRUPTIBLE);
1173
1174 omlp_enqueue(sem, &wait); 1182 omlp_enqueue(sem, &wait);
1175 1183
1184 set_current_state(TASK_UNINTERRUPTIBLE);
1185
1176 /* check if we need to activate priority inheritance */ 1186 /* check if we need to activate priority inheritance */
1177 if (higher_res_prio(t_res, sem->hp_waiter_res)) { 1187 if (higher_res_prio(t_res, sem->hp_waiter_res)) {
1178 sem->hp_waiter = t; 1188 sem->hp_waiter = t;
@@ -1251,6 +1261,7 @@ static int gedf_env_omlp_access_fz_check(struct litmus_lock* l, lt_t fz_len, lt_
1251 schedule(); 1261 schedule();
1252 TS_LOCK_RESUME; 1262 TS_LOCK_RESUME;
1253 } 1263 }
1264
1254 sem->policed = 0; 1265 sem->policed = 0;
1255 1266
1256 t_res = (struct ext_reservation *) tsk_rt(t)->plugin_state; 1267 t_res = (struct ext_reservation *) tsk_rt(t)->plugin_state;
@@ -1275,22 +1286,23 @@ static int gedf_env_omlp_access_fz_check(struct litmus_lock* l, lt_t fz_len, lt_
1275 cutahead_t = omlp_cutahead(sem, ULLONG_MAX); 1286 cutahead_t = omlp_cutahead(sem, ULLONG_MAX);
1276 if (cutahead_t) { 1287 if (cutahead_t) {
1277 wake_up_process(cutahead_t); 1288 wake_up_process(cutahead_t);
1278 local_irq_restore(flags);
1279 set_current_state(TASK_UNINTERRUPTIBLE); 1289 set_current_state(TASK_UNINTERRUPTIBLE);
1280 TS_LOCK_SUSPEND; 1290 TS_LOCK_SUSPEND;
1291 local_irq_restore(flags);
1281 schedule(); 1292 schedule();
1282 TS_LOCK_RESUME; 1293 TS_LOCK_RESUME;
1283 } else { 1294 } else {
1284 /* go on a wait queue to be woken up when the parent reservation 1295 /* go on a wait queue to be woken up when the parent reservation
1285 * is next scheduled */ 1296 * is next scheduled */
1286 BUG_ON(t != sem->owner); 1297 BUG_ON(t != sem->owner);
1287 resume_time = next_component_start(mtd_res, cpu); 1298 resume_time = max(next_component_start(mtd_res, cpu), litmus_clock());
1288 hrtimer_start(&sem->wake_timer, 1299 hrtimer_start(&sem->wake_timer,
1289 ns_to_ktime(resume_time), 1300 ns_to_ktime(resume_time),
1290 HRTIMER_MODE_ABS_PINNED_HARD); 1301 HRTIMER_MODE_ABS_PINNED_HARD);
1291 local_irq_restore(flags); 1302 BUG_ON(!hrtimer_active(&sem->wake_timer));
1292 set_current_state(TASK_UNINTERRUPTIBLE); 1303 set_current_state(TASK_INTERRUPTIBLE);
1293 TS_LOCK_SUSPEND; 1304 TS_LOCK_SUSPEND;
1305 local_irq_restore(flags);