diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2011-10-10 19:24:24 -0400 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2011-10-10 19:24:24 -0400 |
commit | 77870ba296b06385088f02516b7346fa7a7756b4 (patch) | |
tree | d3d6ebbb69f8159981bb7f83059436ec119d9eef /litmus/sched_mc.c | |
parent | 848defae3a19b7e4b160603995db35908fa2a95c (diff) |
Fixed level-A crash when cancel task execution
Diffstat (limited to 'litmus/sched_mc.c')
-rw-r--r-- | litmus/sched_mc.c | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/litmus/sched_mc.c b/litmus/sched_mc.c index 5067b79b026b..9edf038ef164 100644 --- a/litmus/sched_mc.c +++ b/litmus/sched_mc.c | |||
@@ -492,6 +492,9 @@ static void check_for_preempt(struct domain *dom) | |||
492 | entry = crit_cpu(ce); | 492 | entry = crit_cpu(ce); |
493 | recheck = 1; | 493 | recheck = 1; |
494 | 494 | ||
495 | /* Cache ready task */ | ||
496 | dom->peek_ready(dom); | ||
497 | |||
495 | raw_spin_lock(&entry->lock); | 498 | raw_spin_lock(&entry->lock); |
496 | if (!can_use(ce)) | 499 | if (!can_use(ce)) |
497 | /* CPU disabled while locking! */ | 500 | /* CPU disabled while locking! */ |
@@ -530,6 +533,8 @@ static void remove_from_all(struct task_struct* task) | |||
530 | struct crit_entry *ce; | 533 | struct crit_entry *ce; |
531 | struct domain *dom = get_task_domain(task); | 534 | struct domain *dom = get_task_domain(task); |
532 | 535 | ||
536 | QT_START; | ||
537 | |||
533 | TRACE_MC_TASK(task, "Removing from everything\n"); | 538 | TRACE_MC_TASK(task, "Removing from everything\n"); |
534 | BUG_ON(!task); | 539 | BUG_ON(!task); |
535 | 540 | ||
@@ -551,7 +556,7 @@ static void remove_from_all(struct task_struct* task) | |||
551 | link_task_to_cpu(entry, NULL); | 556 | link_task_to_cpu(entry, NULL); |
552 | } | 557 | } |
553 | } else { | 558 | } else { |
554 | TRACE_MC_TASK(task, "Unlinked before we got lock!"); | 559 | TRACE_MC_TASK(task, "Unlinked before we got lock!\n"); |
555 | } | 560 | } |
556 | if (update) | 561 | if (update) |
557 | update_crit_levels(entry); | 562 | update_crit_levels(entry); |
@@ -566,6 +571,7 @@ static void remove_from_all(struct task_struct* task) | |||
566 | 571 | ||
567 | BUG_ON(is_queued(task)); | 572 | BUG_ON(is_queued(task)); |
568 | raw_spin_unlock(dom->lock); | 573 | raw_spin_unlock(dom->lock); |
574 | QT_END; | ||
569 | } | 575 | } |
570 | 576 | ||
571 | /** | 577 | /** |
@@ -663,6 +669,7 @@ static lt_t __ce_timer_function(struct ce_dom_data *ce_data) | |||
663 | struct domain *dom = ce->domain; | 669 | struct domain *dom = ce->domain; |
664 | struct task_struct *old_link = NULL; | 670 | struct task_struct *old_link = NULL; |
665 | lt_t next_timer_abs; | 671 | lt_t next_timer_abs; |
672 | QT_START; | ||
666 | 673 | ||
667 | TRACE("MC level-A timer callback for CPU %d\n", ce_data->cpu); | 674 | TRACE("MC level-A timer callback for CPU %d\n", ce_data->cpu); |
668 | 675 | ||
@@ -692,6 +699,7 @@ static lt_t __ce_timer_function(struct ce_dom_data *ce_data) | |||
692 | raw_spin_unlock(dom->lock); | 699 | raw_spin_unlock(dom->lock); |
693 | check_for_preempt(dom); | 700 | check_for_preempt(dom); |
694 | } | 701 | } |
702 | QT_END; | ||
695 | return next_timer_abs; | 703 | return next_timer_abs; |
696 | } | 704 | } |
697 | 705 | ||
@@ -734,11 +742,15 @@ static void mc_release_jobs(rt_domain_t* rt, struct bheap* tasks) | |||
734 | struct task_struct *first = bheap_peek(rt->order, tasks)->value; | 742 | struct task_struct *first = bheap_peek(rt->order, tasks)->value; |
735 | struct domain *dom = get_task_domain(first); | 743 | struct domain *dom = get_task_domain(first); |
736 | 744 | ||
745 | QT_START; | ||
746 | |||
737 | raw_spin_lock_irqsave(dom->lock, flags); | 747 | raw_spin_lock_irqsave(dom->lock, flags); |
738 | TRACE(TS "Jobs released\n", TA(first)); | 748 | TRACE(TS "Jobs released\n", TA(first)); |
739 | __merge_ready(rt, tasks); | 749 | __merge_ready(rt, tasks); |
740 | check_for_preempt(dom); | 750 | check_for_preempt(dom); |
741 | raw_spin_unlock_irqrestore(dom->lock, flags); | 751 | raw_spin_unlock_irqrestore(dom->lock, flags); |
752 | |||
753 | QT_END; | ||
742 | } | 754 | } |
743 | 755 | ||
744 | /** | 756 | /** |
@@ -877,6 +889,7 @@ static struct task_struct* mc_schedule(struct task_struct* prev) | |||
877 | struct cpu_entry* entry = &__get_cpu_var(cpus); | 889 | struct cpu_entry* entry = &__get_cpu_var(cpus); |
878 | int i, out_of_time, sleep, preempt, exists, blocks, global, lower; | 890 | int i, out_of_time, sleep, preempt, exists, blocks, global, lower; |
879 | struct task_struct *dtask = NULL, *ready_task = NULL, *next = NULL; | 891 | struct task_struct *dtask = NULL, *ready_task = NULL, *next = NULL; |
892 | QT_START; | ||
880 | 893 | ||
881 | local_irq_save(flags); | 894 | local_irq_save(flags); |
882 | raw_spin_lock(&entry->lock); | 895 | raw_spin_lock(&entry->lock); |
@@ -944,12 +957,15 @@ static struct task_struct* mc_schedule(struct task_struct* prev) | |||
944 | */ | 957 | */ |
945 | raw_spin_unlock(&entry->lock); | 958 | raw_spin_unlock(&entry->lock); |
946 | raw_spin_lock(dom->lock); | 959 | raw_spin_lock(dom->lock); |
960 | |||
961 | /* Peek at task here to avoid lock use */ | ||
962 | dtask = dom->peek_ready(dom); | ||
963 | |||
947 | raw_spin_lock(&entry->lock); | 964 | raw_spin_lock(&entry->lock); |
948 | 965 | ||
949 | /* Now that we hold the domain lock...*/ | 966 | /* Now that we hold the domain lock...*/ |
950 | fix_crit_position(ce); | 967 | fix_crit_position(ce); |
951 | 968 | ||
952 | dtask = dom->peek_ready(dom); | ||
953 | if (!entry->linked && !ce->linked && dtask && can_use(ce)) { | 969 | if (!entry->linked && !ce->linked && dtask && can_use(ce)) { |
954 | dom->take_ready(dom); | 970 | dom->take_ready(dom); |
955 | link_task_to_crit(ce, dtask); | 971 | link_task_to_crit(ce, dtask); |
@@ -977,9 +993,10 @@ static struct task_struct* mc_schedule(struct task_struct* prev) | |||
977 | raw_spin_unlock(&entry->lock); | 993 | raw_spin_unlock(&entry->lock); |
978 | local_irq_restore(flags); | 994 | local_irq_restore(flags); |
979 | if (next) { | 995 | if (next) { |
980 | TRACE_TASK(next, "Picked this task\n"); | 996 | TRACE_MC_TASK(next, "Picked this task\n"); |
981 | } else if (exists && !next) | 997 | } else if (exists && !next) |
982 | TRACE_ENTRY(entry, "Becomes idle at %llu\n", litmus_clock()); | 998 | TRACE_ENTRY(entry, "Becomes idle at %llu\n", litmus_clock()); |
999 | QT_END; | ||
983 | return next; | 1000 | return next; |
984 | } | 1001 | } |
985 | 1002 | ||
@@ -987,7 +1004,7 @@ void mc_finish_switch(struct task_struct *prev) | |||
987 | { | 1004 | { |
988 | struct cpu_entry* entry = &__get_cpu_var(cpus); | 1005 | struct cpu_entry* entry = &__get_cpu_var(cpus); |
989 | entry->scheduled = is_realtime(current) ? current : NULL; | 1006 | entry->scheduled = is_realtime(current) ? current : NULL; |
990 | TRACE_TASK(prev, "Switched away from to " TS, | 1007 | TRACE_TASK(prev, "Switched away from to " TS "\n", |
991 | TA(entry->scheduled)); | 1008 | TA(entry->scheduled)); |
992 | } | 1009 | } |
993 | 1010 | ||