aboutsummaryrefslogtreecommitdiffstats
path: root/litmus/sched_crm.c
diff options
context:
space:
mode:
Diffstat (limited to 'litmus/sched_crm.c')
-rw-r--r--litmus/sched_crm.c72
1 files changed, 58 insertions, 14 deletions
diff --git a/litmus/sched_crm.c b/litmus/sched_crm.c
index fd7fab982998..e51de10557f9 100644
--- a/litmus/sched_crm.c
+++ b/litmus/sched_crm.c
@@ -57,6 +57,7 @@
57 57
58#ifdef CONFIG_LITMUS_PAI_SOFTIRQD 58#ifdef CONFIG_LITMUS_PAI_SOFTIRQD
59#include <linux/interrupt.h> 59#include <linux/interrupt.h>
60#include <litmus/trace.h>
60#endif 61#endif
61 62
62#ifdef CONFIG_LITMUS_NVIDIA 63#ifdef CONFIG_LITMUS_NVIDIA
@@ -425,17 +426,24 @@ static void crm_tick(struct task_struct* t)
425static void __do_lit_tasklet(struct tasklet_struct* tasklet, unsigned long flushed) 426static void __do_lit_tasklet(struct tasklet_struct* tasklet, unsigned long flushed)
426{ 427{
427 if (!atomic_read(&tasklet->count)) { 428 if (!atomic_read(&tasklet->count)) {
428 sched_trace_tasklet_begin(tasklet->owner); 429 if(tasklet->owner) {
430 sched_trace_tasklet_begin(tasklet->owner);
431 }
429 432
430 if (!test_and_clear_bit(TASKLET_STATE_SCHED, &tasklet->state)) 433 if (!test_and_clear_bit(TASKLET_STATE_SCHED, &tasklet->state))
431 { 434 {
432 BUG(); 435 BUG();
433 } 436 }
434 TRACE("%s: Invoking tasklet with owner pid = %d (flushed = %d).\n", __FUNCTION__, tasklet->owner->pid, flushed); 437 TRACE("%s: Invoking tasklet with owner pid = %d (flushed = %d).\n",
438 __FUNCTION__,
439 (tasklet->owner) ? tasklet->owner->pid : -1,
440 (tasklet->owner) ? 0 : 1);
435 tasklet->func(tasklet->data); 441 tasklet->func(tasklet->data);
436 tasklet_unlock(tasklet); 442 tasklet_unlock(tasklet);
437 443
438 sched_trace_tasklet_end(tasklet->owner, flushed); 444 if(tasklet->owner) {
445 sched_trace_tasklet_end(tasklet->owner, flushed);
446 }
439 } 447 }
440 else { 448 else {
441 BUG(); 449 BUG();
@@ -491,6 +499,7 @@ static void __extract_tasklets(crm_domain_t* cluster, struct task_struct* task,
491 499
492static void flush_tasklets(crm_domain_t* cluster, struct task_struct* task) 500static void flush_tasklets(crm_domain_t* cluster, struct task_struct* task)
493{ 501{
502#if 0
494 unsigned long flags; 503 unsigned long flags;
495 struct tasklet_head task_tasklets; 504 struct tasklet_head task_tasklets;
496 struct tasklet_struct* step; 505 struct tasklet_struct* step;
@@ -513,6 +522,27 @@ static void flush_tasklets(crm_domain_t* cluster, struct task_struct* task)
513 522
514 step = temp; 523 step = temp;
515 } 524 }
525#endif
526
527 // lazy flushing.
528 // just change ownership to NULL and let an idle processor
529 // take care of it. :P
530
531 struct tasklet_struct* step;
532 unsigned long flags;
533
534 raw_spin_lock_irqsave(&cluster->crm_lock, flags);
535
536 for(step = cluster->pending_tasklets.head; step != NULL; step = step->next)
537 {
538 if(step->owner == task)
539 {
540 TRACE("%s: Found tasklet to flush: %d\n", __FUNCTION__, step->owner->pid);
541 step->owner = NULL;
542 }
543 }
544
545 raw_spin_unlock_irqrestore(&cluster->crm_lock, flags);
516} 546}
517 547
518 548
@@ -524,6 +554,9 @@ static void do_lit_tasklets(crm_domain_t* cluster, struct task_struct* sched_tas
524 unsigned long flags; 554 unsigned long flags;
525 555
526 while(work_to_do) { 556 while(work_to_do) {
557
558 TS_NV_SCHED_BOTISR_START;
559
527 // remove tasklet at head of list if it has higher priority. 560 // remove tasklet at head of list if it has higher priority.
528 raw_spin_lock_irqsave(&cluster->crm_lock, flags); 561 raw_spin_lock_irqsave(&cluster->crm_lock, flags);
529 562
@@ -546,17 +579,17 @@ static void do_lit_tasklets(crm_domain_t* cluster, struct task_struct* sched_tas
546 579
547 if(NULL == tasklet->next) { 580 if(NULL == tasklet->next) {
548 // tasklet is at the head, list only has one element 581 // tasklet is at the head, list only has one element
549 TRACE("%s: Tasklet for %d is the last element in tasklet queue.\n", __FUNCTION__, tasklet->owner->pid); 582 TRACE("%s: Tasklet for %d is the last element in tasklet queue.\n", __FUNCTION__, (tasklet->owner) ? tasklet->owner->pid : -1);
550 cluster->pending_tasklets.tail = &(cluster->pending_tasklets.head); 583 cluster->pending_tasklets.tail = &(cluster->pending_tasklets.head);
551 } 584 }
552 585
553 // remove the tasklet from the queue 586 // remove the tasklet from the queue
554 cluster->pending_tasklets.head = tasklet->next; 587 cluster->pending_tasklets.head = tasklet->next;
555 588
556 TRACE("%s: Removed tasklet for %d from tasklet queue.\n", __FUNCTION__, tasklet->owner->pid); 589 TRACE("%s: Removed tasklet for %d from tasklet queue.\n", __FUNCTION__, (tasklet->owner) ? tasklet->owner->pid : -1);
557 } 590 }
558 else { 591 else {
559 TRACE("%s: Pending tasklet (%d) does not have priority to run on this CPU (%d).\n", __FUNCTION__, tasklet->owner->pid, smp_processor_id()); 592 TRACE("%s: Pending tasklet (%d) does not have priority to run on this CPU (%d).\n", __FUNCTION__, (tasklet->owner) ? tasklet->owner->pid : -1, smp_processor_id());
560 tasklet = NULL; 593 tasklet = NULL;
561 } 594 }
562 } 595 }
@@ -577,6 +610,8 @@ static void do_lit_tasklets(crm_domain_t* cluster, struct task_struct* sched_tas
577 610
578 raw_spin_unlock_irqrestore(&cluster->crm_lock, flags); 611 raw_spin_unlock_irqrestore(&cluster->crm_lock, flags);
579 612
613 TS_NV_SCHED_BOTISR_END;
614
580 if(tasklet) { 615 if(tasklet) {
581 __do_lit_tasklet(tasklet, 0ul); 616 __do_lit_tasklet(tasklet, 0ul);
582 tasklet = NULL; 617 tasklet = NULL;
@@ -619,8 +654,8 @@ static void run_tasklets(struct task_struct* sched_task)
619 preempt_disable(); 654 preempt_disable();
620 655
621 cluster = (is_realtime(sched_task)) ? 656 cluster = (is_realtime(sched_task)) ?
622 task_cpu_cluster(sched_task) : 657 task_cpu_cluster(sched_task) :
623 remote_cluster(smp_processor_id()); 658 remote_cluster(smp_processor_id());
624 659
625 if(cluster && cluster->pending_tasklets.head != NULL) { 660 if(cluster && cluster->pending_tasklets.head != NULL) {
626 TRACE("%s: There are tasklets to process.\n", __FUNCTION__); 661 TRACE("%s: There are tasklets to process.\n", __FUNCTION__);
@@ -679,8 +714,17 @@ static void __add_pai_tasklet(struct tasklet_struct* tasklet, crm_domain_t* clus
679 714
680 // insert tasklet right before step->next. 715 // insert tasklet right before step->next.
681 716
682 TRACE("%s: inserting tasklet for %d between %d and %d.\n", __FUNCTION__, tasklet->owner->pid, step->owner->pid, (step->next) ? step->next->owner->pid : -1); 717 TRACE("%s: inserting tasklet for %d between %d and %d.\n", __FUNCTION__,
683 718 tasklet->owner->pid,
719 (step->owner) ?
720 step->owner->pid :
721 -1,
722 (step->next) ?
723 ((step->next->owner) ?
724 step->next->owner->pid :
725 -1) :
726 -1);
727
684 tasklet->next = step->next; 728 tasklet->next = step->next;
685 step->next = tasklet; 729 step->next = tasklet;
686 730
@@ -1070,6 +1114,10 @@ static void crm_task_exit(struct task_struct * t)
1070 unsigned long flags; 1114 unsigned long flags;
1071 crm_domain_t *cluster = task_cpu_cluster(t); 1115 crm_domain_t *cluster = task_cpu_cluster(t);
1072 1116
1117#ifdef CONFIG_LITMUS_PAI_SOFTIRQD
1118 flush_tasklets(cluster, t);
1119#endif
1120
1073 /* unlink if necessary */ 1121 /* unlink if necessary */
1074 raw_spin_lock_irqsave(&cluster->crm_lock, flags); 1122 raw_spin_lock_irqsave(&cluster->crm_lock, flags);
1075 unlink(t); 1123 unlink(t);
@@ -1080,10 +1128,6 @@ static void crm_task_exit(struct task_struct * t)
1080 tsk_rt(t)->scheduled_on = NO_CPU; 1128 tsk_rt(t)->scheduled_on = NO_CPU;
1081 } 1129 }
1082 raw_spin_unlock_irqrestore(&cluster->crm_lock, flags); 1130 raw_spin_unlock_irqrestore(&cluster->crm_lock, flags);
1083
1084#ifdef CONFIG_LITMUS_PAI_SOFTIRQD
1085 flush_tasklets(cluster, t);
1086#endif
1087 1131
1088 BUG_ON(!is_realtime(t)); 1132 BUG_ON(!is_realtime(t));
1089 TRACE_TASK(t, "RIP\n"); 1133 TRACE_TASK(t, "RIP\n");