aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sched.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sched.c')
-rw-r--r--kernel/sched.c76
1 files changed, 30 insertions, 46 deletions
diff --git a/kernel/sched.c b/kernel/sched.c
index b18f231a4875..38933cafea8a 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -52,7 +52,6 @@
52#include <linux/cpu.h> 52#include <linux/cpu.h>
53#include <linux/cpuset.h> 53#include <linux/cpuset.h>
54#include <linux/percpu.h> 54#include <linux/percpu.h>
55#include <linux/cpu_acct.h>
56#include <linux/kthread.h> 55#include <linux/kthread.h>
57#include <linux/seq_file.h> 56#include <linux/seq_file.h>
58#include <linux/sysctl.h> 57#include <linux/sysctl.h>
@@ -217,15 +216,15 @@ static inline struct task_group *task_group(struct task_struct *p)
217} 216}
218 217
219/* Change a task's cfs_rq and parent entity if it moves across CPUs/groups */ 218/* Change a task's cfs_rq and parent entity if it moves across CPUs/groups */
220static inline void set_task_cfs_rq(struct task_struct *p) 219static inline void set_task_cfs_rq(struct task_struct *p, unsigned int cpu)
221{ 220{
222 p->se.cfs_rq = task_group(p)->cfs_rq[task_cpu(p)]; 221 p->se.cfs_rq = task_group(p)->cfs_rq[cpu];
223 p->se.parent = task_group(p)->se[task_cpu(p)]; 222 p->se.parent = task_group(p)->se[cpu];
224} 223}
225 224
226#else 225#else
227 226
228static inline void set_task_cfs_rq(struct task_struct *p) { } 227static inline void set_task_cfs_rq(struct task_struct *p, unsigned int cpu) { }
229 228
230#endif /* CONFIG_FAIR_GROUP_SCHED */ 229#endif /* CONFIG_FAIR_GROUP_SCHED */
231 230
@@ -456,18 +455,18 @@ static void update_rq_clock(struct rq *rq)
456 */ 455 */
457enum { 456enum {
458 SCHED_FEAT_NEW_FAIR_SLEEPERS = 1, 457 SCHED_FEAT_NEW_FAIR_SLEEPERS = 1,
459 SCHED_FEAT_START_DEBIT = 2, 458 SCHED_FEAT_WAKEUP_PREEMPT = 2,
460 SCHED_FEAT_TREE_AVG = 4, 459 SCHED_FEAT_START_DEBIT = 4,
461 SCHED_FEAT_APPROX_AVG = 8, 460 SCHED_FEAT_TREE_AVG = 8,
462 SCHED_FEAT_WAKEUP_PREEMPT = 16, 461 SCHED_FEAT_APPROX_AVG = 16,
463}; 462};
464 463
465const_debug unsigned int sysctl_sched_features = 464const_debug unsigned int sysctl_sched_features =
466 SCHED_FEAT_NEW_FAIR_SLEEPERS * 1 | 465 SCHED_FEAT_NEW_FAIR_SLEEPERS * 1 |
466 SCHED_FEAT_WAKEUP_PREEMPT * 1 |
467 SCHED_FEAT_START_DEBIT * 1 | 467 SCHED_FEAT_START_DEBIT * 1 |
468 SCHED_FEAT_TREE_AVG * 0 | 468 SCHED_FEAT_TREE_AVG * 0 |
469 SCHED_FEAT_APPROX_AVG * 0 | 469 SCHED_FEAT_APPROX_AVG * 0;
470 SCHED_FEAT_WAKEUP_PREEMPT * 1;
471 470
472#define sched_feat(x) (sysctl_sched_features & SCHED_FEAT_##x) 471#define sched_feat(x) (sysctl_sched_features & SCHED_FEAT_##x)
473 472
@@ -1023,10 +1022,16 @@ unsigned long weighted_cpuload(const int cpu)
1023 1022
1024static inline void __set_task_cpu(struct task_struct *p, unsigned int cpu) 1023static inline void __set_task_cpu(struct task_struct *p, unsigned int cpu)
1025{ 1024{
1025 set_task_cfs_rq(p, cpu);
1026#ifdef CONFIG_SMP 1026#ifdef CONFIG_SMP
1027 /*
1028 * After ->cpu is set up to a new value, task_rq_lock(p, ...) can be
1029 * successfuly executed on another CPU. We must ensure that updates of
1030 * per-task data have been completed by this moment.
1031 */
1032 smp_wmb();
1027 task_thread_info(p)->cpu = cpu; 1033 task_thread_info(p)->cpu = cpu;
1028#endif 1034#endif
1029 set_task_cfs_rq(p);
1030} 1035}
1031 1036
1032#ifdef CONFIG_SMP 1037#ifdef CONFIG_SMP
@@ -3338,13 +3343,9 @@ void account_user_time(struct task_struct *p, cputime_t cputime)
3338{ 3343{
3339 struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat; 3344 struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat;
3340 cputime64_t tmp; 3345 cputime64_t tmp;
3341 struct rq *rq = this_rq();
3342 3346
3343 p->utime = cputime_add(p->utime, cputime); 3347 p->utime = cputime_add(p->utime, cputime);
3344 3348
3345 if (p != rq->idle)
3346 cpuacct_charge(p, cputime);
3347
3348 /* Add user time to cpustat. */ 3349 /* Add user time to cpustat. */
3349 tmp = cputime_to_cputime64(cputime); 3350 tmp = cputime_to_cputime64(cputime);
3350 if (TASK_NICE(p) > 0) 3351 if (TASK_NICE(p) > 0)
@@ -3395,10 +3396,8 @@ void account_system_time(struct task_struct *p, int hardirq_offset,
3395 struct rq *rq = this_rq(); 3396 struct rq *rq = this_rq();
3396 cputime64_t tmp; 3397 cputime64_t tmp;
3397 3398
3398 if (p->flags & PF_VCPU) { 3399 if ((p->flags & PF_VCPU) && (irq_count() - hardirq_offset == 0))
3399 account_guest_time(p, cputime); 3400 return account_guest_time(p, cputime);
3400 return;
3401 }
3402 3401
3403 p->stime = cputime_add(p->stime, cputime); 3402 p->stime = cputime_add(p->stime, cputime);
3404 3403
@@ -3408,10 +3407,9 @@ void account_system_time(struct task_struct *p, int hardirq_offset,
3408 cpustat->irq = cputime64_add(cpustat->irq, tmp); 3407 cpustat->irq = cputime64_add(cpustat->irq, tmp);
3409 else if (softirq_count()) 3408 else if (softirq_count())
3410 cpustat->softirq = cputime64_add(cpustat->softirq, tmp); 3409 cpustat->softirq = cputime64_add(cpustat->softirq, tmp);
3411 else if (p != rq->idle) { 3410 else if (p != rq->idle)
3412 cpustat->system = cputime64_add(cpustat->system, tmp); 3411 cpustat->system = cputime64_add(cpustat->system, tmp);
3413 cpuacct_charge(p, cputime); 3412 else if (atomic_read(&rq->nr_iowait) > 0)
3414 } else if (atomic_read(&rq->nr_iowait) > 0)
3415 cpustat->iowait = cputime64_add(cpustat->iowait, tmp); 3413 cpustat->iowait = cputime64_add(cpustat->iowait, tmp);
3416 else 3414 else
3417 cpustat->idle = cputime64_add(cpustat->idle, tmp); 3415 cpustat->idle = cputime64_add(cpustat->idle, tmp);
@@ -3447,10 +3445,8 @@ void account_steal_time(struct task_struct *p, cputime_t steal)
3447 cpustat->iowait = cputime64_add(cpustat->iowait, tmp); 3445 cpustat->iowait = cputime64_add(cpustat->iowait, tmp);
3448 else 3446 else
3449 cpustat->idle = cputime64_add(cpustat->idle, tmp); 3447 cpustat->idle = cputime64_add(cpustat->idle, tmp);
3450 } else { 3448 } else
3451 cpustat->steal = cputime64_add(cpustat->steal, tmp); 3449 cpustat->steal = cputime64_add(cpustat->steal, tmp);
3452 cpuacct_charge(p, -tmp);
3453 }
3454} 3450}
3455 3451
3456/* 3452/*
@@ -5286,23 +5282,9 @@ static void migrate_live_tasks(int src_cpu)
5286} 5282}
5287 5283
5288/* 5284/*
5289 * activate_idle_task - move idle task to the _front_ of runqueue.
5290 */
5291static void activate_idle_task(struct task_struct *p, struct rq *rq)
5292{
5293 update_rq_clock(rq);
5294
5295 if (p->state == TASK_UNINTERRUPTIBLE)
5296 rq->nr_uninterruptible--;
5297
5298 enqueue_task(rq, p, 0);
5299 inc_nr_running(p, rq);
5300}
5301
5302/*
5303 * Schedules idle task to be the next runnable task on current CPU. 5285 * Schedules idle task to be the next runnable task on current CPU.
5304 * It does so by boosting its priority to highest possible and adding it to 5286 * It does so by boosting its priority to highest possible.
5305 * the _front_ of the runqueue. Used by CPU offline code. 5287 * Used by CPU offline code.
5306 */ 5288 */
5307void sched_idle_next(void) 5289void sched_idle_next(void)
5308{ 5290{
@@ -5322,8 +5304,8 @@ void sched_idle_next(void)
5322 5304
5323 __setscheduler(rq, p, SCHED_FIFO, MAX_RT_PRIO-1); 5305 __setscheduler(rq, p, SCHED_FIFO, MAX_RT_PRIO-1);
5324 5306
5325 /* Add idle task to the _front_ of its priority queue: */ 5307 update_rq_clock(rq);
5326 activate_idle_task(p, rq); 5308 activate_task(rq, p, 0);
5327 5309
5328 spin_unlock_irqrestore(&rq->lock, flags); 5310 spin_unlock_irqrestore(&rq->lock, flags);
5329} 5311}
@@ -7097,8 +7079,10 @@ void sched_move_task(struct task_struct *tsk)
7097 7079
7098 rq = task_rq_lock(tsk, &flags); 7080 rq = task_rq_lock(tsk, &flags);
7099 7081
7100 if (tsk->sched_class != &fair_sched_class) 7082 if (tsk->sched_class != &fair_sched_class) {
7083 set_task_cfs_rq(tsk, task_cpu(tsk));
7101 goto done; 7084 goto done;
7085 }
7102 7086
7103 update_rq_clock(rq); 7087 update_rq_clock(rq);
7104 7088
@@ -7111,7 +7095,7 @@ void sched_move_task(struct task_struct *tsk)
7111 tsk->sched_class->put_prev_task(rq, tsk); 7095 tsk->sched_class->put_prev_task(rq, tsk);
7112 } 7096 }
7113 7097
7114 set_task_cfs_rq(tsk); 7098 set_task_cfs_rq(tsk, task_cpu(tsk));
7115 7099
7116 if (on_rq) { 7100 if (on_rq) {
7117 if (unlikely(running)) 7101 if (unlikely(running))