aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjoern B. Brandenburg <bbb@cs.unc.edu>2010-05-30 19:46:21 -0400
committerBjoern B. Brandenburg <bbb@cs.unc.edu>2010-06-01 10:23:13 -0400
commitcedc8df1cf1ff935af5455a9d565dac05192a47f (patch)
tree04771859bf08ff847894af6107e4b799a7a00cea
parent5b54b24c13b7c5dbaa06eae5e1a0075da354289c (diff)
Make release master support optional
Introduces CONFIG_RELEASE_MASTER and makes release master support dependent on the new symbol. This is useful because dedicated interrupt handling only applies to "large" multicore platforms. This will allow us to not implement smp_send_pull_timers() for all platforms.
-rw-r--r--include/litmus/litmus.h2
-rw-r--r--include/litmus/rt_domain.h6
-rw-r--r--litmus/Kconfig12
-rw-r--r--litmus/litmus.c14
-rw-r--r--litmus/rt_domain.c8
-rw-r--r--litmus/sched_gsn_edf.c12
6 files changed, 51 insertions, 3 deletions
diff --git a/include/litmus/litmus.h b/include/litmus/litmus.h
index d515d1af1096..674528eece14 100644
--- a/include/litmus/litmus.h
+++ b/include/litmus/litmus.h
@@ -9,7 +9,9 @@
9#include <linux/jiffies.h> 9#include <linux/jiffies.h>
10#include <litmus/sched_trace.h> 10#include <litmus/sched_trace.h>
11 11
12#ifdef CONFIG_RELEASE_MASTER
12extern atomic_t release_master_cpu; 13extern atomic_t release_master_cpu;
14#endif
13 15
14extern atomic_t __log_seq_no; 16extern atomic_t __log_seq_no;
15 17
diff --git a/include/litmus/rt_domain.h b/include/litmus/rt_domain.h
index 9bf980713474..59e6b54e9281 100644
--- a/include/litmus/rt_domain.h
+++ b/include/litmus/rt_domain.h
@@ -28,7 +28,10 @@ typedef struct _rt_domain {
28 /* real-time tasks waiting for release are in here */ 28 /* real-time tasks waiting for release are in here */
29 raw_spinlock_t release_lock; 29 raw_spinlock_t release_lock;
30 struct release_queue release_queue; 30 struct release_queue release_queue;
31
32#ifdef CONFIG_RELEASE_MASTER
31 int release_master; 33 int release_master;
34#endif
32 35
33 /* for moving tasks to the release queue */ 36 /* for moving tasks to the release queue */
34 raw_spinlock_t tobe_lock; 37 raw_spinlock_t tobe_lock;
@@ -52,8 +55,11 @@ struct release_heap {
52 struct bheap heap; 55 struct bheap heap;
53 /* used to trigger the release */ 56 /* used to trigger the release */
54 struct hrtimer timer; 57 struct hrtimer timer;
58
59#ifdef CONFIG_RELEASE_MASTER
55 /* used to delegate releases */ 60 /* used to delegate releases */
56 struct hrtimer_start_on_info info; 61 struct hrtimer_start_on_info info;
62#endif
57 /* required for the timer callback */ 63 /* required for the timer callback */
58 rt_domain_t* dom; 64 rt_domain_t* dom;
59}; 65};
diff --git a/litmus/Kconfig b/litmus/Kconfig
index cc49e1a7f9c7..614e1051fa49 100644
--- a/litmus/Kconfig
+++ b/litmus/Kconfig
@@ -1,6 +1,6 @@
1menu "LITMUS^RT" 1menu "LITMUS^RT"
2 2
3menu "Plugins" 3menu "Scheduling"
4 4
5config PLUGIN_CEDF 5config PLUGIN_CEDF
6 bool "Clustered-EDF" 6 bool "Clustered-EDF"
@@ -11,6 +11,16 @@ config PLUGIN_CEDF
11 On smaller platforms (e.g., ARM PB11MPCore), using C-EDF 11 On smaller platforms (e.g., ARM PB11MPCore), using C-EDF
12 makes little sense since there aren't any shared caches. 12 makes little sense since there aren't any shared caches.
13 13
14config RELEASE_MASTER
15 bool "Release-master Support"
16 default n
17 help
18 Allow one processor to act as a dedicated interrupt processor
19 that services all timer interrupts, but that does not schedule
20 real-time tasks. See RTSS'09 paper for details
21 (http://www.cs.unc.edu/~anderson/papers.html).
22 Currently only supported by GSN-EDF.
23
14endmenu 24endmenu
15 25
16menu "Real-Time Synchronization" 26menu "Real-Time Synchronization"
diff --git a/litmus/litmus.c b/litmus/litmus.c
index b71fc819eb51..c60423228607 100644
--- a/litmus/litmus.c
+++ b/litmus/litmus.c
@@ -30,8 +30,10 @@ atomic_t cannot_use_plugin = ATOMIC_INIT(0);
30/* Give log messages sequential IDs. */ 30/* Give log messages sequential IDs. */
31atomic_t __log_seq_no = ATOMIC_INIT(0); 31atomic_t __log_seq_no = ATOMIC_INIT(0);
32 32
33#ifdef CONFIG_RELEASE_MASTER
33/* current master CPU for handling timer IRQs */ 34/* current master CPU for handling timer IRQs */
34atomic_t release_master_cpu = ATOMIC_INIT(NO_CPU); 35atomic_t release_master_cpu = ATOMIC_INIT(NO_CPU);
36#endif
35 37
36static struct kmem_cache * bheap_node_cache; 38static struct kmem_cache * bheap_node_cache;
37extern struct kmem_cache * release_heap_cache; 39extern struct kmem_cache * release_heap_cache;
@@ -627,6 +629,7 @@ static int proc_write_cluster_size(struct file *file,
627 return len; 629 return len;
628} 630}
629 631
632#ifdef CONFIG_RELEASE_MASTER
630static int proc_read_release_master(char *page, char **start, 633static int proc_read_release_master(char *page, char **start,
631 off_t off, int count, 634 off_t off, int count,
632 int *eof, void *data) 635 int *eof, void *data)
@@ -676,13 +679,16 @@ static int proc_write_release_master(struct file *file,
676 } 679 }
677 } 680 }
678} 681}
682#endif
679 683
680static struct proc_dir_entry *litmus_dir = NULL, 684static struct proc_dir_entry *litmus_dir = NULL,
681 *curr_file = NULL, 685 *curr_file = NULL,
682 *stat_file = NULL, 686 *stat_file = NULL,
683 *plugs_file = NULL, 687 *plugs_file = NULL,
684 *clus_cache_idx_file = NULL, 688#ifdef CONFIG_RELEASE_MASTER
685 *release_master_file = NULL; 689 *release_master_file = NULL,
690#endif
691 *clus_cache_idx_file = NULL;
686 692
687static int __init init_litmus_proc(void) 693static int __init init_litmus_proc(void)
688{ 694{
@@ -702,6 +708,7 @@ static int __init init_litmus_proc(void)
702 curr_file->read_proc = proc_read_curr; 708 curr_file->read_proc = proc_read_curr;
703 curr_file->write_proc = proc_write_curr; 709 curr_file->write_proc = proc_write_curr;
704 710
711#ifdef CONFIG_RELEASE_MASTER
705 release_master_file = create_proc_entry("release_master", 712 release_master_file = create_proc_entry("release_master",
706 0644, litmus_dir); 713 0644, litmus_dir);
707 if (!release_master_file) { 714 if (!release_master_file) {
@@ -711,6 +718,7 @@ static int __init init_litmus_proc(void)
711 } 718 }
712 release_master_file->read_proc = proc_read_release_master; 719 release_master_file->read_proc = proc_read_release_master;
713 release_master_file->write_proc = proc_write_release_master; 720 release_master_file->write_proc = proc_write_release_master;
721#endif
714 722
715 clus_cache_idx_file = create_proc_entry("cluster_cache", 723 clus_cache_idx_file = create_proc_entry("cluster_cache",
716 0644, litmus_dir); 724 0644, litmus_dir);
@@ -741,8 +749,10 @@ static void exit_litmus_proc(void)
741 remove_proc_entry("active_plugin", litmus_dir); 749 remove_proc_entry("active_plugin", litmus_dir);
742 if (clus_cache_idx_file) 750 if (clus_cache_idx_file)
743 remove_proc_entry("cluster_cache", litmus_dir); 751 remove_proc_entry("cluster_cache", litmus_dir);
752#ifdef CONFIG_RELEASE_MASTER
744 if (release_master_file) 753 if (release_master_file)
745 remove_proc_entry("release_master", litmus_dir); 754 remove_proc_entry("release_master", litmus_dir);
755#endif
746 if (litmus_dir) 756 if (litmus_dir)
747 remove_proc_entry("litmus", NULL); 757 remove_proc_entry("litmus", NULL);
748} 758}
diff --git a/litmus/rt_domain.c b/litmus/rt_domain.c
index 8d5db6050723..26f1cc48f865 100644
--- a/litmus/rt_domain.c
+++ b/litmus/rt_domain.c
@@ -158,7 +158,9 @@ static void reinit_release_heap(struct task_struct* t)
158 158
159 /* initialize */ 159 /* initialize */
160 bheap_init(&rh->heap); 160 bheap_init(&rh->heap);
161#ifdef __ARCH_HAS_SEND_PULL_TIMERS
161 atomic_set(&rh->info.state, HRTIMER_START_ON_INACTIVE); 162 atomic_set(&rh->info.state, HRTIMER_START_ON_INACTIVE);
163#endif
162} 164}
163/* arm_release_timer() - start local release timer or trigger 165/* arm_release_timer() - start local release timer or trigger
164 * remote timer (pull timer) 166 * remote timer (pull timer)
@@ -221,15 +223,19 @@ static void arm_release_timer(rt_domain_t *_rt)
221 * 223 *
222 * PINNED mode is ok on both local and remote CPU 224 * PINNED mode is ok on both local and remote CPU
223 */ 225 */
226#ifdef CONFIG_RELEASE_MASTER
224 if (rt->release_master == NO_CPU) 227 if (rt->release_master == NO_CPU)
228#endif
225 __hrtimer_start_range_ns(&rh->timer, 229 __hrtimer_start_range_ns(&rh->timer,
226 ns_to_ktime(rh->release_time), 230 ns_to_ktime(rh->release_time),
227 0, HRTIMER_MODE_ABS_PINNED, 0); 231 0, HRTIMER_MODE_ABS_PINNED, 0);
232#ifdef CONFIG_RELEASE_MASTER
228 else 233 else
229 hrtimer_start_on(rt->release_master, 234 hrtimer_start_on(rt->release_master,
230 &rh->info, &rh->timer, 235 &rh->info, &rh->timer,
231 ns_to_ktime(rh->release_time), 236 ns_to_ktime(rh->release_time),
232 HRTIMER_MODE_ABS_PINNED); 237 HRTIMER_MODE_ABS_PINNED);
238#endif
233 } else 239 } else
234 TRACE_TASK(t, "0x%p is not my timer\n", &rh->timer); 240 TRACE_TASK(t, "0x%p is not my timer\n", &rh->timer);
235 } 241 }
@@ -251,7 +257,9 @@ void rt_domain_init(rt_domain_t *rt,
251 if (!order) 257 if (!order)
252 order = dummy_order; 258 order = dummy_order;
253 259
260#ifdef CONFIG_RELEASE_MASTER
254 rt->release_master = NO_CPU; 261 rt->release_master = NO_CPU;
262#endif
255 263
256 bheap_init(&rt->ready_queue); 264 bheap_init(&rt->ready_queue);
257 INIT_LIST_HEAD(&rt->tobe_released); 265 INIT_LIST_HEAD(&rt->tobe_released);
diff --git a/litmus/sched_gsn_edf.c b/litmus/sched_gsn_edf.c
index c0c63eba70ce..e101768740ad 100644
--- a/litmus/sched_gsn_edf.c
+++ b/litmus/sched_gsn_edf.c
@@ -382,11 +382,13 @@ static struct task_struct* gsnedf_schedule(struct task_struct * prev)
382 int out_of_time, sleep, preempt, np, exists, blocks; 382 int out_of_time, sleep, preempt, np, exists, blocks;
383 struct task_struct* next = NULL; 383 struct task_struct* next = NULL;
384 384
385#ifdef CONFIG_RELEASE_MASTER
385 /* Bail out early if we are the release master. 386 /* Bail out early if we are the release master.
386 * The release master never schedules any real-time tasks. 387 * The release master never schedules any real-time tasks.
387 */ 388 */
388 if (gsnedf.release_master == entry->cpu) 389 if (gsnedf.release_master == entry->cpu)
389 return NULL; 390 return NULL;
391#endif
390 392
391 raw_spin_lock(&gsnedf_lock); 393 raw_spin_lock(&gsnedf_lock);
392 clear_will_schedule(); 394 clear_will_schedule();
@@ -518,14 +520,18 @@ static void gsnedf_task_new(struct task_struct * t, int on_rq, int running)
518 entry = &per_cpu(gsnedf_cpu_entries, task_cpu(t)); 520 entry = &per_cpu(gsnedf_cpu_entries, task_cpu(t));
519 BUG_ON(entry->scheduled); 521 BUG_ON(entry->scheduled);
520 522
523#ifdef CONFIG_RELEASE_MASTER
521 if (entry->cpu != gsnedf.release_master) { 524 if (entry->cpu != gsnedf.release_master) {
525#endif
522 entry->scheduled = t; 526 entry->scheduled = t;
523 tsk_rt(t)->scheduled_on = task_cpu(t); 527 tsk_rt(t)->scheduled_on = task_cpu(t);
528#ifdef CONFIG_RELEASE_MASTER
524 } else { 529 } else {
525 /* do not schedule on release master */ 530 /* do not schedule on release master */
526 preempt(entry); /* force resched */ 531 preempt(entry); /* force resched */
527 tsk_rt(t)->scheduled_on = NO_CPU; 532 tsk_rt(t)->scheduled_on = NO_CPU;
528 } 533 }
534#endif
529 } else { 535 } else {
530 t->rt_param.scheduled_on = NO_CPU; 536 t->rt_param.scheduled_on = NO_CPU;
531 } 537 }
@@ -767,7 +773,9 @@ static long gsnedf_activate_plugin(void)
767 cpu_entry_t *entry; 773 cpu_entry_t *entry;
768 774
769 bheap_init(&gsnedf_cpu_heap); 775 bheap_init(&gsnedf_cpu_heap);
776#ifdef CONFIG_RELEASE_MASTER
770 gsnedf.release_master = atomic_read(&release_master_cpu); 777 gsnedf.release_master = atomic_read(&release_master_cpu);
778#endif
771 779
772 for_each_online_cpu(cpu) { 780 for_each_online_cpu(cpu) {
773 entry = &per_cpu(gsnedf_cpu_entries, cpu); 781 entry = &per_cpu(gsnedf_cpu_entries, cpu);
@@ -775,12 +783,16 @@ static long gsnedf_activate_plugin(void)
775 atomic_set(&entry->will_schedule, 0); 783 atomic_set(&entry->will_schedule, 0);
776 entry->linked = NULL; 784 entry->linked = NULL;
777 entry->scheduled = NULL; 785 entry->scheduled = NULL;
786#ifdef CONFIG_RELEASE_MASTER
778 if (cpu != gsnedf.release_master) { 787 if (cpu != gsnedf.release_master) {
788#endif
779 TRACE("GSN-EDF: Initializing CPU #%d.\n", cpu); 789 TRACE("GSN-EDF: Initializing CPU #%d.\n", cpu);
780 update_cpu_position(entry); 790 update_cpu_position(entry);
791#ifdef CONFIG_RELEASE_MASTER
781 } else { 792 } else {
782 TRACE("GSN-EDF: CPU %d is release master.\n", cpu); 793 TRACE("GSN-EDF: CPU %d is release master.\n", cpu);
783 } 794 }
795#endif
784 } 796 }
785 return 0; 797 return 0;
786} 798}