aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--litmus/sched_mc.c57
1 files changed, 49 insertions, 8 deletions
diff --git a/litmus/sched_mc.c b/litmus/sched_mc.c
index f3ace9fe560a..43b0731ab38a 100644
--- a/litmus/sched_mc.c
+++ b/litmus/sched_mc.c
@@ -4,6 +4,49 @@
4 * Implementation of the Mixed Criticality scheduling algorithm. 4 * Implementation of the Mixed Criticality scheduling algorithm.
5 * 5 *
6 * (Per Mollison, Erickson, Anderson, Baruah, Scoredos 2010) 6 * (Per Mollison, Erickson, Anderson, Baruah, Scoredos 2010)
7 *
8 * Absolute first: relative time spent doing different parts of release
9 * and scheduling overhead needs to be measured and graphed.
10 *
11 * Domain locks should be more fine-grained. There is no reason to hold the
12 * ready-queue lock when adding a task to the release-queue.
13 *
14 * The levels should be converted to linked-lists so that they are more
15 * adaptable and need not be identical on all processors.
16 *
17 * The interaction between remove_from_all and other concurrent operations
18 * should be re-examined. If a job_completion and a preemption happen
19 * simultaneously, a task could be requeued, removed, then requeued again.
20 *
21 * Level-C tasks should be able to swap CPUs a-la GSN-EDF. They should also
22 * try and swap with the last CPU they were on. This could be complicated for
23 * ghost tasks.
24 *
25 * Locking for timer-merging could be infinitely more fine-grained. A second
26 * hash could select a lock to use based on queue slot. This approach might
27 * also help with add_release in rt_domains.
28 *
29 * It should be possible to reserve a CPU for ftdumping.
30 *
31 * The real_deadline business seems sloppy.
32 *
33 * The amount of data in the header file should be cut down. The use of the
34 * header file in general needs to be re-examined.
35 *
36 * The plugin needs to be modified so that it doesn't freeze when it is
37 * deactivated in a VM.
38 *
39 * The locking in check_for_preempt is not fine-grained enough.
40 *
41 * The size of the structures could be smaller. Debugging info might be
42 * excessive as things currently stand.
43 *
44 * The macro can_requeue has been expanded too much. Anything beyond
45 * scheduled_on is a hack!
46 *
47 * Domain names (rt_domain) are still clumsy.
48 *
49 * Should BE be moved into the kernel? This will require benchmarking.
7 */ 50 */
8 51
9#include <linux/spinlock.h> 52#include <linux/spinlock.h>
@@ -110,7 +153,7 @@ static int cpu_lower_prio(struct bheap_node *a, struct bheap_node *b)
110} 153}
111 154
112/* 155/*
113 * Return true if the domain has a higher priority ready task. The curr 156 * Return true if the domain has a higher priority ready task. The @curr
114 * task must belong to the domain. 157 * task must belong to the domain.
115 */ 158 */
116static int mc_preempt_needed(struct domain *dom, struct task_struct* curr) 159static int mc_preempt_needed(struct domain *dom, struct task_struct* curr)
@@ -381,6 +424,7 @@ static void link_task_to_cpu(struct cpu_entry *entry, struct task_struct *task)
381 set_rt_flags(task, RT_F_RUNNING); 424 set_rt_flags(task, RT_F_RUNNING);
382 } 425 }
383 entry->linked = task; 426 entry->linked = task;
427
384 /* Higher criticality crit entries are now usable */ 428 /* Higher criticality crit entries are now usable */
385 for (; i < entry_level(entry) + 1; i++) { 429 for (; i < entry_level(entry) + 1; i++) {
386 ce = &entry->crit_entries[i]; 430 ce = &entry->crit_entries[i];
@@ -418,8 +462,7 @@ static void preempt(struct domain *dom, struct crit_entry *ce)
418 link_task_to_cpu(entry, task); 462 link_task_to_cpu(entry, task);
419 preempt_if_preemptable(entry->scheduled, entry->cpu); 463 preempt_if_preemptable(entry->scheduled, entry->cpu);
420 } else if (old && old == entry->linked) { 464 } else if (old && old == entry->linked) {
421 /* 465 /* Preempted a running task with a ghost job. Null needs to be
422 * Preempted a running task with a ghost job. Null needs to be
423 * running. 466 * running.
424 */ 467 */
425 link_task_to_cpu(entry, NULL); 468 link_task_to_cpu(entry, NULL);
@@ -444,7 +487,7 @@ static void update_crit_levels(struct cpu_entry *entry)
444 ce = &entry->crit_entries[i]; 487 ce = &entry->crit_entries[i];
445 488
446 global_preempted = ce->linked && 489 global_preempted = ce->linked &&
447 /* This task is running */ 490 /* This task is running on a cpu */
448 ce->linked->rt_param.scheduled_on == entry->cpu && 491 ce->linked->rt_param.scheduled_on == entry->cpu &&
449 /* But it was preempted */ 492 /* But it was preempted */
450 ce->linked != entry->linked && 493 ce->linked != entry->linked &&
@@ -970,14 +1013,12 @@ static struct task_struct* mc_schedule(struct task_struct* prev)
970 raw_spin_unlock(&entry->lock); 1013 raw_spin_unlock(&entry->lock);
971 raw_spin_lock(dom->lock); 1014 raw_spin_lock(dom->lock);
972 1015
973 /* Peek at task here to avoid lock use */ 1016 /* Do domain stuff before grabbing CPU locks */
974 dtask = dom->peek_ready(dom); 1017 dtask = dom->peek_ready(dom);
1018 fix_crit_position(ce);
975 1019
976 raw_spin_lock(&entry->lock); 1020 raw_spin_lock(&entry->lock);
977 1021
978 /* Now that we hold the domain lock...*/
979 fix_crit_position(ce);
980
981 if (!entry->linked && !ce->linked && dtask && can_use(ce)) { 1022 if (!entry->linked && !ce->linked && dtask && can_use(ce)) {
982 dom->take_ready(dom); 1023 dom->take_ready(dom);
983 link_task_to_crit(ce, dtask); 1024 link_task_to_crit(ce, dtask);