diff options
Diffstat (limited to 'litmus/sched_crm.c')
-rw-r--r-- | litmus/sched_crm.c | 72 |
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) | |||
425 | static void __do_lit_tasklet(struct tasklet_struct* tasklet, unsigned long flushed) | 426 | static 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 | ||
492 | static void flush_tasklets(crm_domain_t* cluster, struct task_struct* task) | 500 | static 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"); |