diff options
| -rw-r--r-- | include/litmus/ctrlpage.h | 6 | ||||
| -rw-r--r-- | include/litmus/locking.h | 5 | ||||
| -rw-r--r-- | include/litmus/reservations/gedf_reservation.h | 6 | ||||
| -rw-r--r-- | litmus/ctrldev.c | 6 | ||||
| -rw-r--r-- | litmus/locking.c | 27 | ||||
| -rw-r--r-- | litmus/reservations/gedf_reservation.c | 161 |
6 files changed, 186 insertions, 25 deletions
diff --git a/include/litmus/ctrlpage.h b/include/litmus/ctrlpage.h index f7b03e1aedd6..445857d2f38b 100644 --- a/include/litmus/ctrlpage.h +++ b/include/litmus/ctrlpage.h | |||
| @@ -74,6 +74,7 @@ typedef enum { | |||
| 74 | LRT_wait_for_ts_release, | 74 | LRT_wait_for_ts_release, |
| 75 | LRT_release_ts, | 75 | LRT_release_ts, |
| 76 | LRT_get_current_budget, | 76 | LRT_get_current_budget, |
| 77 | LRT_access_forbidden_zone_check, | ||
| 77 | } litmus_syscall_id_t; | 78 | } litmus_syscall_id_t; |
| 78 | 79 | ||
| 79 | union litmus_syscall_args { | 80 | union litmus_syscall_args { |
| @@ -98,6 +99,11 @@ union litmus_syscall_args { | |||
| 98 | lt_t __user *expended; | 99 | lt_t __user *expended; |
| 99 | lt_t __user *remaining; | 100 | lt_t __user *remaining; |
| 100 | } get_current_budget; | 101 | } get_current_budget; |
| 102 | |||
| 103 | struct { | ||
| 104 | uint32_t sem_od; | ||
| 105 | lt_t fz_len; | ||
| 106 | } access_forbidden_zone_check; | ||
| 101 | }; | 107 | }; |
| 102 | 108 | ||
| 103 | 109 | ||
diff --git a/include/litmus/locking.h b/include/litmus/locking.h index 4d7b870cb443..0dae82711717 100644 --- a/include/litmus/locking.h +++ b/include/litmus/locking.h | |||
| @@ -1,6 +1,8 @@ | |||
| 1 | #ifndef LITMUS_LOCKING_H | 1 | #ifndef LITMUS_LOCKING_H |
| 2 | #define LITMUS_LOCKING_H | 2 | #define LITMUS_LOCKING_H |
| 3 | 3 | ||
| 4 | #include <litmus/rt_param.h> | ||
| 5 | |||
| 4 | struct litmus_lock_ops; | 6 | struct litmus_lock_ops; |
| 5 | 7 | ||
| 6 | /* Generic base struct for LITMUS^RT userspace semaphores. | 8 | /* Generic base struct for LITMUS^RT userspace semaphores. |
| @@ -21,6 +23,9 @@ struct litmus_lock_ops { | |||
| 21 | int (*lock)(struct litmus_lock*); | 23 | int (*lock)(struct litmus_lock*); |
| 22 | int (*unlock)(struct litmus_lock*); | 24 | int (*unlock)(struct litmus_lock*); |
| 23 | 25 | ||
| 26 | /* Current tries to access protected resource (mandatory methods if supported). */ | ||
| 27 | int (*access_forbidden_zone_check)(struct litmus_lock*, lt_t fz_len); | ||
| 28 | |||
| 24 | /* The lock is no longer being referenced (mandatory method). */ | 29 | /* The lock is no longer being referenced (mandatory method). */ |
| 25 | void (*deallocate)(struct litmus_lock*); | 30 | void (*deallocate)(struct litmus_lock*); |
| 26 | }; | 31 | }; |
diff --git a/include/litmus/reservations/gedf_reservation.h b/include/litmus/reservations/gedf_reservation.h index 08961e7931a2..d9694fa3ac64 100644 --- a/include/litmus/reservations/gedf_reservation.h +++ b/include/litmus/reservations/gedf_reservation.h | |||
| @@ -66,6 +66,12 @@ struct gedf_reservation_environment { | |||
| 66 | struct bheap_node* cpu_node; | 66 | struct bheap_node* cpu_node; |
| 67 | 67 | ||
| 68 | rt_domain_t domain; | 68 | rt_domain_t domain; |
| 69 | |||
| 70 | #ifdef CONFIG_LITMUS_LOCKING | ||
| 71 | /* reservations sleeping due to forbidden zones */ | ||
| 72 | int num_waiter_queues; | ||
| 73 | wait_queue_head_t* fz_waiters; | ||
| 74 | #endif | ||
| 69 | }; | 75 | }; |
| 70 | 76 | ||
| 71 | long alloc_gedf_reservation_environment( | 77 | long alloc_gedf_reservation_environment( |
diff --git a/litmus/ctrldev.c b/litmus/ctrldev.c index cc74c5afa5c6..7090f9bc67ad 100644 --- a/litmus/ctrldev.c +++ b/litmus/ctrldev.c | |||
| @@ -130,6 +130,7 @@ asmlinkage long sys_od_open(int fd, int type, int obj_id, void* __user config); | |||
| 130 | asmlinkage long sys_od_close(int od); | 130 | asmlinkage long sys_od_close(int od); |
| 131 | asmlinkage long sys_complete_job(void); | 131 | asmlinkage long sys_complete_job(void); |
| 132 | asmlinkage long sys_litmus_lock(int lock_od); | 132 | asmlinkage long sys_litmus_lock(int lock_od); |
| 133 | asmlinkage long sys_access_forbidden_zone_check(int lock_od, lt_t fz_len); | ||
| 133 | asmlinkage long sys_litmus_unlock(int lock_od); | 134 | asmlinkage long sys_litmus_unlock(int lock_od); |
| 134 | asmlinkage long sys_wait_for_job_release(unsigned int job); | 135 | asmlinkage long sys_wait_for_job_release(unsigned int job); |
| 135 | asmlinkage long sys_wait_for_ts_release(void); | 136 | asmlinkage long sys_wait_for_ts_release(void); |
| @@ -155,6 +156,7 @@ static long litmus_ctrl_ioctl(struct file *filp, | |||
| 155 | case LRT_reservation_create: | 156 | case LRT_reservation_create: |
| 156 | case LRT_get_current_budget: | 157 | case LRT_get_current_budget: |
| 157 | case LRT_od_open: | 158 | case LRT_od_open: |
| 159 | case LRT_access_forbidden_zone_check: | ||
| 158 | /* multiple arguments => need to get args via pointer */ | 160 | /* multiple arguments => need to get args via pointer */ |
| 159 | /* get syscall parameters */ | 161 | /* get syscall parameters */ |
| 160 | if (copy_from_user(&syscall_args, (void*) arg, | 162 | if (copy_from_user(&syscall_args, (void*) arg, |
| @@ -185,6 +187,10 @@ static long litmus_ctrl_ioctl(struct file *filp, | |||
| 185 | syscall_args.od_open.obj_type, | 187 | syscall_args.od_open.obj_type, |
| 186 | syscall_args.od_open.obj_id, | 188 | syscall_args.od_open.obj_id, |
| 187 | syscall_args.od_open.config); | 189 | syscall_args.od_open.config); |
| 190 | case LRT_access_forbidden_zone_check: | ||
| 191 | return sys_access_forbidden_zone_check( | ||
| 192 | syscall_args.access_forbidden_zone_check.sem_od, | ||
| 193 | syscall_args.access_forbidden_zone_check.fz_len); | ||
| 188 | } | 194 | } |
| 189 | 195 | ||
| 190 | 196 | ||
diff --git a/litmus/locking.c b/litmus/locking.c index a1d0515c5613..eb228e6b01af 100644 --- a/litmus/locking.c +++ b/litmus/locking.c | |||
| @@ -97,6 +97,28 @@ asmlinkage long sys_litmus_lock(int lock_od) | |||
| 97 | return err; | 97 | return err; |
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | asmlinkage long sys_access_forbidden_zone_check(int lock_od, lt_t fz_len) | ||
| 101 | { | ||
| 102 | long err = -EINVAL; | ||
| 103 | struct od_table_entry* entry; | ||
| 104 | struct litmus_lock* l; | ||
| 105 | |||
| 106 | TS_SYSCALL_IN_START; | ||
| 107 | |||
| 108 | TS_SYSCALL_IN_END; | ||
| 109 | |||
| 110 | entry = get_entry_for_od(lock_od); | ||
| 111 | if (entry && is_lock(entry)) { | ||
| 112 | l = get_lock(entry); | ||
| 113 | TRACE_CUR("attempts to check forbidden zone 0x%p\n", l); | ||
| 114 | err = l->ops->access_forbidden_zone_check(l, fz_len); | ||
| 115 | } | ||
| 116 | |||
| 117 | TS_SYSCALL_OUT_START; | ||
| 118 | |||
| 119 | return err; | ||
| 120 | } | ||
| 121 | |||
| 100 | asmlinkage long sys_litmus_unlock(int lock_od) | 122 | asmlinkage long sys_litmus_unlock(int lock_od) |
| 101 | { | 123 | { |
| 102 | long err = -EINVAL; | 124 | long err = -EINVAL; |
| @@ -181,6 +203,11 @@ asmlinkage long sys_litmus_lock(int sem_od) | |||
| 181 | return -ENOSYS; | 203 | return -ENOSYS; |
| 182 | } | 204 | } |
| 183 | 205 | ||
| 206 | asmlinkage long sys_forbidden_zone_start(int lock_od, int fz_len) | ||
| 207 | { | ||
| 208 | return -ENOSYS; | ||
| 209 | } | ||
| 210 | |||
| 184 | asmlinkage long sys_litmus_unlock(int sem_od) | 211 | asmlinkage long sys_litmus_unlock(int sem_od) |
| 185 | { | 212 | { |
| 186 | return -ENOSYS; | 213 | return -ENOSYS; |
diff --git a/litmus/reservations/gedf_reservation.c b/litmus/reservations/gedf_reservation.c index 8b39518f4a1a..e5a19e6de663 100644 --- a/litmus/reservations/gedf_reservation.c +++ b/litmus/reservations/gedf_reservation.c | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include <litmus/debug_trace.h> | 13 | #include <litmus/debug_trace.h> |
| 14 | #include <litmus/trace.h> | 14 | #include <litmus/trace.h> |
| 15 | #include <litmus/reservations/gedf_reservation.h> | 15 | #include <litmus/reservations/gedf_reservation.h> |
| 16 | #include <litmus/reservations/table_driven_ext_reservation.h> | ||
| 16 | 17 | ||
| 17 | // Needed to store context during cross-CPU function calls | 18 | // Needed to store context during cross-CPU function calls |
| 18 | struct csd_wrapper { | 19 | struct csd_wrapper { |
| @@ -554,6 +555,10 @@ static void gedf_env_resume( | |||
| 554 | unsigned long flags; | 555 | unsigned long flags; |
| 555 | // 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 |
| 556 | 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; | ||
| 557 | 562 | ||
| 558 | gedf_env = container_of(env, struct gedf_reservation_environment, env); | 563 | gedf_env = container_of(env, struct gedf_reservation_environment, env); |
| 559 | entry = &gedf_env->cpu_entries[cpu]; | 564 | entry = &gedf_env->cpu_entries[cpu]; |
| @@ -581,6 +586,22 @@ static void gedf_env_resume( | |||
| 581 | // Keep this outside the lock. Resuming the timer may have side-effects. | 586 | // Keep this outside the lock. Resuming the timer may have side-effects. |
| 582 | if (!tmp_cpus) | 587 | if (!tmp_cpus) |
| 583 | domain_resume_releases(&gedf_env->domain); | 588 | domain_resume_releases(&gedf_env->domain); |
| 589 | |||
| 590 | #ifdef CONFIG_LITMUS_LOCKING | ||
| 591 | // Wake up any forbidden-zone waiters | ||
| 592 | for (i = 0; i < gedf_env->num_waiter_queues; i++) { | ||
| 593 | if (i == cpu) | ||
| 594 | continue; | ||
| 595 | |||
| 596 | spin_lock_irqsave(&gedf_env->fz_waiters[i].lock, flags); | ||
| 597 | while ( (next = __waitqueue_remove_first(&gedf_env->fz_waiters[i])) ) { | ||
| 598 | next_res = (struct reservation *) tsk_rt(next)->plugin_state; | ||
| 599 | wake_up_process(next); | ||
| 600 | } | ||
| 601 | |||
| 602 | spin_unlock_irqrestore(&gedf_env->fz_waiters[i].lock, flags); | ||
| 603 | } | ||
| 604 | #endif | ||
| 584 | } | 605 | } |
| 585 | 606 | ||
| 586 | static struct task_struct* gedf_env_dispatch( | 607 | static struct task_struct* gedf_env_dispatch( |
| @@ -716,17 +737,17 @@ static void set_priority_inheritance(struct task_struct* t, struct task_struct* | |||
| 716 | struct gedf_cpu_entry* linked_on; | 737 | struct gedf_cpu_entry* linked_on; |
| 717 | int check_preempt = 0; | 738 | int check_preempt = 0; |
| 718 | 739 | ||
| 719 | struct reservation *t_res = (struct reservation *) tsk_rt(t)->plugin_state; | 740 | struct reservation *t_res, *prio_inh_res; |
| 720 | struct reservation *prio_inh_res = (struct reservation *) tsk_rt(prio_inh)->plugin_state; | ||
| 721 | |||
| 722 | struct reservation_environment *env = t_res->par_env; | ||
| 723 | |||
| 724 | struct gedf_reservation_environment *gedf_env; | 741 | struct gedf_reservation_environment *gedf_env; |
| 725 | gedf_env = container_of(env, struct gedf_reservation_environment, env); | ||
| 726 | |||
| 727 | struct gedf_reservation *gedf_res; | 742 | struct gedf_reservation *gedf_res; |
| 743 | |||
| 744 | t_res = (struct reservation *) tsk_rt(t)->plugin_state; | ||
| 728 | gedf_res = container_of(t_res, struct gedf_reservation, res); | 745 | gedf_res = container_of(t_res, struct gedf_reservation, res); |
| 729 | 746 | ||
| 747 | prio_inh_res = (struct reservation *) tsk_rt(prio_inh)->plugin_state; | ||
| 748 | |||
| 749 | gedf_env = container_of(t_res->par_env, struct gedf_reservation_environment, env); | ||
| 750 | |||
| 730 | raw_spin_lock(&gedf_env->domain.ready_lock); | 751 | raw_spin_lock(&gedf_env->domain.ready_lock); |
| 731 | 752 | ||
| 732 | TRACE_TASK(t, "inherits priority from %s/%d\n", prio_inh->comm, prio_inh->pid); | 753 | TRACE_TASK(t, "inherits priority from %s/%d\n", prio_inh->comm, prio_inh->pid); |
| @@ -785,22 +806,23 @@ static void set_priority_inheritance(struct task_struct* t, struct task_struct* | |||
| 785 | /* called with IRQs off */ | 806 | /* called with IRQs off */ |
| 786 | static void clear_priority_inheritance(struct task_struct* t) | 807 | static void clear_priority_inheritance(struct task_struct* t) |
| 787 | { | 808 | { |
| 788 | struct reservation *t_res = (struct reservation *) tsk_rt(t)->plugin_state; | 809 | struct reservation *t_res; |
| 789 | 810 | struct gedf_reservation *gedf_res; | |
| 790 | struct reservation_environment *env = t_res->par_env; | 811 | struct reservation_environment *env; |
| 791 | |||
| 792 | struct gedf_reservation_environment *gedf_env; | 812 | struct gedf_reservation_environment *gedf_env; |
| 793 | gedf_env = container_of(env, struct gedf_reservation_environment, env); | 813 | struct gedf_cpu_entry *entry; |
| 794 | 814 | ||
| 795 | struct gedf_reservation *gedf_res; | 815 | t_res = (struct reservation *) tsk_rt(t)->plugin_state; |
| 796 | gedf_res = container_of(t_res, struct gedf_reservation, res); | 816 | gedf_res = container_of(t_res, struct gedf_reservation, res); |
| 797 | 817 | ||
| 818 | env = t_res->par_env; | ||
| 819 | gedf_env = container_of(env, struct gedf_reservation_environment, env); | ||
| 820 | |||
| 798 | raw_spin_lock(&gedf_env->domain.ready_lock); | 821 | raw_spin_lock(&gedf_env->domain.ready_lock); |
| 799 | 822 | ||
| 800 | /* A job only stops inheriting a priority when it releases a | 823 | /* A job only stops inheriting a priority when it releases a |
| 801 | * resource. Thus we can make the following assumption.*/ | 824 | * resource. Thus we can make the following assumption.*/ |
| 802 | int cpu = smp_processor_id(); | 825 | entry = &gedf_env->cpu_entries[smp_processor_id()]; |
| 803 | struct gedf_cpu_entry *entry = &gedf_env->cpu_entries[cpu]; | ||
| 804 | BUG_ON(entry->scheduled != gedf_res); | 826 | BUG_ON(entry->scheduled != gedf_res); |
| 805 | 827 | ||
| 806 | TRACE_TASK(t, "priority restored\n"); | 828 | TRACE_TASK(t, "priority restored\n"); |
| @@ -938,10 +960,15 @@ static struct task_struct* omlp_find_hp_waiter(struct omlp_semaphore *sem, | |||
| 938 | 960 | ||
| 939 | int gedf_env_omlp_lock(struct litmus_lock* l) | 961 | int gedf_env_omlp_lock(struct litmus_lock* l) |
| 940 | { | 962 | { |
| 963 | // The task and the semaphore | ||
| 941 | struct task_struct* t = current; | 964 | struct task_struct* t = current; |
| 942 | struct omlp_semaphore *sem = omlp_from_lock(l); | 965 | struct omlp_semaphore *sem = omlp_from_lock(l); |
| 943 | prio_wait_queue_t wait; | 966 | // Various scheduler entities |
| 967 | struct reservation *t_res, *o_res; | ||
| 968 | struct gedf_reservation *gedf_res; | ||
| 969 | // Waiting | ||
| 944 | unsigned long flags; | 970 | unsigned long flags; |
| 971 | prio_wait_queue_t wait; | ||
| 945 | 972 | ||
| 946 | if (!is_realtime(t)) | 973 | if (!is_realtime(t)) |
| 947 | return -EPERM; | 974 | return -EPERM; |
| @@ -951,9 +978,8 @@ int gedf_env_omlp_lock(struct litmus_lock* l) | |||
| 951 | if (tsk_rt(t)->num_locks_held) | 978 | if (tsk_rt(t)->num_locks_held) |
| 952 | return -EBUSY; | 979 | return -EBUSY; |
| 953 | 980 | ||
| 954 | struct reservation *t_res = (struct reservation *) tsk_rt(t)->plugin_state; | 981 | t_res = (struct reservation *) tsk_rt(t)->plugin_state; |
| 955 | 982 | gedf_res = container_of(t_res, struct gedf_reservation, res); | |
| 956 | struct gedf_reservation *gedf_res = container_of(t_res, struct gedf_reservation, res); | ||
| 957 | 983 | ||
| 958 | spin_lock_irqsave(&sem->fifo_wait.lock, flags); | 984 | spin_lock_irqsave(&sem->fifo_wait.lock, flags); |
| 959 | 985 | ||
| @@ -971,7 +997,7 @@ int gedf_env_omlp_lock(struct litmus_lock* l) | |||
| 971 | if (higher_res_prio(t_res, sem->hp_waiter_res)) { | 997 | if (higher_res_prio(t_res, sem->hp_waiter_res)) { |
| 972 | sem->hp_waiter = t; | 998 | sem->hp_waiter = t; |
| 973 | sem->hp_waiter_res = t_res; | 999 | sem->hp_waiter_res = t_res; |
| 974 | struct reservation *o_res = (struct reservation *) tsk_rt(sem->owner)->plugin_state; | 1000 | o_res = (struct reservation *) tsk_rt(sem->owner)->plugin_state; |
| 975 | if (higher_res_prio(t_res, o_res)) { | 1001 | if (higher_res_prio(t_res, o_res)) { |
| 976 | set_priority_inheritance(sem->owner, sem->hp_waiter); | 1002 | set_priority_inheritance(sem->owner, sem->hp_waiter); |
| 977 | } | 1003 | } |
| @@ -1005,12 +1031,80 @@ int gedf_env_omlp_lock(struct litmus_lock* l) | |||
| 1005 | return 0; | 1031 | return 0; |
| 1006 | } | 1032 | } |
| 1007 | 1033 | ||
| 1034 | static int gedf_env_omlp_access_fz_check(struct litmus_lock* l, lt_t fz_len) | ||
| 1035 | { | ||
| 1036 | // The task and the semaphore | ||
| 1037 | struct task_struct* t = current; | ||
| 1038 | struct omlp_semaphore *sem = omlp_from_lock(l); | ||
| 1039 | // Various scheduler entities | ||
| 1040 | struct reservation *t_res; | ||
| 1041 | struct gedf_reservation_environment *gedf_env; | ||
| 1042 | struct gedf_reservation *gedf_res; | ||
| 1043 | // Forbidden zones | ||
| 1044 | unsigned int cpu; | ||
| 1045 | lt_t timeslice_end, remaining_component_budget; | ||
| 1046 | struct mtd_reservation *mtd_res; | ||
| 1047 | // Waiting | ||
| 1048 | unsigned long flags; | ||
| 1049 | wait_queue_t wait; | ||
| 1050 | |||
| 1051 | if (!is_realtime(t)) | ||
| 1052 | return -EPERM; | ||
| 1053 | |||
| 1054 | if (sem->owner != t) { // does this need a lock around it? | ||
| 1055 | return -EINVAL; | ||
| 1056 | } | ||
| 1057 | |||
| 1058 | t_res = (struct reservation *) tsk_rt(t)->plugin_state; | ||
| 1059 | gedf_res = container_of(t_res, struct gedf_reservation, res); | ||
| 1060 | |||
| 1061 | /* if in a forbidden zone, wait until the next time slice */ | ||
| 1062 | /* note that we can't use t_res->par_env->res->cur_budget | ||
| 1063 | * because it is only updated on a call to schedule(), and | ||
| 1064 | * thus might not reflect the current remaining budget | ||
| 1065 | * for the component */ | ||
| 1066 | gedf_env = container_of(t_res->par_env, struct gedf_reservation_environment, env); | ||
| 1067 | spin_lock_irqsave(&gedf_env->fz_waiters[0].lock, flags); | ||
| 1068 | |||
| 1069 | cpu = smp_processor_id(); | ||
| 1070 | |||
| 1071 | spin_unlock_irqrestore(&gedf_env->fz_waiters[0].lock, flags); | ||
| 1072 | spin_lock_irqsave(&gedf_env->fz_waiters[cpu].lock, flags); | ||
| 1073 | |||
| 1074 | mtd_res = (struct mtd_reservation*)t_res->par_env->res; | ||
| 1075 | timeslice_end = mtd_res->cur_interval[cpu].end + mtd_res->major_cycle_start[cpu]; | ||
| 1076 | remaining_component_budget = timeslice_end - litmus_clock(); | ||
| 1077 | |||
| 1078 | if (remaining_component_budget < fz_len) { | ||
| 1079 | /* go on a wait queue to be woken up when the parent reservation | ||
| 1080 | * is next scheduled */ | ||
| 1081 | init_waitqueue_entry(&wait, t); | ||
| 1082 | set_task_state(t, TASK_UNINTERRUPTIBLE); | ||
| 1083 | __add_wait_queue_tail_exclusive(&gedf_env->fz_waiters[cpu], &wait); | ||
| 1084 | |||
| 1085 | TS_LOCK_SUSPEND; | ||
| 1086 | |||
| 1087 | spin_unlock_irqrestore(&gedf_env->fz_waiters[cpu].lock, flags); | ||
| 1088 | |||
| 1089 | BUG_ON(!gedf_res->linked_on && !bheap_node_in_heap(t_res->heap_node)); | ||
| 1090 | |||
| 1091 | schedule(); | ||
| 1092 | |||
| 1093 | TS_LOCK_RESUME; | ||
| 1094 | } else { | ||
| 1095 | spin_unlock_irqrestore(&gedf_env->fz_waiters[cpu].lock, flags); | ||
| 1096 | } | ||
| 1097 | |||
| 1098 | return 0; | ||
| 1099 | } | ||
| 1100 | |||
| 1008 | static int gedf_env_omlp_unlock(struct litmus_lock* l) | 1101 | static int gedf_env_omlp_unlock(struct litmus_lock* l) |
| 1009 | { | 1102 | { |
| 1010 | struct task_struct *t = current, *next; | 1103 | struct task_struct *t = current, *next; |
| 1011 | struct omlp_semaphore *sem = omlp_from_lock(l); | 1104 | struct omlp_semaphore *sem = omlp_from_lock(l); |
| 1012 | unsigned long flags; | 1105 | unsigned long flags; |
| 1013 | int err = 0; | 1106 | int err = 0; |
| 1107 | struct reservation *n_res; | ||
| 1014 | 1108 | ||
| 1015 | spin_lock_irqsave(&sem->fifo_wait.lock, flags); | 1109 | spin_lock_irqsave(&sem->fifo_wait.lock, flags); |
| 1016 | 1110 | ||
| @@ -1028,7 +1122,7 @@ static int gedf_env_omlp_unlock(struct litmus_lock* l) | |||
| 1028 | sem->owner = next; | 1122 | sem->owner = next; |
| 1029 | TRACE_CUR("lock ownership passed to %s/%d\n", next->comm, next->pid); | 1123 | TRACE_CUR("lock ownership passed to %s/%d\n", next->comm, next->pid); |
| 1030 | 1124 | ||
| 1031 | struct reservation *n_res = (struct reservation *) tsk_rt(next)->plugin_state; | 1125 | n_res = (struct reservation *) tsk_rt(next)->plugin_state; |
| 1032 | 1126 | ||
| 1033 | /* determine new hp_waiter if necessary */ | 1127 | /* determine new hp_waiter if necessary */ |
| 1034 | if (next == sem->hp_waiter) { | 1128 | if (next == sem->hp_waiter) { |
| @@ -1095,10 +1189,11 @@ static void gedf_env_omlp_free(struct litmus_lock* lock) | |||
| 1095 | } | 1189 | } |
| 1096 | 1190 | ||
| 1097 | static struct litmus_lock_ops gedf_env_omlp_lock_ops = { | 1191 | static struct litmus_lock_ops gedf_env_omlp_lock_ops = { |
| 1098 | .close = gedf_env_omlp_close, | 1192 | .close = gedf_env_omlp_close, |
| 1099 | .lock = gedf_env_omlp_lock, | 1193 | .lock = gedf_env_omlp_lock, |
| 1100 | .unlock = gedf_env_omlp_unlock, | 1194 | .access_forbidden_zone_check = gedf_env_omlp_access_fz_check, |
| 1101 | .deallocate = gedf_env_omlp_free, | 1195 | .unlock = gedf_env_omlp_unlock, |
| 1196 | .deallocate = gedf_env_omlp_free, | ||
| 1102 | }; | 1197 | }; |
| 1103 | 1198 | ||
| 1104 | static struct litmus_lock* gedf_env_new_omlp(void) | 1199 | static struct litmus_lock* gedf_env_new_omlp(void) |
| @@ -1195,6 +1290,15 @@ long alloc_gedf_reservation_environment( | |||
| 1195 | kfree(gedf_env); | 1290 | kfree(gedf_env); |
| 1196 | return -ENOMEM; | 1291 | return -ENOMEM; |
| 1197 | } | 1292 | } |
| 1293 | #ifdef CONFIG_LITMUS_LOCKING | ||
| 1294 | gedf_env->fz_waiters = kzalloc(sizeof(wait_queue_head_t)*total_cpus, GFP_ATOMIC); | ||
| 1295 | if (!gedf_env->fz_waiters) { | ||
| 1296 | kfree(gedf_env->cpu_entries); | ||
| 1297 | kfree(gedf_env->cpu_node); | ||
| 1298 | kfree(gedf_env); | ||
| 1299 | return -ENOMEM; | ||
| 1300 | } | ||
| 1301 | #endif | ||
| 1198 | 1302 | ||
| 1199 | /* set environment callback actions */ | 1303 | /* set environment callback actions */ |
| 1200 | gedf_env->env.ops = &gedf_env_ops; | 1304 | gedf_env->env.ops = &gedf_env_ops; |
| @@ -1213,6 +1317,13 @@ long alloc_gedf_reservation_environment( | |||
| 1213 | /* initialize environment domain */ | 1317 | /* initialize environment domain */ |
| 1214 | rt_domain_init(&gedf_env->domain, edf_ready_order, NULL, gedf_env_release_jobs); | 1318 | rt_domain_init(&gedf_env->domain, edf_ready_order, NULL, gedf_env_release_jobs); |
| 1215 | 1319 | ||
| 1320 | #ifdef CONFIG_LITMUS_LOCKING | ||
| 1321 | gedf_env->num_waiter_queues = max_cpus; | ||
| 1322 | for (i = 0; i < max_cpus; i++) { | ||
| 1323 | init_waitqueue_head(&gedf_env->fz_waiters[i]); | ||
| 1324 | } | ||
| 1325 | #endif | ||
| 1326 | |||
| 1216 | *_env = gedf_env; | 1327 | *_env = gedf_env; |
| 1217 | return 0; | 1328 | return 0; |
| 1218 | } | 1329 | } |
