aboutsummaryrefslogtreecommitdiffstats
path: root/litmus/sched_mc.c
diff options
context:
space:
mode:
Diffstat (limited to 'litmus/sched_mc.c')
-rw-r--r--litmus/sched_mc.c79
1 files changed, 37 insertions, 42 deletions
diff --git a/litmus/sched_mc.c b/litmus/sched_mc.c
index 577e7d36faf5..bce25bc8822e 100644
--- a/litmus/sched_mc.c
+++ b/litmus/sched_mc.c
@@ -24,25 +24,7 @@
24#include <litmus/bheap.h> 24#include <litmus/bheap.h>
25 25
26#include <litmus/sched_mc.h> 26#include <litmus/sched_mc.h>
27 27#include <litmus/ce_domain.h>
28/**
29 * crit_entry_t - State of a CPU within each criticality level system.
30 * @level Criticality level of this entry
31 * @linked Logically running task, ghost or regular
32 * @domain Domain from which to draw tasks
33 * @usable False if a higher criticality task is running
34 * @timer For ghost task budget enforcement
35 * @node Used to sort crit_entries by preemptability in global domains
36 */
37typedef struct {
38 enum crit_level level;
39 struct task_struct* linked;
40 domain_t* domain;
41 int usable;
42 struct hrtimer timer;
43 struct bheap_node* node;
44 atomic_t dirty;
45} crit_entry_t;
46 28
47/** 29/**
48 * cpu_entry_t - State of a CPU for the entire MC system 30 * cpu_entry_t - State of a CPU for the entire MC system
@@ -64,18 +46,6 @@ typedef struct {
64#endif 46#endif
65} cpu_entry_t; 47} cpu_entry_t;
66 48
67/**
68 * domain_data_t - Wrap domains with related CPU state
69 * @domain A domain for a criticality level
70 * @heap The preemptable heap of crit entries (for global domains)
71 * @crit_entry The crit entry for this domain (for partitioned domains)
72 */
73typedef struct {
74 domain_t domain;
75 struct bheap* heap;
76 crit_entry_t* crit_entry;
77} domain_data_t;
78
79static cpu_entry_t* cpus[NR_CPUS]; 49static cpu_entry_t* cpus[NR_CPUS];
80#ifdef CONFIG_RELEASE_MASTER 50#ifdef CONFIG_RELEASE_MASTER
81static int interrupt_cpu; 51static int interrupt_cpu;
@@ -213,10 +183,14 @@ static void link_task_to_crit(crit_entry_t *ce,
213 ce->linked = task; 183 ce->linked = task;
214 if (task) { 184 if (task) {
215 task->rt_param.linked_on = crit_cpu(ce)->cpu; 185 task->rt_param.linked_on = crit_cpu(ce)->cpu;
216 if (is_ghost(task)) { 186 if (is_ghost(task) && CRIT_LEVEL_A != tsk_mc_crit(task)) {
187 /* There is a level-A timer that will force a
188 * preemption, so we don't set this for level-A
189 * tasks.
190 */
217 /* Reset budget timer */ 191 /* Reset budget timer */
218 task->se.exec_start = litmus_clock(); 192 task->se.exec_start = litmus_clock();
219 when_to_fire = litmus_clock() + 193 when_to_fire = task->se.exec_start +
220 tsk_mc_data(task)->mc_job.ghost_budget; 194 tsk_mc_data(task)->mc_job.ghost_budget;
221 __hrtimer_start_range_ns(&ce->timer, 195 __hrtimer_start_range_ns(&ce->timer,
222 ns_to_ktime(when_to_fire), 196 ns_to_ktime(when_to_fire),
@@ -659,6 +633,9 @@ static void mc_task_exit(struct task_struct *task)
659 tsk_rt(task)->scheduled_on = NO_CPU; 633 tsk_rt(task)->scheduled_on = NO_CPU;
660 } 634 }
661 635
636 if (CRIT_LEVEL_A == tsk_mc_crit(task))
637 ce_task_exit(get_task_domain(task), task);
638
662 local_irq_restore(flags); 639 local_irq_restore(flags);
663} 640}
664 641
@@ -797,7 +774,22 @@ static long mc_activate_plugin(void)
797 if (interrupt_cpu == NO_CPU) 774 if (interrupt_cpu == NO_CPU)
798 interrupt_cpu = 0; 775 interrupt_cpu = 0;
799#endif 776#endif
800 return 0; 777 return ce_activate_plugin();
778}
779
780/*
781 * This is the plugin's release at function, called by the release task-set
782 * system call. Other places in the file use the generic LITMUS release_at(),
783 * which is not this.
784 */
785void mc_release_at(struct task_struct *ts, lt_t start)
786{
787 ce_start(ts, start);
788}
789
790long mc_deactivate_plugin(void)
791{
792 return ce_deactivate_plugin();
801} 793}
802 794
803/* ************************************************************************** 795/* **************************************************************************
@@ -820,11 +812,6 @@ static rt_domain_t _mc_crit_c_rt;
820struct bheap _mc_heap_c; 812struct bheap _mc_heap_c;
821struct bheap_node _mc_nodes_c[NR_CPUS]; 813struct bheap_node _mc_nodes_c[NR_CPUS];
822 814
823/*
824 * XXX commented out because I think this was an obvious typo
825 */
826/* release_at)_ */
827
828static struct sched_plugin mc_plugin __cacheline_aligned_in_smp = { 815static struct sched_plugin mc_plugin __cacheline_aligned_in_smp = {
829 .plugin_name = "MC", 816 .plugin_name = "MC",
830 .task_new = mc_task_new, 817 .task_new = mc_task_new,
@@ -835,6 +822,8 @@ static struct sched_plugin mc_plugin __cacheline_aligned_in_smp = {
835 .task_block = mc_task_block, 822 .task_block = mc_task_block,
836 .admit_task = mc_admit_task, 823 .admit_task = mc_admit_task,
837 .activate_plugin = mc_activate_plugin, 824 .activate_plugin = mc_activate_plugin,
825 .release_at = mc_release_at,
826 .deactivate_plugin = mc_deactivate_plugin,
838}; 827};
839 828
840static void init_crit_entry(crit_entry_t *ce, enum crit_level level, 829static void init_crit_entry(crit_entry_t *ce, enum crit_level level,
@@ -888,12 +877,14 @@ static inline void init_edf_domain(domain_t *dom, rt_domain_t *rt)
888 edf_higher_prio); 877 edf_higher_prio);
889} 878}
890 879
880domain_data_t *ce_domain_for(int);
891static int __init init_mc(void) 881static int __init init_mc(void)
892{ 882{
893 int cpu; 883 int cpu;
894 cpu_entry_t *entry; 884 cpu_entry_t *entry;
895 rt_domain_t *rt; 885 rt_domain_t *rt;
896 domain_data_t *dom_data; 886 domain_data_t *dom_data;
887 domain_t *dom;
897 raw_spinlock_t *a_dom, *b_dom, *c_dom; /* For lock debugger */ 888 raw_spinlock_t *a_dom, *b_dom, *c_dom; /* For lock debugger */
898 889
899 for_each_online_cpu(cpu) { 890 for_each_online_cpu(cpu) {
@@ -911,13 +902,17 @@ static int __init init_mc(void)
911#endif 902#endif
912 903
913 /* CRIT_LEVEL_A */ 904 /* CRIT_LEVEL_A */
914 dom_data = &per_cpu(_mc_crit_a, cpu); 905 dom_data = ce_domain_for(cpu);
915 rt = &per_cpu(_mc_crit_a_rt, cpu);
916 init_local_domain(entry, dom_data, CRIT_LEVEL_A); 906 init_local_domain(entry, dom_data, CRIT_LEVEL_A);
917 init_edf_domain(&dom_data->domain, rt);
918 a_dom = dom_data->domain.lock; 907 a_dom = dom_data->domain.lock;
919 raw_spin_lock_init(a_dom); 908 raw_spin_lock_init(a_dom);
920 dom_data->domain.name = "LVL-A"; 909 dom_data->domain.name = "LVL-A";
910 /* Hook up the level A functions */
911 dom = &dom_data->domain;
912 dom->requeue = ce_requeue;
913 dom->peek_ready = dom->take_ready = ce_peek_and_take_ready;
914 dom->higher_prio = ce_higher_prio;
915 dom->preempt_needed = mc_preempt_needed;
921 916
922 /* CRIT_LEVEL_B */ 917 /* CRIT_LEVEL_B */
923 dom_data = &per_cpu(_mc_crit_b, cpu); 918 dom_data = &per_cpu(_mc_crit_b, cpu);