diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2016-09-01 12:33:46 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2016-09-01 12:33:46 -0400 |
commit | 0cb7bf61b1e9f05027de58c80f9b46a714d24e35 (patch) | |
tree | 41fb55cf62d07b425122f9a8b96412c0d8eb99c5 /kernel/sched | |
parent | aa877175e7a9982233ed8f10cb4bfddd78d82741 (diff) | |
parent | 3eab887a55424fc2c27553b7bfe32330df83f7b8 (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.c | 19 | ||||
-rw-r--r-- | kernel/sched/cpudeadline.c | 2 | ||||
-rw-r--r-- | kernel/sched/cputime.c | 41 | ||||
-rw-r--r-- | kernel/sched/deadline.c | 5 | ||||
-rw-r--r-- | kernel/sched/fair.c | 2 |
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); | |||
2972 | EXPORT_PER_CPU_SYMBOL(kernel_cpustat); | 2973 | EXPORT_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 | */ | ||
2981 | static 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 | */ | ||
266 | static __always_inline cputime_t steal_account_process_time(cputime_t maxtime) | 271 | static __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 | */ |
509 | void account_idle_ticks(unsigned long ticks) | 514 | void 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 | ||
640 | update: | ||
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 | ||
644 | update: | ||
645 | prev->stime = stime; | 663 | prev->stime = stime; |
646 | prev->utime = utime; | 664 | prev->utime = utime; |
647 | out: | 665 | out: |
@@ -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() */ |