aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sched
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2016-09-01 12:33:46 -0400
committerThomas Gleixner <tglx@linutronix.de>2016-09-01 12:33:46 -0400
commit0cb7bf61b1e9f05027de58c80f9b46a714d24e35 (patch)
tree41fb55cf62d07b425122f9a8b96412c0d8eb99c5 /kernel/sched
parentaa877175e7a9982233ed8f10cb4bfddd78d82741 (diff)
parent3eab887a55424fc2c27553b7bfe32330df83f7b8 (diff)
Merge branch 'linus' into smp/hotplug
Apply upstream changes to avoid conflicts with pending patches.
Diffstat (limited to 'kernel/sched')
-rw-r--r--kernel/sched/core.c19
-rw-r--r--kernel/sched/cpudeadline.c2
-rw-r--r--kernel/sched/cputime.c41
-rw-r--r--kernel/sched/deadline.c5
-rw-r--r--kernel/sched/fair.c2
5 files changed, 58 insertions, 11 deletions
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 5c883fe8e440..2a906f20fba7 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -74,6 +74,7 @@
74#include <linux/context_tracking.h> 74#include <linux/context_tracking.h>
75#include <linux/compiler.h> 75#include <linux/compiler.h>
76#include <linux/frame.h> 76#include <linux/frame.h>
77#include <linux/prefetch.h>
77 78
78#include <asm/switch_to.h> 79#include <asm/switch_to.h>
79#include <asm/tlb.h> 80#include <asm/tlb.h>
@@ -2972,6 +2973,23 @@ EXPORT_PER_CPU_SYMBOL(kstat);
2972EXPORT_PER_CPU_SYMBOL(kernel_cpustat); 2973EXPORT_PER_CPU_SYMBOL(kernel_cpustat);
2973 2974
2974/* 2975/*
2976 * The function fair_sched_class.update_curr accesses the struct curr
2977 * and its field curr->exec_start; when called from task_sched_runtime(),
2978 * we observe a high rate of cache misses in practice.
2979 * Prefetching this data results in improved performance.
2980 */
2981static inline void prefetch_curr_exec_start(struct task_struct *p)
2982{
2983#ifdef CONFIG_FAIR_GROUP_SCHED
2984 struct sched_entity *curr = (&p->se)->cfs_rq->curr;
2985#else
2986 struct sched_entity *curr = (&task_rq(p)->cfs)->curr;
2987#endif
2988 prefetch(curr);
2989 prefetch(&curr->exec_start);
2990}
2991
2992/*
2975 * Return accounted runtime for the task. 2993 * Return accounted runtime for the task.
2976 * In case the task is currently running, return the runtime plus current's 2994 * In case the task is currently running, return the runtime plus current's
2977 * pending runtime that have not been accounted yet. 2995 * pending runtime that have not been accounted yet.
@@ -3005,6 +3023,7 @@ unsigned long long task_sched_runtime(struct task_struct *p)
3005 * thread, breaking clock_gettime(). 3023 * thread, breaking clock_gettime().
3006 */ 3024 */
3007 if (task_current(rq, p) && task_on_rq_queued(p)) { 3025 if (task_current(rq, p) && task_on_rq_queued(p)) {
3026 prefetch_curr_exec_start(p);
3008 update_rq_clock(rq); 3027 update_rq_clock(rq);
3009 p->sched_class->update_curr(rq); 3028 p->sched_class->update_curr(rq);
3010 } 3029 }
diff --git a/kernel/sched/cpudeadline.c b/kernel/sched/cpudeadline.c
index 5be58820465c..d4184498c9f5 100644
--- a/kernel/sched/cpudeadline.c
+++ b/kernel/sched/cpudeadline.c
@@ -168,7 +168,7 @@ void cpudl_set(struct cpudl *cp, int cpu, u64 dl, int is_valid)
168 168
169 if (old_idx == IDX_INVALID) { 169 if (old_idx == IDX_INVALID) {
170 cp->size++; 170 cp->size++;
171 cp->elements[cp->size - 1].dl = 0; 171 cp->elements[cp->size - 1].dl = dl;
172 cp->elements[cp->size - 1].cpu = cpu; 172 cp->elements[cp->size - 1].cpu = cpu;
173 cp->elements[cpu].idx = cp->size - 1; 173 cp->elements[cpu].idx = cp->size - 1;
174 cpudl_change_key(cp, cp->size - 1, dl); 174 cpudl_change_key(cp, cp->size - 1, dl);
diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c
index 1934f658c036..a846cf89eb96 100644
--- a/kernel/sched/cputime.c
+++ b/kernel/sched/cputime.c
@@ -263,6 +263,11 @@ void account_idle_time(cputime_t cputime)
263 cpustat[CPUTIME_IDLE] += (__force u64) cputime; 263 cpustat[CPUTIME_IDLE] += (__force u64) cputime;
264} 264}
265 265
266/*
267 * When a guest is interrupted for a longer amount of time, missed clock
268 * ticks are not redelivered later. Due to that, this function may on
269 * occasion account more time than the calling functions think elapsed.
270 */
266static __always_inline cputime_t steal_account_process_time(cputime_t maxtime) 271static __always_inline cputime_t steal_account_process_time(cputime_t maxtime)
267{ 272{
268#ifdef CONFIG_PARAVIRT 273#ifdef CONFIG_PARAVIRT
@@ -371,7 +376,7 @@ static void irqtime_account_process_tick(struct task_struct *p, int user_tick,
371 * idle, or potentially user or system time. Due to rounding, 376 * idle, or potentially user or system time. Due to rounding,
372 * other time can exceed ticks occasionally. 377 * other time can exceed ticks occasionally.
373 */ 378 */
374 other = account_other_time(cputime); 379 other = account_other_time(ULONG_MAX);
375 if (other >= cputime) 380 if (other >= cputime)
376 return; 381 return;
377 cputime -= other; 382 cputime -= other;
@@ -486,7 +491,7 @@ void account_process_tick(struct task_struct *p, int user_tick)
486 } 491 }
487 492
488 cputime = cputime_one_jiffy; 493 cputime = cputime_one_jiffy;
489 steal = steal_account_process_time(cputime); 494 steal = steal_account_process_time(ULONG_MAX);
490 495
491 if (steal >= cputime) 496 if (steal >= cputime)
492 return; 497 return;
@@ -508,13 +513,21 @@ void account_process_tick(struct task_struct *p, int user_tick)
508 */ 513 */
509void account_idle_ticks(unsigned long ticks) 514void account_idle_ticks(unsigned long ticks)
510{ 515{
516 cputime_t cputime, steal;
511 517
512 if (sched_clock_irqtime) { 518 if (sched_clock_irqtime) {
513 irqtime_account_idle_ticks(ticks); 519 irqtime_account_idle_ticks(ticks);
514 return; 520 return;
515 } 521 }
516 522
517 account_idle_time(jiffies_to_cputime(ticks)); 523 cputime = jiffies_to_cputime(ticks);
524 steal = steal_account_process_time(ULONG_MAX);
525
526 if (steal >= cputime)
527 return;
528
529 cputime -= steal;
530 account_idle_time(cputime);
518} 531}
519 532
520/* 533/*
@@ -606,19 +619,25 @@ static void cputime_adjust(struct task_cputime *curr,
606 stime = curr->stime; 619 stime = curr->stime;
607 utime = curr->utime; 620 utime = curr->utime;
608 621
609 if (utime == 0) { 622 /*
610 stime = rtime; 623 * If either stime or both stime and utime are 0, assume all runtime is
624 * userspace. Once a task gets some ticks, the monotonicy code at
625 * 'update' will ensure things converge to the observed ratio.
626 */
627 if (stime == 0) {
628 utime = rtime;
611 goto update; 629 goto update;
612 } 630 }
613 631
614 if (stime == 0) { 632 if (utime == 0) {
615 utime = rtime; 633 stime = rtime;
616 goto update; 634 goto update;
617 } 635 }
618 636
619 stime = scale_stime((__force u64)stime, (__force u64)rtime, 637 stime = scale_stime((__force u64)stime, (__force u64)rtime,
620 (__force u64)(stime + utime)); 638 (__force u64)(stime + utime));
621 639
640update:
622 /* 641 /*
623 * Make sure stime doesn't go backwards; this preserves monotonicity 642 * Make sure stime doesn't go backwards; this preserves monotonicity
624 * for utime because rtime is monotonic. 643 * for utime because rtime is monotonic.
@@ -641,7 +660,6 @@ static void cputime_adjust(struct task_cputime *curr,
641 stime = rtime - utime; 660 stime = rtime - utime;
642 } 661 }
643 662
644update:
645 prev->stime = stime; 663 prev->stime = stime;
646 prev->utime = utime; 664 prev->utime = utime;
647out: 665out:
@@ -686,6 +704,13 @@ static cputime_t get_vtime_delta(struct task_struct *tsk)
686 unsigned long now = READ_ONCE(jiffies); 704 unsigned long now = READ_ONCE(jiffies);
687 cputime_t delta, other; 705 cputime_t delta, other;
688 706
707 /*
708 * Unlike tick based timing, vtime based timing never has lost
709 * ticks, and no need for steal time accounting to make up for
710 * lost ticks. Vtime accounts a rounded version of actual
711 * elapsed time. Limit account_other_time to prevent rounding
712 * errors from causing elapsed vtime to go negative.
713 */
689 delta = jiffies_to_cputime(now - tsk->vtime_snap); 714 delta = jiffies_to_cputime(now - tsk->vtime_snap);
690 other = account_other_time(delta); 715 other = account_other_time(delta);
691 WARN_ON_ONCE(tsk->vtime_snap_whence == VTIME_INACTIVE); 716 WARN_ON_ONCE(tsk->vtime_snap_whence == VTIME_INACTIVE);
diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
index fcb7f0217ff4..1ce8867283dc 100644
--- a/kernel/sched/deadline.c
+++ b/kernel/sched/deadline.c
@@ -658,8 +658,11 @@ static enum hrtimer_restart dl_task_timer(struct hrtimer *timer)
658 * 658 *
659 * XXX figure out if select_task_rq_dl() deals with offline cpus. 659 * XXX figure out if select_task_rq_dl() deals with offline cpus.
660 */ 660 */
661 if (unlikely(!rq->online)) 661 if (unlikely(!rq->online)) {
662 lockdep_unpin_lock(&rq->lock, rf.cookie);
662 rq = dl_task_offline_migration(rq, p); 663 rq = dl_task_offline_migration(rq, p);
664 rf.cookie = lockdep_pin_lock(&rq->lock);
665 }
663 666
664 /* 667 /*
665 * Queueing this task back might have overloaded rq, check if we need 668 * Queueing this task back might have overloaded rq, check if we need
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 4088eedea763..039de34f1521 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -4269,7 +4269,7 @@ static void sync_throttle(struct task_group *tg, int cpu)
4269 pcfs_rq = tg->parent->cfs_rq[cpu]; 4269 pcfs_rq = tg->parent->cfs_rq[cpu];
4270 4270
4271 cfs_rq->throttle_count = pcfs_rq->throttle_count; 4271 cfs_rq->throttle_count = pcfs_rq->throttle_count;
4272 pcfs_rq->throttled_clock_task = rq_clock_task(cpu_rq(cpu)); 4272 cfs_rq->throttled_clock_task = rq_clock_task(cpu_rq(cpu));
4273} 4273}
4274 4274
4275/* conditionally throttle active cfs_rq's from put_prev_entity() */ 4275/* conditionally throttle active cfs_rq's from put_prev_entity() */