aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTanya Amert <tamert@cs.unc.edu>2020-10-19 13:20:11 -0400
committerTanya Amert <tamert@cs.unc.edu>2020-10-19 13:20:11 -0400
commit87160e4752860f528acd9f59b016f55cfed25b7d (patch)
treeea88f702efab85a94bc61a87aae09b64515eb42e
parent79bdff982e50975d2d2bae1471ac4d879dfec526 (diff)
Have a hard-coded component-wide forbidden zone working.
-rw-r--r--include/litmus/reservations/gedf_reservation.h3
-rw-r--r--include/litmus/reservations/table_driven_ext_reservation.h12
-rw-r--r--litmus/reservations/gedf_reservation.c82
3 files changed, 54 insertions, 43 deletions
diff --git a/include/litmus/reservations/gedf_reservation.h b/include/litmus/reservations/gedf_reservation.h
index 927e83f4bc2e..d9694fa3ac64 100644
--- a/include/litmus/reservations/gedf_reservation.h
+++ b/include/litmus/reservations/gedf_reservation.h
@@ -69,7 +69,8 @@ struct gedf_reservation_environment {
69 69
70#ifdef CONFIG_LITMUS_LOCKING 70#ifdef CONFIG_LITMUS_LOCKING
71 /* reservations sleeping due to forbidden zones */ 71 /* reservations sleeping due to forbidden zones */
72 wait_queue_head_t fz_waiters; 72 int num_waiter_queues;
73 wait_queue_head_t* fz_waiters;
73#endif 74#endif
74}; 75};
75 76
diff --git a/include/litmus/reservations/table_driven_ext_reservation.h b/include/litmus/reservations/table_driven_ext_reservation.h
index 36d20c91a8dc..c906ceb785bb 100644
--- a/include/litmus/reservations/table_driven_ext_reservation.h
+++ b/include/litmus/reservations/table_driven_ext_reservation.h
@@ -5,14 +5,14 @@
5 5
6/* ************************************************************************** */ 6/* ************************************************************************** */
7struct mtd_reservation { 7struct mtd_reservation {
8 struct reservation res[4]; 8 struct reservation res[NR_CPUS];
9 lt_t major_cycle; 9 lt_t major_cycle;
10 unsigned int interval_index[4]; 10 unsigned int interval_index[NR_CPUS];
11 unsigned int num_intervals[4]; 11 unsigned int num_intervals[NR_CPUS];
12 struct lt_interval* intervals[4]; 12 struct lt_interval* intervals[NR_CPUS];
13 13
14 struct lt_interval cur_interval[4]; 14 struct lt_interval cur_interval[NR_CPUS];
15 lt_t major_cycle_start[4]; 15 lt_t major_cycle_start[NR_CPUS];
16}; 16};
17 17
18long mtd_res_install_table( 18long mtd_res_install_table(
diff --git a/litmus/reservations/gedf_reservation.c b/litmus/reservations/gedf_reservation.c
index 0d02e31bac89..b037f63ed119 100644
--- a/litmus/reservations/gedf_reservation.c
+++ b/litmus/reservations/gedf_reservation.c
@@ -555,6 +555,10 @@ static void gedf_env_resume(
555 unsigned long flags; 555 unsigned long flags;
556 // Needs to be volatile or it may be optimized to gedf_env->num_cpus 556 // Needs to be volatile or it may be optimized to gedf_env->num_cpus
557 volatile int tmp_cpus; 557 volatile int tmp_cpus;
558 // For waking up forbidden-zone waiters
559 int i;
560 struct task_struct *next;
561 struct reservation *next_res;
558 562
559 gedf_env = container_of(env, struct gedf_reservation_environment, env); 563 gedf_env = container_of(env, struct gedf_reservation_environment, env);
560 entry = &gedf_env->cpu_entries[cpu]; 564 entry = &gedf_env->cpu_entries[cpu];
@@ -584,26 +588,18 @@ static void gedf_env_resume(
584 domain_resume_releases(&gedf_env->domain); 588 domain_resume_releases(&gedf_env->domain);
585 589
586#ifdef CONFIG_LITMUS_LOCKING 590#ifdef CONFIG_LITMUS_LOCKING
587 // Only the first cpu to resume should wake up forbidden-zone waiters 591 // Wake up any forbidden-zone waiters
588 if (!tmp_cpus) { 592 for (i = 0; i < gedf_env->num_waiter_queues; i++) {
589 // if (gedf_env->env.res->id == 1) 593 if (i == cpu)
590 // printk("[%u] About to check for waiters.\n", gedf_env->env.res->id); 594 continue;
591 595
592 // Wake up any forbidden-zone waiters 596 spin_lock_irqsave(&gedf_env->fz_waiters[i].lock, flags);
593 spin_lock_irqsave(&gedf_env->fz_waiters.lock, flags); 597 while ( (next = __waitqueue_remove_first(&gedf_env->fz_waiters[i])) ) {
594 598 next_res = (struct reservation *) tsk_rt(next)->plugin_state;
595 struct task_struct *next; 599 wake_up_process(next);
596 while ((next) = __waitqueue_remove_first(&gedf_env->fz_waiters)) {
597 printk("[%u] Waking up process %d, state=%d.\n", gedf_env->env.res->id, next->pid, next->state);
598
599 /* wake up next by re-adding it to the gedf env */
600 struct reservation *next_res = (struct reservation *) tsk_rt(next)->plugin_state;
601 gedf_env_add_res(env, next_res, cpu);
602
603 printk("[%u] Woke up %d.\n", gedf_env->env.res->id, next->pid);
604 } 600 }
605 601
606 spin_unlock_irqrestore(&gedf_env->fz_waiters.lock, flags); 602 spin_unlock_irqrestore(&gedf_env->fz_waiters[i].lock, flags);
607 } 603 }
608#endif 604#endif
609} 605}
@@ -965,15 +961,20 @@ static struct task_struct* omlp_find_hp_waiter(struct omlp_semaphore *sem,
965 961
966int gedf_env_omlp_lock(struct litmus_lock* l) 962int gedf_env_omlp_lock(struct litmus_lock* l)
967{ 963{
964 // The task and the semaphore
968 struct task_struct* t = current; 965 struct task_struct* t = current;
969 struct omlp_semaphore *sem = omlp_from_lock(l); 966 struct omlp_semaphore *sem = omlp_from_lock(l);
970 prio_wait_queue_t wait; 967 prio_wait_queue_t wait;
971 wait_queue_t fz_wait;
972 unsigned long flags; 968 unsigned long flags;
969 // Various scheduler entities
973 struct reservation *t_res, *o_res; 970 struct reservation *t_res, *o_res;
974 struct gedf_reservation *gedf_res; 971 struct gedf_reservation *gedf_res;
975 struct gedf_reservation_environment *gedf_env; 972 struct gedf_reservation_environment *gedf_env;
976 lt_t remaining_component_budget, fz_length; 973 // Forbidden zones
974 unsigned int cpu;
975 lt_t timeslice_end, remaining_component_budget, fz_length;
976 wait_queue_t fz_wait;
977 struct mtd_reservation *mtd_res;
977 978
978 if (!is_realtime(t)) 979 if (!is_realtime(t))
979 return -EPERM; 980 return -EPERM;
@@ -1039,39 +1040,36 @@ int gedf_env_omlp_lock(struct litmus_lock* l)
1039 * thus might not reflect the current remaining budget 1040 * thus might not reflect the current remaining budget
1040 * for the component */ 1041 * for the component */
1041 gedf_env = container_of(t_res->par_env, struct gedf_reservation_environment, env); 1042 gedf_env = container_of(t_res->par_env, struct gedf_reservation_environment, env);
1042 spin_lock_irqsave(&gedf_env->fz_waiters.lock, flags); 1043 spin_lock_irqsave(&gedf_env->fz_waiters[0].lock, flags);
1044
1045 cpu = smp_processor_id();
1043 1046
1044 unsigned int cpu = smp_processor_id(); 1047 spin_unlock_irqrestore(&gedf_env->fz_waiters[0].lock, flags);
1045 struct mtd_reservation *mtd_res = (struct mtd_reservation*)t_res->par_env->res; 1048 spin_lock_irqsave(&gedf_env->fz_waiters[cpu].lock, flags);
1046 lt_t timeslice_end = mtd_res->cur_interval[cpu].end + mtd_res->major_cycle_start[cpu]; 1049
1050 mtd_res = (struct mtd_reservation*)t_res->par_env->res;
1051 timeslice_end = mtd_res->cur_interval[cpu].end + mtd_res->major_cycle_start[cpu];
1047 remaining_component_budget = timeslice_end - litmus_clock(); 1052 remaining_component_budget = timeslice_end - litmus_clock();
1048 1053
1049 fz_length = 100 * 1000000LL; // for now, hard-coded at 100ms 1054 fz_length = 100 * 1000000LL; // for now, hard-coded at 100ms
1050 if (remaining_component_budget < fz_length) { 1055 if (remaining_component_budget < fz_length) {
1051 /* go on a wait queue to be woken up when the parent reservation 1056 /* go on a wait queue to be woken up when the parent reservation
1052 * is next scheduled */ 1057 * is next scheduled */
1053 printk("%d in the forbidden zone, going on wait queue (budget left: %llu)\n",
1054 t->pid, remaining_component_budget);
1055
1056 init_waitqueue_entry(&fz_wait, t); 1058 init_waitqueue_entry(&fz_wait, t);
1057 set_task_state(t, TASK_UNINTERRUPTIBLE); 1059 set_task_state(t, TASK_UNINTERRUPTIBLE);
1058 __add_wait_queue_tail_exclusive(&gedf_env->fz_waiters, &fz_wait); 1060 __add_wait_queue_tail_exclusive(&gedf_env->fz_waiters[cpu], &fz_wait);
1059 1061
1060 TS_LOCK_SUSPEND; 1062 TS_LOCK_SUSPEND;
1061 1063
1062 spin_unlock_irqrestore(&gedf_env->fz_waiters.lock, flags); 1064 spin_unlock_irqrestore(&gedf_env->fz_waiters[cpu].lock, flags);
1063 1065
1064 BUG_ON(!gedf_res->linked_on && !bheap_node_in_heap(t_res->heap_node)); 1066 BUG_ON(!gedf_res->linked_on && !bheap_node_in_heap(t_res->heap_node));
1065 1067
1066 schedule(); // calls gedf_env_remove_res() 1068 schedule();
1067 1069
1068 TS_LOCK_RESUME; 1070 TS_LOCK_RESUME;
1069
1070 printk("%d awake!\n", t->pid);
1071 } else { 1071 } else {
1072 printk("%d is not in the FZ, budget remaining is %llu\n", 1072 spin_unlock_irqrestore(&gedf_env->fz_waiters[cpu].lock, flags);
1073 t->pid, remaining_component_budget);
1074 spin_unlock_irqrestore(&gedf_env->fz_waiters.lock, flags);
1075 } 1073 }
1076 1074
1077 return 0; 1075 return 0;
@@ -1268,6 +1266,15 @@ long alloc_gedf_reservation_environment(
1268 kfree(gedf_env); 1266 kfree(gedf_env);
1269 return -ENOMEM; 1267 return -ENOMEM;
1270 } 1268 }
1269#ifdef CONFIG_LITMUS_LOCKING
1270 gedf_env->fz_waiters = kzalloc(sizeof(wait_queue_head_t)*total_cpus, GFP_ATOMIC);
1271 if (!gedf_env->fz_waiters) {
1272 kfree(gedf_env->cpu_entries);
1273 kfree(gedf_env->cpu_node);
1274 kfree(gedf_env);
1275 return -ENOMEM;
1276 }
1277#endif
1271 1278
1272 /* set environment callback actions */ 1279 /* set environment callback actions */
1273 gedf_env->env.ops = &gedf_env_ops; 1280 gedf_env->env.ops = &gedf_env_ops;
@@ -1287,7 +1294,10 @@ long alloc_gedf_reservation_environment(
1287 rt_domain_init(&gedf_env->domain, edf_ready_order, NULL, gedf_env_release_jobs); 1294 rt_domain_init(&gedf_env->domain, edf_ready_order, NULL, gedf_env_release_jobs);
1288 1295
1289#ifdef CONFIG_LITMUS_LOCKING 1296#ifdef CONFIG_LITMUS_LOCKING
1290 init_waitqueue_head(&gedf_env->fz_waiters); 1297 gedf_env->num_waiter_queues = max_cpus;
1298 for (i = 0; i < max_cpus; i++) {
1299 init_waitqueue_head(&gedf_env->fz_waiters[i]);
1300 }
1291#endif 1301#endif
1292 1302
1293 *_env = gedf_env; 1303 *_env = gedf_env;