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.c36
1 files changed, 17 insertions, 19 deletions
diff --git a/litmus/sched_mc.c b/litmus/sched_mc.c
index b2a9ca205be4..f360abf34035 100644
--- a/litmus/sched_mc.c
+++ b/litmus/sched_mc.c
@@ -183,7 +183,7 @@ static void update_ghost_time(struct task_struct *p)
183static inline void update_crit_position(struct crit_entry *ce) 183static inline void update_crit_position(struct crit_entry *ce)
184{ 184{
185 struct bheap *heap; 185 struct bheap *heap;
186 if (is_global(ce->domain)) { 186 if (is_global(ce->domain) && ce->usable) {
187 heap = domain_data(ce->domain)->heap; 187 heap = domain_data(ce->domain)->heap;
188 BUG_ON(!heap); 188 BUG_ON(!heap);
189 BUG_ON(!bheap_node_in_heap(ce->node)); 189 BUG_ON(!bheap_node_in_heap(ce->node));
@@ -451,9 +451,18 @@ static void check_for_preempt(struct domain *dom)
451 entry = crit_cpu(ce); 451 entry = crit_cpu(ce);
452 preempted = 0; 452 preempted = 0;
453 raw_spin_lock(&entry->lock); 453 raw_spin_lock(&entry->lock);
454 if (ce->usable && dom->preempt_needed(dom, ce->linked)){ 454
455 if (!ce->usable) {
456 TRACE_CRIT_ENTRY(ce, "Removing");
457 bheap_delete(cpu_lower_prio,
458 domain_data(dom)->heap, ce->node);
459 continue;
460 }
461 if (dom->preempt_needed(dom, ce->linked)){
455 preempted = 1; 462 preempted = 1;
456 preempt(dom, ce); 463 preempt(dom, ce);
464 } else {
465 TRACE_CRIT_ENTRY(ce, "Stopped global check\n");
457 } 466 }
458 raw_spin_unlock(&entry->lock); 467 raw_spin_unlock(&entry->lock);
459 } 468 }
@@ -486,10 +495,10 @@ static void remove_from_all(struct task_struct* task)
486 495
487 raw_spin_lock(dom->lock); 496 raw_spin_lock(dom->lock);
488 497
498 /* Remove the task from any CPU state */
489 if (task->rt_param.linked_on != NO_CPU) { 499 if (task->rt_param.linked_on != NO_CPU) {
490 entry = &per_cpu(cpus, task->rt_param.linked_on); 500 entry = &per_cpu(cpus, task->rt_param.linked_on);
491 raw_spin_lock(&entry->lock); 501 raw_spin_lock(&entry->lock);
492
493 /* Unlink only if task is still linked post lock */ 502 /* Unlink only if task is still linked post lock */
494 ce = &entry->crit_entries[tsk_mc_crit(task)]; 503 ce = &entry->crit_entries[tsk_mc_crit(task)];
495 if (task->rt_param.linked_on != NO_CPU) { 504 if (task->rt_param.linked_on != NO_CPU) {
@@ -501,23 +510,15 @@ static void remove_from_all(struct task_struct* task)
501 link_task_to_cpu(entry, NULL); 510 link_task_to_cpu(entry, NULL);
502 } 511 }
503 } 512 }
504
505 if (update) 513 if (update)
506 update_crit_levels(entry); 514 update_crit_levels(entry);
507 else 515 else
508 raw_spin_unlock(&entry->lock); 516 raw_spin_unlock(&entry->lock);
509 } 517 }
510 518
511 if (is_queued(task)) { 519 /* Ensure the task isn't returned by its domain */
512 /* This is an interesting situation: t is scheduled, 520 dom->remove(dom, task);
513 * but was just recently unlinked. It cannot be 521
514 * linked anywhere else (because then it would have
515 * been relinked to this CPU), thus it must be in some
516 * queue. We must remove it from the list in this
517 * case.
518 */
519 remove((rt_domain_t*)get_task_domain(task)->data, task);
520 }
521 BUG_ON(is_queued(task)); 522 BUG_ON(is_queued(task));
522 raw_spin_unlock(dom->lock); 523 raw_spin_unlock(dom->lock);
523} 524}
@@ -853,12 +854,9 @@ static struct task_struct* mc_schedule(struct task_struct * prev)
853 854
854 if (exists) { 855 if (exists) {
855 entry->scheduled->rt_param.scheduled_on = NO_CPU; 856 entry->scheduled->rt_param.scheduled_on = NO_CPU;
856 TRACE(TS
857 " blocks:%d out_of_time:%d sleep:%d preempt:%d "
858 "state:%d sig:%d global:%d\n", TA(prev),
859 blocks, out_of_time, sleep, preempt,
860 prev->state, signal_pending(prev), global);
861 } 857 }
858 TRACE(TS " blocks:%d out_of_time:%d sleep:%d preempt:%d\n",
859 TA(prev), blocks, out_of_time, sleep, preempt);
862 raw_spin_unlock(&entry->lock); 860 raw_spin_unlock(&entry->lock);
863 861
864 862