diff options
| -rw-r--r-- | include/litmus/rt_domain.h | 16 | ||||
| -rw-r--r-- | litmus/rt_domain.c | 40 |
2 files changed, 49 insertions, 7 deletions
diff --git a/include/litmus/rt_domain.h b/include/litmus/rt_domain.h index 59e6b54e9281..ac249292e866 100644 --- a/include/litmus/rt_domain.h +++ b/include/litmus/rt_domain.h | |||
| @@ -143,12 +143,26 @@ static inline struct task_struct* take_ready(rt_domain_t* rt) | |||
| 143 | static inline void add_release(rt_domain_t* rt, struct task_struct *task) | 143 | static inline void add_release(rt_domain_t* rt, struct task_struct *task) |
| 144 | { | 144 | { |
| 145 | unsigned long flags; | 145 | unsigned long flags; |
| 146 | /* first we need the write lock for rt_ready_queue */ | ||
| 147 | raw_spin_lock_irqsave(&rt->tobe_lock, flags); | 146 | raw_spin_lock_irqsave(&rt->tobe_lock, flags); |
| 148 | __add_release(rt, task); | 147 | __add_release(rt, task); |
| 149 | raw_spin_unlock_irqrestore(&rt->tobe_lock, flags); | 148 | raw_spin_unlock_irqrestore(&rt->tobe_lock, flags); |
| 150 | } | 149 | } |
| 151 | 150 | ||
| 151 | #ifdef CONFIG_RELEASE_MASTER | ||
| 152 | void __add_release_on(rt_domain_t* rt, struct task_struct *task, | ||
| 153 | int target_cpu); | ||
| 154 | |||
| 155 | static inline void add_release_on(rt_domain_t* rt, | ||
| 156 | struct task_struct *task, | ||
| 157 | int target_cpu) | ||
| 158 | { | ||
| 159 | unsigned long flags; | ||
| 160 | raw_spin_lock_irqsave(&rt->tobe_lock, flags); | ||
| 161 | __add_release_on(rt, task, target_cpu); | ||
| 162 | raw_spin_unlock_irqrestore(&rt->tobe_lock, flags); | ||
| 163 | } | ||
| 164 | #endif | ||
| 165 | |||
| 152 | static inline int __jobs_pending(rt_domain_t* rt) | 166 | static inline int __jobs_pending(rt_domain_t* rt) |
| 153 | { | 167 | { |
| 154 | return !bheap_empty(&rt->ready_queue); | 168 | return !bheap_empty(&rt->ready_queue); |
diff --git a/litmus/rt_domain.c b/litmus/rt_domain.c index 8a3ff706c208..d27af48e0298 100644 --- a/litmus/rt_domain.c +++ b/litmus/rt_domain.c | |||
| @@ -169,7 +169,12 @@ static void reinit_release_heap(struct task_struct* t) | |||
| 169 | * - tobe_lock taken | 169 | * - tobe_lock taken |
| 170 | * - IRQ disabled | 170 | * - IRQ disabled |
| 171 | */ | 171 | */ |
| 172 | static void arm_release_timer(rt_domain_t *_rt) | 172 | #ifdef CONFIG_RELEASE_MASTER |
| 173 | #define arm_release_timer(t) arm_release_timer_on((t), NO_CPU) | ||
| 174 | static void arm_release_timer_on(rt_domain_t *_rt , int target_cpu) | ||
| 175 | #else | ||
| 176 | static void arm_release_master(rt_domain_t *_rt) | ||
| 177 | #endif | ||
| 173 | { | 178 | { |
| 174 | rt_domain_t *rt = _rt; | 179 | rt_domain_t *rt = _rt; |
| 175 | struct list_head list; | 180 | struct list_head list; |
| @@ -224,17 +229,21 @@ static void arm_release_timer(rt_domain_t *_rt) | |||
| 224 | * PINNED mode is ok on both local and remote CPU | 229 | * PINNED mode is ok on both local and remote CPU |
| 225 | */ | 230 | */ |
| 226 | #ifdef CONFIG_RELEASE_MASTER | 231 | #ifdef CONFIG_RELEASE_MASTER |
| 227 | if (rt->release_master == NO_CPU) | 232 | if (rt->release_master == NO_CPU && |
| 233 | target_cpu == NO_CPU) | ||
| 228 | #endif | 234 | #endif |
| 229 | __hrtimer_start_range_ns(&rh->timer, | 235 | __hrtimer_start_range_ns(&rh->timer, |
| 230 | ns_to_ktime(rh->release_time), | 236 | ns_to_ktime(rh->release_time), |
| 231 | 0, HRTIMER_MODE_ABS_PINNED, 0); | 237 | 0, HRTIMER_MODE_ABS_PINNED, 0); |
| 232 | #ifdef CONFIG_RELEASE_MASTER | 238 | #ifdef CONFIG_RELEASE_MASTER |
| 233 | else | 239 | else |
| 234 | hrtimer_start_on(rt->release_master, | 240 | hrtimer_start_on( |
| 235 | &rh->info, &rh->timer, | 241 | /* target_cpu overrides release master */ |
| 236 | ns_to_ktime(rh->release_time), | 242 | (target_cpu != NO_CPU ? |
| 237 | HRTIMER_MODE_ABS_PINNED); | 243 | target_cpu : rt->release_master), |
| 244 | &rh->info, &rh->timer, | ||
| 245 | ns_to_ktime(rh->release_time), | ||
| 246 | HRTIMER_MODE_ABS_PINNED); | ||
| 238 | #endif | 247 | #endif |
| 239 | } else | 248 | } else |
| 240 | TRACE_TASK(t, "0x%p is not my timer\n", &rh->timer); | 249 | TRACE_TASK(t, "0x%p is not my timer\n", &rh->timer); |
| @@ -299,6 +308,25 @@ void __merge_ready(rt_domain_t* rt, struct bheap* tasks) | |||
| 299 | rt->check_resched(rt); | 308 | rt->check_resched(rt); |
| 300 | } | 309 | } |
| 301 | 310 | ||
| 311 | |||
| 312 | #ifdef CONFIG_RELEASE_MASTER | ||
| 313 | void __add_release_on(rt_domain_t* rt, struct task_struct *task, | ||
| 314 | int target_cpu) | ||
| 315 | { | ||
| 316 | TRACE_TASK(task, "add_release_on(), rel=%llu, target=%d\n", | ||
| 317 | get_release(task), target_cpu); | ||
| 318 | list_add(&tsk_rt(task)->list, &rt->tobe_released); | ||
| 319 | task->rt_param.domain = rt; | ||
| 320 | |||
| 321 | /* start release timer */ | ||
| 322 | TS_SCHED2_START(task); | ||
| 323 | |||
| 324 | arm_release_timer_on(rt, target_cpu); | ||
| 325 | |||
| 326 | TS_SCHED2_END(task); | ||
| 327 | } | ||
| 328 | #endif | ||
| 329 | |||
| 302 | /* add_release - add a real-time task to the rt release queue. | 330 | /* add_release - add a real-time task to the rt release queue. |
| 303 | * @task: the sleeping task | 331 | * @task: the sleeping task |
| 304 | */ | 332 | */ |
