diff options
-rw-r--r-- | include/linux/sched.h | 1 | ||||
-rw-r--r-- | kernel/sched.c | 31 | ||||
-rw-r--r-- | kernel/sched_fair.c | 8 | ||||
-rw-r--r-- | litmus/preempt.c | 4 |
4 files changed, 39 insertions, 5 deletions
diff --git a/include/linux/sched.h b/include/linux/sched.h index c9ac4fc837ba..0aaf530c9603 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -2308,6 +2308,7 @@ static inline void set_tsk_need_resched(struct task_struct *tsk) | |||
2308 | static inline void clear_tsk_need_resched(struct task_struct *tsk) | 2308 | static inline void clear_tsk_need_resched(struct task_struct *tsk) |
2309 | { | 2309 | { |
2310 | clear_tsk_thread_flag(tsk,TIF_NEED_RESCHED); | 2310 | clear_tsk_thread_flag(tsk,TIF_NEED_RESCHED); |
2311 | TRACE_TASK(tsk, "clear_tsk_need_resched\n"); | ||
2311 | } | 2312 | } |
2312 | 2313 | ||
2313 | static inline int test_tsk_need_resched(struct task_struct *tsk) | 2314 | static inline int test_tsk_need_resched(struct task_struct *tsk) |
diff --git a/kernel/sched.c b/kernel/sched.c index e4cfd193e76b..3682adadf6a7 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -79,6 +79,7 @@ | |||
79 | #include "sched_cpupri.h" | 79 | #include "sched_cpupri.h" |
80 | #include "workqueue_sched.h" | 80 | #include "workqueue_sched.h" |
81 | 81 | ||
82 | #include <litmus/litmus.h> | ||
82 | #include <litmus/debug_trace.h> | 83 | #include <litmus/debug_trace.h> |
83 | #include <litmus/sched_trace.h> | 84 | #include <litmus/sched_trace.h> |
84 | #include <litmus/trace.h> | 85 | #include <litmus/trace.h> |
@@ -462,6 +463,8 @@ struct rq { | |||
462 | /* runqueue lock: */ | 463 | /* runqueue lock: */ |
463 | raw_spinlock_t lock; | 464 | raw_spinlock_t lock; |
464 | 465 | ||
466 | int dbg_in_schedule; | ||
467 | |||
465 | /* | 468 | /* |
466 | * nr_running and cpu_load should be in the same cacheline because | 469 | * nr_running and cpu_load should be in the same cacheline because |
467 | * remote CPUs use both these fields when doing load calculation. | 470 | * remote CPUs use both these fields when doing load calculation. |
@@ -573,6 +576,8 @@ static DEFINE_PER_CPU_SHARED_ALIGNED(struct rq, runqueues); | |||
573 | static inline | 576 | static inline |
574 | void check_preempt_curr(struct rq *rq, struct task_struct *p, int flags) | 577 | void check_preempt_curr(struct rq *rq, struct task_struct *p, int flags) |
575 | { | 578 | { |
579 | if (test_tsk_need_resched(p)) | ||
580 | TRACE_TASK(p, "already need_resched when resuming\n"); | ||
576 | rq->curr->sched_class->check_preempt_curr(rq, p, flags); | 581 | rq->curr->sched_class->check_preempt_curr(rq, p, flags); |
577 | 582 | ||
578 | /* | 583 | /* |
@@ -1193,6 +1198,10 @@ static void resched_task(struct task_struct *p) | |||
1193 | if (test_tsk_need_resched(p)) | 1198 | if (test_tsk_need_resched(p)) |
1194 | return; | 1199 | return; |
1195 | 1200 | ||
1201 | if(task_rq(p)->dbg_in_schedule) | ||
1202 | TRACE_TASK(p, "XXXX calling resched_task() during schedule() from ret:0x%p [rt:%d nr_running:%d]\n", | ||
1203 | __builtin_return_address(0), is_realtime(p), task_rq(p)->nr_running); | ||
1204 | |||
1196 | set_tsk_need_resched(p); | 1205 | set_tsk_need_resched(p); |
1197 | 1206 | ||
1198 | cpu = task_cpu(p); | 1207 | cpu = task_cpu(p); |
@@ -3823,6 +3832,7 @@ need_resched_nonpreemptible: | |||
3823 | hrtick_clear(rq); | 3832 | hrtick_clear(rq); |
3824 | 3833 | ||
3825 | raw_spin_lock_irq(&rq->lock); | 3834 | raw_spin_lock_irq(&rq->lock); |
3835 | rq->dbg_in_schedule = 1; | ||
3826 | clear_tsk_need_resched(prev); | 3836 | clear_tsk_need_resched(prev); |
3827 | 3837 | ||
3828 | switch_count = &prev->nivcsw; | 3838 | switch_count = &prev->nivcsw; |
@@ -3840,20 +3850,35 @@ need_resched_nonpreemptible: | |||
3840 | struct task_struct *to_wakeup; | 3850 | struct task_struct *to_wakeup; |
3841 | 3851 | ||
3842 | to_wakeup = wq_worker_sleeping(prev, cpu); | 3852 | to_wakeup = wq_worker_sleeping(prev, cpu); |
3843 | if (to_wakeup) | 3853 | if (to_wakeup) { |
3854 | TRACE_TASK(prev, "try_to_wake_up_local(%s/%d)\n", to_wakeup->comm, to_wakeup->pid); | ||
3844 | try_to_wake_up_local(to_wakeup); | 3855 | try_to_wake_up_local(to_wakeup); |
3856 | } | ||
3845 | } | 3857 | } |
3846 | deactivate_task(rq, prev, DEQUEUE_SLEEP); | 3858 | deactivate_task(rq, prev, DEQUEUE_SLEEP); |
3847 | } | 3859 | } |
3848 | switch_count = &prev->nvcsw; | 3860 | switch_count = &prev->nvcsw; |
3849 | } | 3861 | } |
3850 | 3862 | ||
3863 | if (test_tsk_need_resched(prev)) | ||
3864 | TRACE_TASK(prev, "need_resched before pre_schedule()\n"); | ||
3865 | |||
3851 | pre_schedule(rq, prev); | 3866 | pre_schedule(rq, prev); |
3852 | 3867 | ||
3853 | if (unlikely(!rq->nr_running)) | 3868 | if (test_tsk_need_resched(prev)) |
3869 | TRACE_TASK(prev, "need_resched after pre_schedule()\n"); | ||
3870 | |||
3871 | if (unlikely(!rq->nr_running)) { | ||
3854 | idle_balance(cpu, rq); | 3872 | idle_balance(cpu, rq); |
3873 | if (test_tsk_need_resched(prev)) | ||
3874 | TRACE_TASK(prev, "need_resched after idle_balance\n"); | ||
3875 | } | ||
3855 | 3876 | ||
3856 | put_prev_task(rq, prev); | 3877 | put_prev_task(rq, prev); |
3878 | |||
3879 | if (test_tsk_need_resched(prev)) | ||
3880 | TRACE_TASK(prev, "need_resched after put_prev\n"); | ||
3881 | |||
3857 | next = pick_next_task(rq); | 3882 | next = pick_next_task(rq); |
3858 | 3883 | ||
3859 | if (likely(prev != next)) { | 3884 | if (likely(prev != next)) { |
@@ -3866,6 +3891,7 @@ need_resched_nonpreemptible: | |||
3866 | 3891 | ||
3867 | TS_SCHED_END(next); | 3892 | TS_SCHED_END(next); |
3868 | TS_CXS_START(next); | 3893 | TS_CXS_START(next); |
3894 | rq->dbg_in_schedule = 0; | ||
3869 | context_switch(rq, prev, next); /* unlocks the rq */ | 3895 | context_switch(rq, prev, next); /* unlocks the rq */ |
3870 | TS_CXS_END(current); | 3896 | TS_CXS_END(current); |
3871 | /* | 3897 | /* |
@@ -3878,6 +3904,7 @@ need_resched_nonpreemptible: | |||
3878 | rq = cpu_rq(cpu); | 3904 | rq = cpu_rq(cpu); |
3879 | } else { | 3905 | } else { |
3880 | TS_SCHED_END(prev); | 3906 | TS_SCHED_END(prev); |
3907 | rq->dbg_in_schedule = 0; | ||
3881 | raw_spin_unlock_irq(&rq->lock); | 3908 | raw_spin_unlock_irq(&rq->lock); |
3882 | } | 3909 | } |
3883 | 3910 | ||
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index e0e8d5ca3c98..47a38af8b30f 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c | |||
@@ -531,8 +531,14 @@ static void update_curr(struct cfs_rq *cfs_rq) | |||
531 | * overflow on 32 bits): | 531 | * overflow on 32 bits): |
532 | */ | 532 | */ |
533 | delta_exec = (unsigned long)(now - curr->exec_start); | 533 | delta_exec = (unsigned long)(now - curr->exec_start); |
534 | if (!delta_exec) | 534 | if (!delta_exec) { |
535 | if (rq_of(cfs_rq)->skip_clock_update) { | ||
536 | TRACE_TASK(rq_of(cfs_rq)->curr, | ||
537 | "rq->skip_clock_update [CFS] => sum_exec_runtime=%llu delta=0\n", | ||
538 | curr->sum_exec_runtime); | ||
539 | } | ||
535 | return; | 540 | return; |
541 | } | ||
536 | 542 | ||
537 | __update_curr(cfs_rq, curr, delta_exec); | 543 | __update_curr(cfs_rq, curr, delta_exec); |
538 | curr->exec_start = now; | 544 | curr->exec_start = now; |
diff --git a/litmus/preempt.c b/litmus/preempt.c index ebe2e3461895..ea13fd3bd3be 100644 --- a/litmus/preempt.c +++ b/litmus/preempt.c | |||
@@ -30,8 +30,8 @@ void sched_state_will_schedule(struct task_struct* tsk) | |||
30 | /* Litmus tasks should never be subject to a remote | 30 | /* Litmus tasks should never be subject to a remote |
31 | * set_tsk_need_resched(). */ | 31 | * set_tsk_need_resched(). */ |
32 | BUG_ON(is_realtime(tsk)); | 32 | BUG_ON(is_realtime(tsk)); |
33 | TRACE_TASK(tsk, "set_tsk_need_resched() ret:%p\n", | 33 | TRACE_TASK(tsk, "set_tsk_need_resched() ret:%p task_cpu:%d\n", |
34 | __builtin_return_address(0)); | 34 | __builtin_return_address(0), task_cpu(tsk)); |
35 | } | 35 | } |
36 | 36 | ||
37 | /* Called by the IPI handler after another CPU called smp_send_resched(). */ | 37 | /* Called by the IPI handler after another CPU called smp_send_resched(). */ |