diff options
Diffstat (limited to 'kernel/sched.c')
-rw-r--r-- | kernel/sched.c | 49 |
1 files changed, 34 insertions, 15 deletions
diff --git a/kernel/sched.c b/kernel/sched.c index 6a212c97f52..3c2a54f70ff 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -71,6 +71,7 @@ | |||
71 | #include <linux/debugfs.h> | 71 | #include <linux/debugfs.h> |
72 | #include <linux/ctype.h> | 72 | #include <linux/ctype.h> |
73 | #include <linux/ftrace.h> | 73 | #include <linux/ftrace.h> |
74 | #include <linux/slab.h> | ||
74 | 75 | ||
75 | #include <asm/tlb.h> | 76 | #include <asm/tlb.h> |
76 | #include <asm/irq_regs.h> | 77 | #include <asm/irq_regs.h> |
@@ -322,6 +323,15 @@ static inline struct task_group *task_group(struct task_struct *p) | |||
322 | /* Change a task's cfs_rq and parent entity if it moves across CPUs/groups */ | 323 | /* Change a task's cfs_rq and parent entity if it moves across CPUs/groups */ |
323 | static inline void set_task_rq(struct task_struct *p, unsigned int cpu) | 324 | static inline void set_task_rq(struct task_struct *p, unsigned int cpu) |
324 | { | 325 | { |
326 | /* | ||
327 | * Strictly speaking this rcu_read_lock() is not needed since the | ||
328 | * task_group is tied to the cgroup, which in turn can never go away | ||
329 | * as long as there are tasks attached to it. | ||
330 | * | ||
331 | * However since task_group() uses task_subsys_state() which is an | ||
332 | * rcu_dereference() user, this quiets CONFIG_PROVE_RCU. | ||
333 | */ | ||
334 | rcu_read_lock(); | ||
325 | #ifdef CONFIG_FAIR_GROUP_SCHED | 335 | #ifdef CONFIG_FAIR_GROUP_SCHED |
326 | p->se.cfs_rq = task_group(p)->cfs_rq[cpu]; | 336 | p->se.cfs_rq = task_group(p)->cfs_rq[cpu]; |
327 | p->se.parent = task_group(p)->se[cpu]; | 337 | p->se.parent = task_group(p)->se[cpu]; |
@@ -331,6 +341,7 @@ static inline void set_task_rq(struct task_struct *p, unsigned int cpu) | |||
331 | p->rt.rt_rq = task_group(p)->rt_rq[cpu]; | 341 | p->rt.rt_rq = task_group(p)->rt_rq[cpu]; |
332 | p->rt.parent = task_group(p)->rt_se[cpu]; | 342 | p->rt.parent = task_group(p)->rt_se[cpu]; |
333 | #endif | 343 | #endif |
344 | rcu_read_unlock(); | ||
334 | } | 345 | } |
335 | 346 | ||
336 | #else | 347 | #else |
@@ -1521,7 +1532,7 @@ static unsigned long cpu_avg_load_per_task(int cpu) | |||
1521 | 1532 | ||
1522 | #ifdef CONFIG_FAIR_GROUP_SCHED | 1533 | #ifdef CONFIG_FAIR_GROUP_SCHED |
1523 | 1534 | ||
1524 | static __read_mostly unsigned long *update_shares_data; | 1535 | static __read_mostly unsigned long __percpu *update_shares_data; |
1525 | 1536 | ||
1526 | static void __set_se_shares(struct sched_entity *se, unsigned long shares); | 1537 | static void __set_se_shares(struct sched_entity *se, unsigned long shares); |
1527 | 1538 | ||
@@ -2359,7 +2370,7 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state, | |||
2359 | { | 2370 | { |
2360 | int cpu, orig_cpu, this_cpu, success = 0; | 2371 | int cpu, orig_cpu, this_cpu, success = 0; |
2361 | unsigned long flags; | 2372 | unsigned long flags; |
2362 | struct rq *rq, *orig_rq; | 2373 | struct rq *rq; |
2363 | 2374 | ||
2364 | if (!sched_feat(SYNC_WAKEUPS)) | 2375 | if (!sched_feat(SYNC_WAKEUPS)) |
2365 | wake_flags &= ~WF_SYNC; | 2376 | wake_flags &= ~WF_SYNC; |
@@ -2367,7 +2378,7 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state, | |||
2367 | this_cpu = get_cpu(); | 2378 | this_cpu = get_cpu(); |
2368 | 2379 | ||
2369 | smp_wmb(); | 2380 | smp_wmb(); |
2370 | rq = orig_rq = task_rq_lock(p, &flags); | 2381 | rq = task_rq_lock(p, &flags); |
2371 | update_rq_clock(rq); | 2382 | update_rq_clock(rq); |
2372 | if (!(p->state & state)) | 2383 | if (!(p->state & state)) |
2373 | goto out; | 2384 | goto out; |
@@ -2650,7 +2661,7 @@ void wake_up_new_task(struct task_struct *p, unsigned long clone_flags) | |||
2650 | { | 2661 | { |
2651 | unsigned long flags; | 2662 | unsigned long flags; |
2652 | struct rq *rq; | 2663 | struct rq *rq; |
2653 | int cpu = get_cpu(); | 2664 | int cpu __maybe_unused = get_cpu(); |
2654 | 2665 | ||
2655 | #ifdef CONFIG_SMP | 2666 | #ifdef CONFIG_SMP |
2656 | /* | 2667 | /* |
@@ -3779,7 +3790,7 @@ int mutex_spin_on_owner(struct mutex *lock, struct thread_info *owner) | |||
3779 | * the mutex owner just released it and exited. | 3790 | * the mutex owner just released it and exited. |
3780 | */ | 3791 | */ |
3781 | if (probe_kernel_address(&owner->cpu, cpu)) | 3792 | if (probe_kernel_address(&owner->cpu, cpu)) |
3782 | goto out; | 3793 | return 0; |
3783 | #else | 3794 | #else |
3784 | cpu = owner->cpu; | 3795 | cpu = owner->cpu; |
3785 | #endif | 3796 | #endif |
@@ -3789,14 +3800,14 @@ int mutex_spin_on_owner(struct mutex *lock, struct thread_info *owner) | |||
3789 | * the cpu field may no longer be valid. | 3800 | * the cpu field may no longer be valid. |
3790 | */ | 3801 | */ |
3791 | if (cpu >= nr_cpumask_bits) | 3802 | if (cpu >= nr_cpumask_bits) |
3792 | goto out; | 3803 | return 0; |
3793 | 3804 | ||
3794 | /* | 3805 | /* |
3795 | * We need to validate that we can do a | 3806 | * We need to validate that we can do a |
3796 | * get_cpu() and that we have the percpu area. | 3807 | * get_cpu() and that we have the percpu area. |
3797 | */ | 3808 | */ |
3798 | if (!cpu_online(cpu)) | 3809 | if (!cpu_online(cpu)) |
3799 | goto out; | 3810 | return 0; |
3800 | 3811 | ||
3801 | rq = cpu_rq(cpu); | 3812 | rq = cpu_rq(cpu); |
3802 | 3813 | ||
@@ -3815,7 +3826,7 @@ int mutex_spin_on_owner(struct mutex *lock, struct thread_info *owner) | |||
3815 | 3826 | ||
3816 | cpu_relax(); | 3827 | cpu_relax(); |
3817 | } | 3828 | } |
3818 | out: | 3829 | |
3819 | return 1; | 3830 | return 1; |
3820 | } | 3831 | } |
3821 | #endif | 3832 | #endif |
@@ -4353,7 +4364,7 @@ int can_nice(const struct task_struct *p, const int nice) | |||
4353 | /* convert nice value [19,-20] to rlimit style value [1,40] */ | 4364 | /* convert nice value [19,-20] to rlimit style value [1,40] */ |
4354 | int nice_rlim = 20 - nice; | 4365 | int nice_rlim = 20 - nice; |
4355 | 4366 | ||
4356 | return (nice_rlim <= p->signal->rlim[RLIMIT_NICE].rlim_cur || | 4367 | return (nice_rlim <= task_rlimit(p, RLIMIT_NICE) || |
4357 | capable(CAP_SYS_NICE)); | 4368 | capable(CAP_SYS_NICE)); |
4358 | } | 4369 | } |
4359 | 4370 | ||
@@ -4530,7 +4541,7 @@ recheck: | |||
4530 | 4541 | ||
4531 | if (!lock_task_sighand(p, &flags)) | 4542 | if (!lock_task_sighand(p, &flags)) |
4532 | return -ESRCH; | 4543 | return -ESRCH; |
4533 | rlim_rtprio = p->signal->rlim[RLIMIT_RTPRIO].rlim_cur; | 4544 | rlim_rtprio = task_rlimit(p, RLIMIT_RTPRIO); |
4534 | unlock_task_sighand(p, &flags); | 4545 | unlock_task_sighand(p, &flags); |
4535 | 4546 | ||
4536 | /* can't set/change the rt policy */ | 4547 | /* can't set/change the rt policy */ |
@@ -4902,7 +4913,9 @@ SYSCALL_DEFINE3(sched_getaffinity, pid_t, pid, unsigned int, len, | |||
4902 | int ret; | 4913 | int ret; |
4903 | cpumask_var_t mask; | 4914 | cpumask_var_t mask; |
4904 | 4915 | ||
4905 | if (len < cpumask_size()) | 4916 | if ((len * BITS_PER_BYTE) < nr_cpu_ids) |
4917 | return -EINVAL; | ||
4918 | if (len & (sizeof(unsigned long)-1)) | ||
4906 | return -EINVAL; | 4919 | return -EINVAL; |
4907 | 4920 | ||
4908 | if (!alloc_cpumask_var(&mask, GFP_KERNEL)) | 4921 | if (!alloc_cpumask_var(&mask, GFP_KERNEL)) |
@@ -4910,10 +4923,12 @@ SYSCALL_DEFINE3(sched_getaffinity, pid_t, pid, unsigned int, len, | |||
4910 | 4923 | ||
4911 | ret = sched_getaffinity(pid, mask); | 4924 | ret = sched_getaffinity(pid, mask); |
4912 | if (ret == 0) { | 4925 | if (ret == 0) { |
4913 | if (copy_to_user(user_mask_ptr, mask, cpumask_size())) | 4926 | size_t retlen = min_t(size_t, len, cpumask_size()); |
4927 | |||
4928 | if (copy_to_user(user_mask_ptr, mask, retlen)) | ||
4914 | ret = -EFAULT; | 4929 | ret = -EFAULT; |
4915 | else | 4930 | else |
4916 | ret = cpumask_size(); | 4931 | ret = retlen; |
4917 | } | 4932 | } |
4918 | free_cpumask_var(mask); | 4933 | free_cpumask_var(mask); |
4919 | 4934 | ||
@@ -5383,7 +5398,7 @@ int set_cpus_allowed_ptr(struct task_struct *p, const struct cpumask *new_mask) | |||
5383 | 5398 | ||
5384 | get_task_struct(mt); | 5399 | get_task_struct(mt); |
5385 | task_rq_unlock(rq, &flags); | 5400 | task_rq_unlock(rq, &flags); |
5386 | wake_up_process(rq->migration_thread); | 5401 | wake_up_process(mt); |
5387 | put_task_struct(mt); | 5402 | put_task_struct(mt); |
5388 | wait_for_completion(&req.done); | 5403 | wait_for_completion(&req.done); |
5389 | tlb_migrate_finish(p->mm); | 5404 | tlb_migrate_finish(p->mm); |
@@ -7406,11 +7421,13 @@ static ssize_t sched_power_savings_store(const char *buf, size_t count, int smt) | |||
7406 | 7421 | ||
7407 | #ifdef CONFIG_SCHED_MC | 7422 | #ifdef CONFIG_SCHED_MC |
7408 | static ssize_t sched_mc_power_savings_show(struct sysdev_class *class, | 7423 | static ssize_t sched_mc_power_savings_show(struct sysdev_class *class, |
7424 | struct sysdev_class_attribute *attr, | ||
7409 | char *page) | 7425 | char *page) |
7410 | { | 7426 | { |
7411 | return sprintf(page, "%u\n", sched_mc_power_savings); | 7427 | return sprintf(page, "%u\n", sched_mc_power_savings); |
7412 | } | 7428 | } |
7413 | static ssize_t sched_mc_power_savings_store(struct sysdev_class *class, | 7429 | static ssize_t sched_mc_power_savings_store(struct sysdev_class *class, |
7430 | struct sysdev_class_attribute *attr, | ||
7414 | const char *buf, size_t count) | 7431 | const char *buf, size_t count) |
7415 | { | 7432 | { |
7416 | return sched_power_savings_store(buf, count, 0); | 7433 | return sched_power_savings_store(buf, count, 0); |
@@ -7422,11 +7439,13 @@ static SYSDEV_CLASS_ATTR(sched_mc_power_savings, 0644, | |||
7422 | 7439 | ||
7423 | #ifdef CONFIG_SCHED_SMT | 7440 | #ifdef CONFIG_SCHED_SMT |
7424 | static ssize_t sched_smt_power_savings_show(struct sysdev_class *dev, | 7441 | static ssize_t sched_smt_power_savings_show(struct sysdev_class *dev, |
7442 | struct sysdev_class_attribute *attr, | ||
7425 | char *page) | 7443 | char *page) |
7426 | { | 7444 | { |
7427 | return sprintf(page, "%u\n", sched_smt_power_savings); | 7445 | return sprintf(page, "%u\n", sched_smt_power_savings); |
7428 | } | 7446 | } |
7429 | static ssize_t sched_smt_power_savings_store(struct sysdev_class *dev, | 7447 | static ssize_t sched_smt_power_savings_store(struct sysdev_class *dev, |
7448 | struct sysdev_class_attribute *attr, | ||
7430 | const char *buf, size_t count) | 7449 | const char *buf, size_t count) |
7431 | { | 7450 | { |
7432 | return sched_power_savings_store(buf, count, 1); | 7451 | return sched_power_savings_store(buf, count, 1); |
@@ -8813,7 +8832,7 @@ struct cgroup_subsys cpu_cgroup_subsys = { | |||
8813 | struct cpuacct { | 8832 | struct cpuacct { |
8814 | struct cgroup_subsys_state css; | 8833 | struct cgroup_subsys_state css; |
8815 | /* cpuusage holds pointer to a u64-type object on every cpu */ | 8834 | /* cpuusage holds pointer to a u64-type object on every cpu */ |
8816 | u64 *cpuusage; | 8835 | u64 __percpu *cpuusage; |
8817 | struct percpu_counter cpustat[CPUACCT_STAT_NSTATS]; | 8836 | struct percpu_counter cpustat[CPUACCT_STAT_NSTATS]; |
8818 | struct cpuacct *parent; | 8837 | struct cpuacct *parent; |
8819 | }; | 8838 | }; |