diff options
author | Tanya Amert <tamert@cs.unc.edu> | 2020-10-19 13:20:11 -0400 |
---|---|---|
committer | Tanya Amert <tamert@cs.unc.edu> | 2020-10-19 13:20:11 -0400 |
commit | 87160e4752860f528acd9f59b016f55cfed25b7d (patch) | |
tree | ea88f702efab85a94bc61a87aae09b64515eb42e | |
parent | 79bdff982e50975d2d2bae1471ac4d879dfec526 (diff) |
Have a hard-coded component-wide forbidden zone working.
-rw-r--r-- | include/litmus/reservations/gedf_reservation.h | 3 | ||||
-rw-r--r-- | include/litmus/reservations/table_driven_ext_reservation.h | 12 | ||||
-rw-r--r-- | litmus/reservations/gedf_reservation.c | 82 |
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 | /* ************************************************************************** */ |
7 | struct mtd_reservation { | 7 | struct 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 | ||
18 | long mtd_res_install_table( | 18 | long 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 | ||
966 | int gedf_env_omlp_lock(struct litmus_lock* l) | 962 | int 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; |