diff options
| -rw-r--r-- | kernel/sched.c | 28 | ||||
| -rw-r--r-- | kernel/sched_debug.c | 4 |
2 files changed, 30 insertions, 2 deletions
diff --git a/kernel/sched.c b/kernel/sched.c index 651c899a9b74..a6f6869fdefb 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
| @@ -541,6 +541,11 @@ struct rq { | |||
| 541 | unsigned long long rq_cpu_time; | 541 | unsigned long long rq_cpu_time; |
| 542 | /* could above be rq->cfs_rq.exec_clock + rq->rt_rq.rt_runtime ? */ | 542 | /* could above be rq->cfs_rq.exec_clock + rq->rt_rq.rt_runtime ? */ |
| 543 | 543 | ||
| 544 | u64 skip_clock_max; | ||
| 545 | u64 skip_clock_recent_max; | ||
| 546 | u64 skip_clock_set; | ||
| 547 | unsigned int skip_clock_count; | ||
| 548 | |||
| 544 | /* sys_sched_yield() stats */ | 549 | /* sys_sched_yield() stats */ |
| 545 | unsigned int yld_count; | 550 | unsigned int yld_count; |
| 546 | 551 | ||
| @@ -639,6 +644,22 @@ static inline struct task_group *task_group(struct task_struct *p) | |||
| 639 | static u64 irq_time_cpu(int cpu); | 644 | static u64 irq_time_cpu(int cpu); |
| 640 | static void sched_irq_time_avg_update(struct rq *rq, u64 irq_time); | 645 | static void sched_irq_time_avg_update(struct rq *rq, u64 irq_time); |
| 641 | 646 | ||
| 647 | static void clear_skip_clock_update(struct rq *rq) | ||
| 648 | { | ||
| 649 | #ifdef CONFIG_SCHEDSTATS | ||
| 650 | if (unlikely(rq->skip_clock_update)) { | ||
| 651 | u64 skipped = sched_clock_cpu(cpu_of(rq)) - rq->skip_clock_set; | ||
| 652 | rq->skip_clock_max = max(rq->skip_clock_max, skipped); | ||
| 653 | /* reset infrequently to expose changes */ | ||
| 654 | if (!(++rq->skip_clock_count % 10000)) | ||
| 655 | rq->skip_clock_recent_max = 0; | ||
| 656 | rq->skip_clock_recent_max = max(rq->skip_clock_recent_max, | ||
| 657 | skipped); | ||
| 658 | } | ||
| 659 | #endif | ||
| 660 | rq->skip_clock_update = 0; | ||
| 661 | } | ||
| 662 | |||
| 642 | inline void update_rq_clock(struct rq *rq) | 663 | inline void update_rq_clock(struct rq *rq) |
| 643 | { | 664 | { |
| 644 | if (!rq->skip_clock_update) { | 665 | if (!rq->skip_clock_update) { |
| @@ -652,7 +673,7 @@ inline void update_rq_clock(struct rq *rq) | |||
| 652 | 673 | ||
| 653 | sched_irq_time_avg_update(rq, irq_time); | 674 | sched_irq_time_avg_update(rq, irq_time); |
| 654 | } | 675 | } |
| 655 | rq->skip_clock_update = 0; | 676 | clear_skip_clock_update(rq); |
| 656 | } | 677 | } |
| 657 | 678 | ||
| 658 | /* | 679 | /* |
| @@ -2130,8 +2151,11 @@ static void check_preempt_curr(struct rq *rq, struct task_struct *p, int flags) | |||
| 2130 | * A queue event has occurred, and we're going to schedule. In | 2151 | * A queue event has occurred, and we're going to schedule. In |
| 2131 | * this case, we can save a useless back to back clock update. | 2152 | * this case, we can save a useless back to back clock update. |
| 2132 | */ | 2153 | */ |
| 2133 | if (rq->curr->se.on_rq && test_tsk_need_resched(rq->curr)) | 2154 | if (rq->curr->se.on_rq && test_tsk_need_resched(rq->curr)) { |
| 2155 | schedstat_set(rq->skip_clock_set, | ||
| 2156 | sched_clock_cpu(cpu_of(rq))); | ||
| 2134 | rq->skip_clock_update = 1; | 2157 | rq->skip_clock_update = 1; |
| 2158 | } | ||
| 2135 | } | 2159 | } |
| 2136 | 2160 | ||
| 2137 | #ifdef CONFIG_SMP | 2161 | #ifdef CONFIG_SMP |
diff --git a/kernel/sched_debug.c b/kernel/sched_debug.c index 2e1b0d17dd9b..8924be259506 100644 --- a/kernel/sched_debug.c +++ b/kernel/sched_debug.c | |||
| @@ -298,6 +298,10 @@ static void print_cpu(struct seq_file *m, int cpu) | |||
| 298 | 298 | ||
| 299 | P(bkl_count); | 299 | P(bkl_count); |
| 300 | 300 | ||
| 301 | P(skip_clock_count); | ||
| 302 | P64(skip_clock_recent_max); | ||
| 303 | P64(skip_clock_max); | ||
| 304 | |||
| 301 | #undef P | 305 | #undef P |
| 302 | #endif | 306 | #endif |
| 303 | print_cfs_stats(m, cpu); | 307 | print_cfs_stats(m, cpu); |
