aboutsummaryrefslogtreecommitdiffstats
path: root/litmus
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2009-12-17 21:47:19 -0500
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-29 17:19:53 -0400
commit0b28a3122d6917784701377e15a863489aee1c6c (patch)
tree259c8f59ed477e81f97b5dc6ac7ec8ce06ce1e26 /litmus
parentc15be843778236e9f2fdbc207ab36ba996b2bb1b (diff)
[ported from 2008.3] Add release-master support
Diffstat (limited to 'litmus')
-rw-r--r--litmus/rt_domain.c21
-rw-r--r--litmus/sched_gsn_edf.c26
2 files changed, 36 insertions, 11 deletions
diff --git a/litmus/rt_domain.c b/litmus/rt_domain.c
index 78e76421aeba..62c9fdcd22be 100644
--- a/litmus/rt_domain.c
+++ b/litmus/rt_domain.c
@@ -158,6 +158,7 @@ static void reinit_release_heap(struct task_struct* t)
158 158
159 /* initialize */ 159 /* initialize */
160 heap_init(&rh->heap); 160 heap_init(&rh->heap);
161 atomic_set(&rh->info.state, HRTIMER_START_ON_INACTIVE);
161} 162}
162/* arm_release_timer() - start local release timer or trigger 163/* arm_release_timer() - start local release timer or trigger
163 * remote timer (pull timer) 164 * remote timer (pull timer)
@@ -217,14 +218,18 @@ static void arm_release_timer(rt_domain_t *_rt)
217 TRACE_TASK(t, "arming timer 0x%p\n", &rh->timer); 218 TRACE_TASK(t, "arming timer 0x%p\n", &rh->timer);
218 /* we cannot arm the timer using hrtimer_start() 219 /* we cannot arm the timer using hrtimer_start()
219 * as it may deadlock on rq->lock 220 * as it may deadlock on rq->lock
221 *
222 * PINNED mode is ok on both local and remote CPU
220 */ 223 */
221 /* FIXME now only one cpu without pulling 224 if (rt->release_master == NO_CPU)
222 * later more cpus; hrtimer_pull should call 225 __hrtimer_start_range_ns(&rh->timer,
223 * __hrtimer_start... always with PINNED mode 226 ns_to_ktime(rh->release_time),
224 */ 227 0, HRTIMER_MODE_ABS_PINNED, 0);
225 __hrtimer_start_range_ns(&rh->timer, 228 else
226 ns_to_ktime(rh->release_time), 229 hrtimer_start_on(rt->release_master,
227 0, HRTIMER_MODE_ABS_PINNED, 0); 230 &rh->info, &rh->timer,
231 ns_to_ktime(rh->release_time),
232 HRTIMER_MODE_ABS_PINNED);
228 } else 233 } else
229 TRACE_TASK(t, "0x%p is not my timer\n", &rh->timer); 234 TRACE_TASK(t, "0x%p is not my timer\n", &rh->timer);
230 } 235 }
@@ -246,6 +251,8 @@ void rt_domain_init(rt_domain_t *rt,
246 if (!order) 251 if (!order)
247 order = dummy_order; 252 order = dummy_order;
248 253
254 rt->release_master = NO_CPU;
255
249 heap_init(&rt->ready_queue); 256 heap_init(&rt->ready_queue);
250 INIT_LIST_HEAD(&rt->tobe_released); 257 INIT_LIST_HEAD(&rt->tobe_released);
251 for (i = 0; i < RELEASE_QUEUE_SLOTS; i++) 258 for (i = 0; i < RELEASE_QUEUE_SLOTS; i++)
diff --git a/litmus/sched_gsn_edf.c b/litmus/sched_gsn_edf.c
index 69990805e16a..a223e69f2efb 100644
--- a/litmus/sched_gsn_edf.c
+++ b/litmus/sched_gsn_edf.c
@@ -393,6 +393,12 @@ static struct task_struct* gsnedf_schedule(struct task_struct * prev)
393 int out_of_time, sleep, preempt, np, exists, blocks; 393 int out_of_time, sleep, preempt, np, exists, blocks;
394 struct task_struct* next = NULL; 394 struct task_struct* next = NULL;
395 395
396 /* Bail out early if we are the release master.
397 * The release master never schedules any real-time tasks.
398 */
399 if (gsnedf.release_master == entry->cpu)
400 return NULL;
401
396 spin_lock(&gsnedf_lock); 402 spin_lock(&gsnedf_lock);
397 clear_will_schedule(); 403 clear_will_schedule();
398 404
@@ -515,8 +521,15 @@ static void gsnedf_task_new(struct task_struct * t, int on_rq, int running)
515 if (running) { 521 if (running) {
516 entry = &per_cpu(gsnedf_cpu_entries, task_cpu(t)); 522 entry = &per_cpu(gsnedf_cpu_entries, task_cpu(t));
517 BUG_ON(entry->scheduled); 523 BUG_ON(entry->scheduled);
518 entry->scheduled = t; 524
519 tsk_rt(t)->scheduled_on = task_cpu(t); 525 if (entry->cpu != gsnedf.release_master) {
526 entry->scheduled = t;
527 tsk_rt(t)->scheduled_on = task_cpu(t);
528 } else {
529 /* do not schedule on release master */
530 preempt(entry); /* force resched */
531 tsk_rt(t)->scheduled_on = NO_CPU;
532 }
520 } else { 533 } else {
521 t->rt_param.scheduled_on = NO_CPU; 534 t->rt_param.scheduled_on = NO_CPU;
522 } 535 }
@@ -758,6 +771,7 @@ static long gsnedf_activate_plugin(void)
758 cpu_entry_t *entry; 771 cpu_entry_t *entry;
759 772
760 heap_init(&gsnedf_cpu_heap); 773 heap_init(&gsnedf_cpu_heap);
774 gsnedf.release_master = atomic_read(&release_master_cpu);
761 775
762 for_each_online_cpu(cpu) { 776 for_each_online_cpu(cpu) {
763 entry = &per_cpu(gsnedf_cpu_entries, cpu); 777 entry = &per_cpu(gsnedf_cpu_entries, cpu);
@@ -765,8 +779,12 @@ static long gsnedf_activate_plugin(void)
765 atomic_set(&entry->will_schedule, 0); 779 atomic_set(&entry->will_schedule, 0);
766 entry->linked = NULL; 780 entry->linked = NULL;
767 entry->scheduled = NULL; 781 entry->scheduled = NULL;
768 TRACE("GSN-EDF: Initializing CPU #%d.\n", cpu); 782 if (cpu != gsnedf.release_master) {
769 update_cpu_position(entry); 783 TRACE("GSN-EDF: Initializing CPU #%d.\n", cpu);
784 update_cpu_position(entry);
785 } else {
786 TRACE("GSN-EDF: CPU %d is release master.\n", cpu);
787 }
770 } 788 }
771 return 0; 789 return 0;
772} 790}