diff options
Diffstat (limited to 'kernel/sched/core.c')
-rw-r--r-- | kernel/sched/core.c | 55 |
1 files changed, 39 insertions, 16 deletions
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 204d3d281809..0a7251678982 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c | |||
@@ -3195,17 +3195,40 @@ __getparam_dl(struct task_struct *p, struct sched_attr *attr) | |||
3195 | * We ask for the deadline not being zero, and greater or equal | 3195 | * We ask for the deadline not being zero, and greater or equal |
3196 | * than the runtime, as well as the period of being zero or | 3196 | * than the runtime, as well as the period of being zero or |
3197 | * greater than deadline. Furthermore, we have to be sure that | 3197 | * greater than deadline. Furthermore, we have to be sure that |
3198 | * user parameters are above the internal resolution (1us); we | 3198 | * user parameters are above the internal resolution of 1us (we |
3199 | * check sched_runtime only since it is always the smaller one. | 3199 | * check sched_runtime only since it is always the smaller one) and |
3200 | * below 2^63 ns (we have to check both sched_deadline and | ||
3201 | * sched_period, as the latter can be zero). | ||
3200 | */ | 3202 | */ |
3201 | static bool | 3203 | static bool |
3202 | __checkparam_dl(const struct sched_attr *attr) | 3204 | __checkparam_dl(const struct sched_attr *attr) |
3203 | { | 3205 | { |
3204 | return attr && attr->sched_deadline != 0 && | 3206 | /* deadline != 0 */ |
3205 | (attr->sched_period == 0 || | 3207 | if (attr->sched_deadline == 0) |
3206 | (s64)(attr->sched_period - attr->sched_deadline) >= 0) && | 3208 | return false; |
3207 | (s64)(attr->sched_deadline - attr->sched_runtime ) >= 0 && | 3209 | |
3208 | attr->sched_runtime >= (2 << (DL_SCALE - 1)); | 3210 | /* |
3211 | * Since we truncate DL_SCALE bits, make sure we're at least | ||
3212 | * that big. | ||
3213 | */ | ||
3214 | if (attr->sched_runtime < (1ULL << DL_SCALE)) | ||
3215 | return false; | ||
3216 | |||
3217 | /* | ||
3218 | * Since we use the MSB for wrap-around and sign issues, make | ||
3219 | * sure it's not set (mind that period can be equal to zero). | ||
3220 | */ | ||
3221 | if (attr->sched_deadline & (1ULL << 63) || | ||
3222 | attr->sched_period & (1ULL << 63)) | ||
3223 | return false; | ||
3224 | |||
3225 | /* runtime <= deadline <= period (if period != 0) */ | ||
3226 | if ((attr->sched_period != 0 && | ||
3227 | attr->sched_period < attr->sched_deadline) || | ||
3228 | attr->sched_deadline < attr->sched_runtime) | ||
3229 | return false; | ||
3230 | |||
3231 | return true; | ||
3209 | } | 3232 | } |
3210 | 3233 | ||
3211 | /* | 3234 | /* |
@@ -3658,8 +3681,12 @@ SYSCALL_DEFINE3(sched_setattr, pid_t, pid, struct sched_attr __user *, uattr, | |||
3658 | if (!uattr || pid < 0 || flags) | 3681 | if (!uattr || pid < 0 || flags) |
3659 | return -EINVAL; | 3682 | return -EINVAL; |
3660 | 3683 | ||
3661 | if (sched_copy_attr(uattr, &attr)) | 3684 | retval = sched_copy_attr(uattr, &attr); |
3662 | return -EFAULT; | 3685 | if (retval) |
3686 | return retval; | ||
3687 | |||
3688 | if (attr.sched_policy < 0) | ||
3689 | return -EINVAL; | ||
3663 | 3690 | ||
3664 | rcu_read_lock(); | 3691 | rcu_read_lock(); |
3665 | retval = -ESRCH; | 3692 | retval = -ESRCH; |
@@ -3709,7 +3736,7 @@ SYSCALL_DEFINE1(sched_getscheduler, pid_t, pid) | |||
3709 | */ | 3736 | */ |
3710 | SYSCALL_DEFINE2(sched_getparam, pid_t, pid, struct sched_param __user *, param) | 3737 | SYSCALL_DEFINE2(sched_getparam, pid_t, pid, struct sched_param __user *, param) |
3711 | { | 3738 | { |
3712 | struct sched_param lp; | 3739 | struct sched_param lp = { .sched_priority = 0 }; |
3713 | struct task_struct *p; | 3740 | struct task_struct *p; |
3714 | int retval; | 3741 | int retval; |
3715 | 3742 | ||
@@ -3726,11 +3753,8 @@ SYSCALL_DEFINE2(sched_getparam, pid_t, pid, struct sched_param __user *, param) | |||
3726 | if (retval) | 3753 | if (retval) |
3727 | goto out_unlock; | 3754 | goto out_unlock; |
3728 | 3755 | ||
3729 | if (task_has_dl_policy(p)) { | 3756 | if (task_has_rt_policy(p)) |
3730 | retval = -EINVAL; | 3757 | lp.sched_priority = p->rt_priority; |
3731 | goto out_unlock; | ||
3732 | } | ||
3733 | lp.sched_priority = p->rt_priority; | ||
3734 | rcu_read_unlock(); | 3758 | rcu_read_unlock(); |
3735 | 3759 | ||
3736 | /* | 3760 | /* |
@@ -5052,7 +5076,6 @@ static int sched_cpu_active(struct notifier_block *nfb, | |||
5052 | unsigned long action, void *hcpu) | 5076 | unsigned long action, void *hcpu) |
5053 | { | 5077 | { |
5054 | switch (action & ~CPU_TASKS_FROZEN) { | 5078 | switch (action & ~CPU_TASKS_FROZEN) { |
5055 | case CPU_STARTING: | ||
5056 | case CPU_DOWN_FAILED: | 5079 | case CPU_DOWN_FAILED: |
5057 | set_cpu_active((long)hcpu, true); | 5080 | set_cpu_active((long)hcpu, true); |
5058 | return NOTIFY_OK; | 5081 | return NOTIFY_OK; |