aboutsummaryrefslogtreecommitdiffstats
path: root/litmus/sched_mc.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2011-10-10 19:24:24 -0400
committerJonathan Herman <hermanjl@cs.unc.edu>2011-10-10 19:24:24 -0400
commit77870ba296b06385088f02516b7346fa7a7756b4 (patch)
treed3d6ebbb69f8159981bb7f83059436ec119d9eef /litmus/sched_mc.c
parent848defae3a19b7e4b160603995db35908fa2a95c (diff)
Fixed level-A crash when cancel task execution
Diffstat (limited to 'litmus/sched_mc.c')
-rw-r--r--litmus/sched_mc.c25
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