diff options
Diffstat (limited to 'kernel/sched.c')
-rw-r--r-- | kernel/sched.c | 97 |
1 files changed, 68 insertions, 29 deletions
diff --git a/kernel/sched.c b/kernel/sched.c index 830967e18285..76c0e9691fc0 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -39,7 +39,7 @@ | |||
39 | #include <linux/completion.h> | 39 | #include <linux/completion.h> |
40 | #include <linux/kernel_stat.h> | 40 | #include <linux/kernel_stat.h> |
41 | #include <linux/debug_locks.h> | 41 | #include <linux/debug_locks.h> |
42 | #include <linux/perf_counter.h> | 42 | #include <linux/perf_event.h> |
43 | #include <linux/security.h> | 43 | #include <linux/security.h> |
44 | #include <linux/notifier.h> | 44 | #include <linux/notifier.h> |
45 | #include <linux/profile.h> | 45 | #include <linux/profile.h> |
@@ -780,7 +780,7 @@ static int sched_feat_open(struct inode *inode, struct file *filp) | |||
780 | return single_open(filp, sched_feat_show, NULL); | 780 | return single_open(filp, sched_feat_show, NULL); |
781 | } | 781 | } |
782 | 782 | ||
783 | static struct file_operations sched_feat_fops = { | 783 | static const struct file_operations sched_feat_fops = { |
784 | .open = sched_feat_open, | 784 | .open = sched_feat_open, |
785 | .write = sched_feat_write, | 785 | .write = sched_feat_write, |
786 | .read = seq_read, | 786 | .read = seq_read, |
@@ -2053,7 +2053,7 @@ void set_task_cpu(struct task_struct *p, unsigned int new_cpu) | |||
2053 | if (task_hot(p, old_rq->clock, NULL)) | 2053 | if (task_hot(p, old_rq->clock, NULL)) |
2054 | schedstat_inc(p, se.nr_forced2_migrations); | 2054 | schedstat_inc(p, se.nr_forced2_migrations); |
2055 | #endif | 2055 | #endif |
2056 | perf_swcounter_event(PERF_COUNT_SW_CPU_MIGRATIONS, | 2056 | perf_sw_event(PERF_COUNT_SW_CPU_MIGRATIONS, |
2057 | 1, 1, NULL, 0); | 2057 | 1, 1, NULL, 0); |
2058 | } | 2058 | } |
2059 | p->se.vruntime -= old_cfsrq->min_vruntime - | 2059 | p->se.vruntime -= old_cfsrq->min_vruntime - |
@@ -2515,22 +2515,17 @@ void sched_fork(struct task_struct *p, int clone_flags) | |||
2515 | __sched_fork(p); | 2515 | __sched_fork(p); |
2516 | 2516 | ||
2517 | /* | 2517 | /* |
2518 | * Make sure we do not leak PI boosting priority to the child. | ||
2519 | */ | ||
2520 | p->prio = current->normal_prio; | ||
2521 | |||
2522 | /* | ||
2523 | * Revert to default priority/policy on fork if requested. | 2518 | * Revert to default priority/policy on fork if requested. |
2524 | */ | 2519 | */ |
2525 | if (unlikely(p->sched_reset_on_fork)) { | 2520 | if (unlikely(p->sched_reset_on_fork)) { |
2526 | if (p->policy == SCHED_FIFO || p->policy == SCHED_RR) | 2521 | if (p->policy == SCHED_FIFO || p->policy == SCHED_RR) { |
2527 | p->policy = SCHED_NORMAL; | 2522 | p->policy = SCHED_NORMAL; |
2528 | 2523 | p->normal_prio = p->static_prio; | |
2529 | if (p->normal_prio < DEFAULT_PRIO) | 2524 | } |
2530 | p->prio = DEFAULT_PRIO; | ||
2531 | 2525 | ||
2532 | if (PRIO_TO_NICE(p->static_prio) < 0) { | 2526 | if (PRIO_TO_NICE(p->static_prio) < 0) { |
2533 | p->static_prio = NICE_TO_PRIO(0); | 2527 | p->static_prio = NICE_TO_PRIO(0); |
2528 | p->normal_prio = p->static_prio; | ||
2534 | set_load_weight(p); | 2529 | set_load_weight(p); |
2535 | } | 2530 | } |
2536 | 2531 | ||
@@ -2541,6 +2536,11 @@ void sched_fork(struct task_struct *p, int clone_flags) | |||
2541 | p->sched_reset_on_fork = 0; | 2536 | p->sched_reset_on_fork = 0; |
2542 | } | 2537 | } |
2543 | 2538 | ||
2539 | /* | ||
2540 | * Make sure we do not leak PI boosting priority to the child. | ||
2541 | */ | ||
2542 | p->prio = current->normal_prio; | ||
2543 | |||
2544 | if (!rt_prio(p->prio)) | 2544 | if (!rt_prio(p->prio)) |
2545 | p->sched_class = &fair_sched_class; | 2545 | p->sched_class = &fair_sched_class; |
2546 | 2546 | ||
@@ -2581,8 +2581,6 @@ void wake_up_new_task(struct task_struct *p, unsigned long clone_flags) | |||
2581 | BUG_ON(p->state != TASK_RUNNING); | 2581 | BUG_ON(p->state != TASK_RUNNING); |
2582 | update_rq_clock(rq); | 2582 | update_rq_clock(rq); |
2583 | 2583 | ||
2584 | p->prio = effective_prio(p); | ||
2585 | |||
2586 | if (!p->sched_class->task_new || !current->se.on_rq) { | 2584 | if (!p->sched_class->task_new || !current->se.on_rq) { |
2587 | activate_task(rq, p, 0); | 2585 | activate_task(rq, p, 0); |
2588 | } else { | 2586 | } else { |
@@ -2718,7 +2716,7 @@ static void finish_task_switch(struct rq *rq, struct task_struct *prev) | |||
2718 | */ | 2716 | */ |
2719 | prev_state = prev->state; | 2717 | prev_state = prev->state; |
2720 | finish_arch_switch(prev); | 2718 | finish_arch_switch(prev); |
2721 | perf_counter_task_sched_in(current, cpu_of(rq)); | 2719 | perf_event_task_sched_in(current, cpu_of(rq)); |
2722 | finish_lock_switch(rq, prev); | 2720 | finish_lock_switch(rq, prev); |
2723 | 2721 | ||
2724 | fire_sched_in_preempt_notifiers(current); | 2722 | fire_sched_in_preempt_notifiers(current); |
@@ -2904,6 +2902,19 @@ unsigned long nr_iowait(void) | |||
2904 | return sum; | 2902 | return sum; |
2905 | } | 2903 | } |
2906 | 2904 | ||
2905 | unsigned long nr_iowait_cpu(void) | ||
2906 | { | ||
2907 | struct rq *this = this_rq(); | ||
2908 | return atomic_read(&this->nr_iowait); | ||
2909 | } | ||
2910 | |||
2911 | unsigned long this_cpu_load(void) | ||
2912 | { | ||
2913 | struct rq *this = this_rq(); | ||
2914 | return this->cpu_load[0]; | ||
2915 | } | ||
2916 | |||
2917 | |||
2907 | /* Variables and functions for calc_load */ | 2918 | /* Variables and functions for calc_load */ |
2908 | static atomic_long_t calc_load_tasks; | 2919 | static atomic_long_t calc_load_tasks; |
2909 | static unsigned long calc_load_update; | 2920 | static unsigned long calc_load_update; |
@@ -5079,17 +5090,16 @@ void account_idle_time(cputime_t cputime) | |||
5079 | */ | 5090 | */ |
5080 | void account_process_tick(struct task_struct *p, int user_tick) | 5091 | void account_process_tick(struct task_struct *p, int user_tick) |
5081 | { | 5092 | { |
5082 | cputime_t one_jiffy = jiffies_to_cputime(1); | 5093 | cputime_t one_jiffy_scaled = cputime_to_scaled(cputime_one_jiffy); |
5083 | cputime_t one_jiffy_scaled = cputime_to_scaled(one_jiffy); | ||
5084 | struct rq *rq = this_rq(); | 5094 | struct rq *rq = this_rq(); |
5085 | 5095 | ||
5086 | if (user_tick) | 5096 | if (user_tick) |
5087 | account_user_time(p, one_jiffy, one_jiffy_scaled); | 5097 | account_user_time(p, cputime_one_jiffy, one_jiffy_scaled); |
5088 | else if ((p != rq->idle) || (irq_count() != HARDIRQ_OFFSET)) | 5098 | else if ((p != rq->idle) || (irq_count() != HARDIRQ_OFFSET)) |
5089 | account_system_time(p, HARDIRQ_OFFSET, one_jiffy, | 5099 | account_system_time(p, HARDIRQ_OFFSET, cputime_one_jiffy, |
5090 | one_jiffy_scaled); | 5100 | one_jiffy_scaled); |
5091 | else | 5101 | else |
5092 | account_idle_time(one_jiffy); | 5102 | account_idle_time(cputime_one_jiffy); |
5093 | } | 5103 | } |
5094 | 5104 | ||
5095 | /* | 5105 | /* |
@@ -5193,7 +5203,7 @@ void scheduler_tick(void) | |||
5193 | curr->sched_class->task_tick(rq, curr, 0); | 5203 | curr->sched_class->task_tick(rq, curr, 0); |
5194 | spin_unlock(&rq->lock); | 5204 | spin_unlock(&rq->lock); |
5195 | 5205 | ||
5196 | perf_counter_task_tick(curr, cpu); | 5206 | perf_event_task_tick(curr, cpu); |
5197 | 5207 | ||
5198 | #ifdef CONFIG_SMP | 5208 | #ifdef CONFIG_SMP |
5199 | rq->idle_at_tick = idle_cpu(cpu); | 5209 | rq->idle_at_tick = idle_cpu(cpu); |
@@ -5409,7 +5419,7 @@ need_resched_nonpreemptible: | |||
5409 | 5419 | ||
5410 | if (likely(prev != next)) { | 5420 | if (likely(prev != next)) { |
5411 | sched_info_switch(prev, next); | 5421 | sched_info_switch(prev, next); |
5412 | perf_counter_task_sched_out(prev, next, cpu); | 5422 | perf_event_task_sched_out(prev, next, cpu); |
5413 | 5423 | ||
5414 | rq->nr_switches++; | 5424 | rq->nr_switches++; |
5415 | rq->curr = next; | 5425 | rq->curr = next; |
@@ -7671,7 +7681,7 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu) | |||
7671 | /* | 7681 | /* |
7672 | * Register at high priority so that task migration (migrate_all_tasks) | 7682 | * Register at high priority so that task migration (migrate_all_tasks) |
7673 | * happens before everything else. This has to be lower priority than | 7683 | * happens before everything else. This has to be lower priority than |
7674 | * the notifier in the perf_counter subsystem, though. | 7684 | * the notifier in the perf_event subsystem, though. |
7675 | */ | 7685 | */ |
7676 | static struct notifier_block __cpuinitdata migration_notifier = { | 7686 | static struct notifier_block __cpuinitdata migration_notifier = { |
7677 | .notifier_call = migration_call, | 7687 | .notifier_call = migration_call, |
@@ -9528,7 +9538,7 @@ void __init sched_init(void) | |||
9528 | alloc_cpumask_var(&cpu_isolated_map, GFP_NOWAIT); | 9538 | alloc_cpumask_var(&cpu_isolated_map, GFP_NOWAIT); |
9529 | #endif /* SMP */ | 9539 | #endif /* SMP */ |
9530 | 9540 | ||
9531 | perf_counter_init(); | 9541 | perf_event_init(); |
9532 | 9542 | ||
9533 | scheduler_running = 1; | 9543 | scheduler_running = 1; |
9534 | } | 9544 | } |
@@ -10300,7 +10310,7 @@ static int sched_rt_global_constraints(void) | |||
10300 | #endif /* CONFIG_RT_GROUP_SCHED */ | 10310 | #endif /* CONFIG_RT_GROUP_SCHED */ |
10301 | 10311 | ||
10302 | int sched_rt_handler(struct ctl_table *table, int write, | 10312 | int sched_rt_handler(struct ctl_table *table, int write, |
10303 | struct file *filp, void __user *buffer, size_t *lenp, | 10313 | void __user *buffer, size_t *lenp, |
10304 | loff_t *ppos) | 10314 | loff_t *ppos) |
10305 | { | 10315 | { |
10306 | int ret; | 10316 | int ret; |
@@ -10311,7 +10321,7 @@ int sched_rt_handler(struct ctl_table *table, int write, | |||
10311 | old_period = sysctl_sched_rt_period; | 10321 | old_period = sysctl_sched_rt_period; |
10312 | old_runtime = sysctl_sched_rt_runtime; | 10322 | old_runtime = sysctl_sched_rt_runtime; |
10313 | 10323 | ||
10314 | ret = proc_dointvec(table, write, filp, buffer, lenp, ppos); | 10324 | ret = proc_dointvec(table, write, buffer, lenp, ppos); |
10315 | 10325 | ||
10316 | if (!ret && write) { | 10326 | if (!ret && write) { |
10317 | ret = sched_rt_global_constraints(); | 10327 | ret = sched_rt_global_constraints(); |
@@ -10365,8 +10375,7 @@ cpu_cgroup_destroy(struct cgroup_subsys *ss, struct cgroup *cgrp) | |||
10365 | } | 10375 | } |
10366 | 10376 | ||
10367 | static int | 10377 | static int |
10368 | cpu_cgroup_can_attach(struct cgroup_subsys *ss, struct cgroup *cgrp, | 10378 | cpu_cgroup_can_attach_task(struct cgroup *cgrp, struct task_struct *tsk) |
10369 | struct task_struct *tsk) | ||
10370 | { | 10379 | { |
10371 | #ifdef CONFIG_RT_GROUP_SCHED | 10380 | #ifdef CONFIG_RT_GROUP_SCHED |
10372 | if (!sched_rt_can_attach(cgroup_tg(cgrp), tsk)) | 10381 | if (!sched_rt_can_attach(cgroup_tg(cgrp), tsk)) |
@@ -10376,15 +10385,45 @@ cpu_cgroup_can_attach(struct cgroup_subsys *ss, struct cgroup *cgrp, | |||
10376 | if (tsk->sched_class != &fair_sched_class) | 10385 | if (tsk->sched_class != &fair_sched_class) |
10377 | return -EINVAL; | 10386 | return -EINVAL; |
10378 | #endif | 10387 | #endif |
10388 | return 0; | ||
10389 | } | ||
10379 | 10390 | ||
10391 | static int | ||
10392 | cpu_cgroup_can_attach(struct cgroup_subsys *ss, struct cgroup *cgrp, | ||
10393 | struct task_struct *tsk, bool threadgroup) | ||
10394 | { | ||
10395 | int retval = cpu_cgroup_can_attach_task(cgrp, tsk); | ||
10396 | if (retval) | ||
10397 | return retval; | ||
10398 | if (threadgroup) { | ||
10399 | struct task_struct *c; | ||
10400 | rcu_read_lock(); | ||
10401 | list_for_each_entry_rcu(c, &tsk->thread_group, thread_group) { | ||
10402 | retval = cpu_cgroup_can_attach_task(cgrp, c); | ||
10403 | if (retval) { | ||
10404 | rcu_read_unlock(); | ||
10405 | return retval; | ||
10406 | } | ||
10407 | } | ||
10408 | rcu_read_unlock(); | ||
10409 | } | ||
10380 | return 0; | 10410 | return 0; |
10381 | } | 10411 | } |
10382 | 10412 | ||
10383 | static void | 10413 | static void |
10384 | cpu_cgroup_attach(struct cgroup_subsys *ss, struct cgroup *cgrp, | 10414 | cpu_cgroup_attach(struct cgroup_subsys *ss, struct cgroup *cgrp, |
10385 | struct cgroup *old_cont, struct task_struct *tsk) | 10415 | struct cgroup *old_cont, struct task_struct *tsk, |
10416 | bool threadgroup) | ||
10386 | { | 10417 | { |
10387 | sched_move_task(tsk); | 10418 | sched_move_task(tsk); |
10419 | if (threadgroup) { | ||
10420 | struct task_struct *c; | ||
10421 | rcu_read_lock(); | ||
10422 | list_for_each_entry_rcu(c, &tsk->thread_group, thread_group) { | ||
10423 | sched_move_task(c); | ||
10424 | } | ||
10425 | rcu_read_unlock(); | ||
10426 | } | ||
10388 | } | 10427 | } |
10389 | 10428 | ||
10390 | #ifdef CONFIG_FAIR_GROUP_SCHED | 10429 | #ifdef CONFIG_FAIR_GROUP_SCHED |