aboutsummaryrefslogtreecommitdiffstats
path: root/litmus
diff options
context:
space:
mode:
authorChristopher Kenna <cjk@cs.unc.edu>2011-09-30 20:21:31 -0400
committerChristopher Kenna <cjk@cs.unc.edu>2011-09-30 20:21:31 -0400
commitb0466ecb422692bd0d30764075af834101849bd2 (patch)
tree319b5b04e6bf5785c6938ac2382388926ccbec82 /litmus
parent17a40d7ea17014b7a615b9f91facc16c6d9072e3 (diff)
Debug commit.
Some things are working, but the kernel panics when you try and deallocate an event group. Committed so Jonathan can look at it.
Diffstat (limited to 'litmus')
-rw-r--r--litmus/event_group.c8
-rw-r--r--litmus/litmus.c3
-rw-r--r--litmus/rt_domain.c10
-rw-r--r--litmus/sched_mc.c22
-rw-r--r--litmus/sched_mc_ce.c41
5 files changed, 61 insertions, 23 deletions
diff --git a/litmus/event_group.c b/litmus/event_group.c
index 3b50e15bd354..a130a68c731a 100644
--- a/litmus/event_group.c
+++ b/litmus/event_group.c
@@ -30,7 +30,7 @@ static unsigned int time2slot(lt_t time)
30static enum hrtimer_restart on_timer(struct hrtimer *timer) 30static enum hrtimer_restart on_timer(struct hrtimer *timer)
31{ 31{
32 unsigned long flags; 32 unsigned long flags;
33 int num = 0; 33 unsigned long num = 0;
34 struct event_list *el; 34 struct event_list *el;
35 struct rt_event *e; 35 struct rt_event *e;
36 struct list_head *pos, *safe, list; 36 struct list_head *pos, *safe, list;
@@ -50,7 +50,7 @@ static enum hrtimer_restart on_timer(struct hrtimer *timer)
50 list_for_each_safe(pos, safe, &list) { 50 list_for_each_safe(pos, safe, &list) {
51 num++; 51 num++;
52 e = list_entry(pos, struct rt_event, list); 52 e = list_entry(pos, struct rt_event, list);
53 TRACE("Dequeueing event 0x%p with prio %d from 0x%p\n", 53 VTRACE("Dequeueing event 0x%p with prio %d from 0x%p\n",
54 e, e->prio, el); 54 e, e->prio, el);
55 list_del_init(pos); 55 list_del_init(pos);
56 e->function(e); 56 e->function(e);
@@ -238,7 +238,7 @@ void cancel_event(struct rt_event *e)
238 } 238 }
239} 239}
240 240
241struct kmem_cache *event_list_cache, *event_cache; 241struct kmem_cache *event_list_cache;
242 242
243struct event_list* event_list_alloc(int gfp_flags) 243struct event_list* event_list_alloc(int gfp_flags)
244{ 244{
@@ -249,6 +249,8 @@ struct event_list* event_list_alloc(int gfp_flags)
249 el->timer.function = on_timer; 249 el->timer.function = on_timer;
250 } else { 250 } else {
251 VTRACE("Failed to allocate event list!"); 251 VTRACE("Failed to allocate event list!");
252 printk(KERN_CRIT "Failed to allocate event list.\n");
253 BUG();
252 } 254 }
253 return el; 255 return el;
254} 256}
diff --git a/litmus/litmus.c b/litmus/litmus.c
index deaaee3b3f20..f4d676c17d5f 100644
--- a/litmus/litmus.c
+++ b/litmus/litmus.c
@@ -46,6 +46,7 @@ extern struct kmem_cache *release_heap_cache;
46#ifdef CONFIG_MERGE_TIMERS 46#ifdef CONFIG_MERGE_TIMERS
47extern struct kmem_cache *event_list_cache; 47extern struct kmem_cache *event_list_cache;
48#endif 48#endif
49
49#ifdef CONFIG_PLUGIN_MC 50#ifdef CONFIG_PLUGIN_MC
50static struct kmem_cache *mc_data_cache; 51static struct kmem_cache *mc_data_cache;
51#endif 52#endif
@@ -574,7 +575,7 @@ void exit_litmus(struct task_struct *dead_tsk)
574 * Check and free it here. 575 * Check and free it here.
575 */ 576 */
576 if (tsk_rt(dead_tsk)->mc_data) 577 if (tsk_rt(dead_tsk)->mc_data)
577 kfree(tsk_rt(dead_tsk)->mc_data); 578 kmem_cache_free(mc_data_cache, tsk_rt(dead_tsk)->mc_data);
578#endif 579#endif
579 580
580 /* main cleanup only for RT tasks */ 581 /* main cleanup only for RT tasks */
diff --git a/litmus/rt_domain.c b/litmus/rt_domain.c
index fbd91c829619..ffb3cab9cffd 100644
--- a/litmus/rt_domain.c
+++ b/litmus/rt_domain.c
@@ -100,12 +100,18 @@ struct release_heap* release_heap_alloc(int gfp_flags)
100 return rh; 100 return rh;
101} 101}
102 102
103#ifdef CONFIG_MERGE_TIMERS
104extern struct kmem_cache *event_list_cache;
105#endif
106
103void release_heap_free(struct release_heap* rh) 107void release_heap_free(struct release_heap* rh)
104{ 108{
105 /* make sure timer is no longer in use */ 109 /* make sure timer is no longer in use */
106#ifdef CONFIG_MERGE_TIMERS 110#ifdef CONFIG_MERGE_TIMERS
107 /* if (rh->dom) */ 111 if (rh->dom) {
108 /* cancel_event(&rh->event); */ 112 cancel_event(&rh->event);
113 kmem_cache_free(event_list_cache, rh->event.event_list);
114 }
109#else 115#else
110 hrtimer_cancel(&rh->timer); 116 hrtimer_cancel(&rh->timer);
111#endif 117#endif
diff --git a/litmus/sched_mc.c b/litmus/sched_mc.c
index 17f84c9eba79..e20e97810847 100644
--- a/litmus/sched_mc.c
+++ b/litmus/sched_mc.c
@@ -27,8 +27,6 @@
27#include <litmus/sched_mc.h> 27#include <litmus/sched_mc.h>
28#include <litmus/ce_domain.h> 28#include <litmus/ce_domain.h>
29 29
30/* XXX TODO Do we ever want to move level-A timers? */
31
32/** 30/**
33 * struct cpu_entry - State of a CPU for the entire MC system 31 * struct cpu_entry - State of a CPU for the entire MC system
34 * @cpu CPU id 32 * @cpu CPU id
@@ -50,6 +48,9 @@ struct cpu_entry {
50 struct list_head redir; 48 struct list_head redir;
51 raw_spinlock_t redir_lock; 49 raw_spinlock_t redir_lock;
52#endif 50#endif
51#ifdef CONFIG_MERGE_TIMERS
52 struct event_group *event_group;
53#endif
53}; 54};
54 55
55DEFINE_PER_CPU(struct cpu_entry, cpus); 56DEFINE_PER_CPU(struct cpu_entry, cpus);
@@ -141,7 +142,7 @@ static inline void cancel_ghost(struct crit_entry *ce)
141static inline void arm_ghost(struct crit_entry *ce, lt_t fire) 142static inline void arm_ghost(struct crit_entry *ce, lt_t fire)
142{ 143{
143#ifdef CONFIG_MERGE_TIMERS 144#ifdef CONFIG_MERGE_TIMERS
144 add_event(get_event_group_for(crit_cpu(ce)->cpu), &ce->event, fire); 145 add_event(crit_cpu(ce)->event_group, &ce->event, fire);
145#else 146#else
146 __hrtimer_start_range_ns(&ce->timer, 147 __hrtimer_start_range_ns(&ce->timer,
147 ns_to_ktime(fire), 148 ns_to_ktime(fire),
@@ -298,7 +299,7 @@ static void fix_global_levels(void)
298 struct list_head *pos, *safe; 299 struct list_head *pos, *safe;
299 struct task_struct *t; 300 struct task_struct *t;
300 301
301 STRACE("Fixing global levels"); 302 STRACE("Fixing global levels\n");
302 for_each_online_cpu(c) { 303 for_each_online_cpu(c) {
303 e = &per_cpu(cpus, c); 304 e = &per_cpu(cpus, c);
304 raw_spin_lock(&e->redir_lock); 305 raw_spin_lock(&e->redir_lock);
@@ -621,13 +622,12 @@ static void ce_timer_function(struct rt_event *e)
621{ 622{
622 struct ce_dom_data *ce_data = 623 struct ce_dom_data *ce_data =
623 container_of(e, struct ce_dom_data, event); 624 container_of(e, struct ce_dom_data, event);
624 struct event_group *event_group = get_event_group_for(ce_data->cpu);
625 unsigned long flags; 625 unsigned long flags;
626 lt_t next_timer_abs; 626 lt_t next_timer_abs;
627 627
628 local_irq_save(flags); 628 local_irq_save(flags);
629 next_timer_abs = __ce_timer_function(ce_data); 629 next_timer_abs = __ce_timer_function(ce_data);
630 add_event(event_group, e, next_timer_abs); 630 add_event(per_cpu(cpus, ce_data->cpu).event_group, e, next_timer_abs);
631 local_irq_restore(flags); 631 local_irq_restore(flags);
632} 632}
633#else /* else to CONFIG_MERGE_TIMERS */ 633#else /* else to CONFIG_MERGE_TIMERS */
@@ -945,13 +945,13 @@ static long mc_activate_plugin(void)
945 struct domain_data *dom_data; 945 struct domain_data *dom_data;
946 struct domain *dom; 946 struct domain *dom;
947 struct domain_data *our_domains[NR_CPUS]; 947 struct domain_data *our_domains[NR_CPUS];
948 struct event_group *event_group;
948 int cpu, n = 0; 949 int cpu, n = 0;
949 long ret; 950 long ret;
950 951
951#ifdef CONFIG_RELEASE_MASTER 952#ifdef CONFIG_RELEASE_MASTER
952 interrupt_cpu = atomic_read(&release_master_cpu); 953 interrupt_cpu = atomic_read(&release_master_cpu);
953#if defined(CONFIG_PLUGIN_MC_REDIRECT) || \ 954#if defined(CONFIG_PLUGIN_MC_REDIRECT) || defined(CONFIG_PLUGIN_MC_RELEASE_MASTER)
954 (defined(CONFIG_PLUGIN_MC_RELEASE_MASTER) && defined(CONFIG_MERGE_TIMERS))
955 if (NO_CPU == interrupt_cpu) { 955 if (NO_CPU == interrupt_cpu) {
956 printk(KERN_ERR "LITMUS-MC: need a release master\n"); 956 printk(KERN_ERR "LITMUS-MC: need a release master\n");
957 ret = -EINVAL; 957 ret = -EINVAL;
@@ -965,6 +965,12 @@ static long mc_activate_plugin(void)
965 dom = per_cpu(cpus, cpu).crit_entries[CRIT_LEVEL_A].domain; 965 dom = per_cpu(cpus, cpu).crit_entries[CRIT_LEVEL_A].domain;
966 dom_data = domain_data(dom); 966 dom_data = domain_data(dom);
967 our_domains[cpu] = dom_data; 967 our_domains[cpu] = dom_data;
968#if defined(CONFIG_MERGE_TIMERS) && defined(CONFIG_PLUGIN_MC_RELEASE_MASTER)
969 event_group = get_event_group_for(interrupt_cpu);
970#elif defined(CONFIG_MERGE_TIMERS) && !defined(CONFIG_PLUGIN_MC_RELEASE_MASTER)
971 event_group = get_event_group_for(cpu);
972#endif
973 per_cpu(cpus, cpu).event_group = event_group;
968 n++; 974 n++;
969 } 975 }
970 ret = mc_ce_set_domains(n, our_domains); 976 ret = mc_ce_set_domains(n, our_domains);
diff --git a/litmus/sched_mc_ce.c b/litmus/sched_mc_ce.c
index c5066918f282..5125df9572ba 100644
--- a/litmus/sched_mc_ce.c
+++ b/litmus/sched_mc_ce.c
@@ -79,6 +79,10 @@ DEFINE_PER_CPU(struct domain_data, _mc_ce_doms);
79DEFINE_PER_CPU(struct ce_dom_data, _mc_ce_dom_data); 79DEFINE_PER_CPU(struct ce_dom_data, _mc_ce_dom_data);
80DEFINE_PER_CPU(raw_spinlock_t, _mc_ce_dom_locks); 80DEFINE_PER_CPU(raw_spinlock_t, _mc_ce_dom_locks);
81 81
82#ifdef CONFIG_PLUGIN_MC_RELEASE_MASTER
83static int interrupt_cpu;
84#endif
85
82long mc_ce_set_domains(const int n, struct domain_data *domains_in[]) 86long mc_ce_set_domains(const int n, struct domain_data *domains_in[])
83{ 87{
84 const int max = (NR_CPUS < n) ? NR_CPUS : n; 88 const int max = (NR_CPUS < n) ? NR_CPUS : n;
@@ -520,8 +524,9 @@ static enum hrtimer_restart mc_ce_timer_callback(struct hrtimer *timer)
520#ifdef CONFIG_MERGE_TIMERS 524#ifdef CONFIG_MERGE_TIMERS
521 struct event_group *event_group; 525 struct event_group *event_group;
522 ce_data = container_of(e, struct ce_dom_data, event); 526 ce_data = container_of(e, struct ce_dom_data, event);
523 event_group = get_event_group_for(ce_data->cpu); 527 /* use the same CPU the callbacking is executing on by passing NO_CPU */
524#else 528 event_group = get_event_group_for(NO_CPU);
529#else /* CONFIG_MERGE_TIMERS */
525 ce_data = container_of(timer, struct ce_dom_data, timer); 530 ce_data = container_of(timer, struct ce_dom_data, timer);
526#endif 531#endif
527 dom = get_domain_for(ce_data->cpu); 532 dom = get_domain_for(ce_data->cpu);
@@ -588,7 +593,7 @@ static void arm_all_timers(void)
588 struct domain *dom; 593 struct domain *dom;
589 struct ce_dom_data *ce_data; 594 struct ce_dom_data *ce_data;
590 struct ce_pid_table *pid_table; 595 struct ce_pid_table *pid_table;
591 int cpu, idx; 596 int cpu, idx, cpu_for_timer;
592 const lt_t start = atomic64_read(&start_time); 597 const lt_t start = atomic64_read(&start_time);
593 598
594 TRACE("arm all timers\n"); 599 TRACE("arm all timers\n");
@@ -602,13 +607,19 @@ static void arm_all_timers(void)
602 for (idx = 0; idx < pid_table->num_pid_entries; idx++) { 607 for (idx = 0; idx < pid_table->num_pid_entries; idx++) {
603 pid_table->entries[idx].expected_job = 0; 608 pid_table->entries[idx].expected_job = 0;
604 } 609 }
610#ifdef CONFIG_PLUGIN_MC_RELEASE_MASTER
611 cpu_for_timer = interrupt_cpu;
612#else
613 cpu_for_timer = cpu;
614#endif
615
605#ifdef CONFIG_MERGE_TIMERS 616#ifdef CONFIG_MERGE_TIMERS
606 TRACE("adding event for CPU %d\n", cpu); 617 add_event(get_event_group_for(cpu_for_timer),
607 add_event(get_event_group_for(cpu), &ce_data->event, start); 618 &ce_data->event, start);
608#else 619#else
609 TRACE("arming timer for CPU %d\n", cpu); 620 hrtimer_start_on(cpu_for_timer, &ce_data->timer_info,
610 hrtimer_start_on(cpu, &ce_data->timer_info, &ce_data->timer, 621 &ce_data->timer, ns_to_ktime(start),
611 ns_to_ktime(start), HRTIMER_MODE_ABS_PINNED); 622 HRTIMER_MODE_ABS_PINNED);
612#endif 623#endif
613 } 624 }
614} 625}
@@ -634,8 +645,18 @@ long mc_ce_activate_plugin_common(void)
634{ 645{
635 struct ce_dom_data *ce_data; 646 struct ce_dom_data *ce_data;
636 struct domain *dom; 647 struct domain *dom;
648 long ret;
637 int cpu; 649 int cpu;
638 650
651#ifdef CONFIG_PLUGIN_MC_RELEASE_MASTER
652 interrupt_cpu = atomic_read(&release_master_cpu);
653 if (NO_CPU == interrupt_cpu) {
654 printk(KERN_ERR "LITMUS: MC-CE needs a release master\n");
655 ret = -EINVAL;
656 goto out;
657 }
658#endif
659
639 for_each_online_cpu(cpu) { 660 for_each_online_cpu(cpu) {
640 dom = get_domain_for(cpu); 661 dom = get_domain_for(cpu);
641 ce_data = dom->data; 662 ce_data = dom->data;
@@ -647,7 +668,9 @@ long mc_ce_activate_plugin_common(void)
647 atomic64_set(&start_time, litmus_clock()); 668 atomic64_set(&start_time, litmus_clock());
648 /* may not want to arm timers on activation, just after release */ 669 /* may not want to arm timers on activation, just after release */
649 arm_all_timers(); 670 arm_all_timers();
650 return 0; 671 ret = 0;
672out:
673 return ret;
651} 674}
652 675
653static long mc_ce_activate_plugin(void) 676static long mc_ce_activate_plugin(void)