diff options
author | Peter Zijlstra <peterz@infradead.org> | 2014-01-15 11:05:04 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2014-01-16 03:27:17 -0500 |
commit | 7479f3c9cf67edf5e8a76b21ea3726757f35cf53 (patch) | |
tree | 25dfe80eb86cdfbd73008e143b9ae9f68d44a96e /kernel/sched/core.c | |
parent | 0bb040a44381261c0729636abbe03caeedb7d72e (diff) |
sched: Move SCHED_RESET_ON_FORK into attr::sched_flags
I noticed the new sched_{set,get}attr() calls didn't properly deal
with the SCHED_RESET_ON_FORK hack.
Instead of propagating the flags in high bits nonsense use the brand
spanking new attr::sched_flags field.
Signed-off-by: Peter Zijlstra <peterz@infradead.org>
Cc: Juri Lelli <juri.lelli@gmail.com>
Cc: Dario Faggioli <raistlin@linux.it>
Link: http://lkml.kernel.org/r/20140115162242.GJ31570@twins.programming.kicks-ass.net
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'kernel/sched/core.c')
-rw-r--r-- | kernel/sched/core.c | 42 |
1 files changed, 28 insertions, 14 deletions
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 5a6ccdf4b39d..93a2836b6220 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c | |||
@@ -3267,8 +3267,7 @@ recheck: | |||
3267 | reset_on_fork = p->sched_reset_on_fork; | 3267 | reset_on_fork = p->sched_reset_on_fork; |
3268 | policy = oldpolicy = p->policy; | 3268 | policy = oldpolicy = p->policy; |
3269 | } else { | 3269 | } else { |
3270 | reset_on_fork = !!(policy & SCHED_RESET_ON_FORK); | 3270 | reset_on_fork = !!(attr->sched_flags & SCHED_FLAG_RESET_ON_FORK); |
3271 | policy &= ~SCHED_RESET_ON_FORK; | ||
3272 | 3271 | ||
3273 | if (policy != SCHED_DEADLINE && | 3272 | if (policy != SCHED_DEADLINE && |
3274 | policy != SCHED_FIFO && policy != SCHED_RR && | 3273 | policy != SCHED_FIFO && policy != SCHED_RR && |
@@ -3277,6 +3276,9 @@ recheck: | |||
3277 | return -EINVAL; | 3276 | return -EINVAL; |
3278 | } | 3277 | } |
3279 | 3278 | ||
3279 | if (attr->sched_flags & ~(SCHED_FLAG_RESET_ON_FORK)) | ||
3280 | return -EINVAL; | ||
3281 | |||
3280 | /* | 3282 | /* |
3281 | * Valid priorities for SCHED_FIFO and SCHED_RR are | 3283 | * Valid priorities for SCHED_FIFO and SCHED_RR are |
3282 | * 1..MAX_USER_RT_PRIO-1, valid priority for SCHED_NORMAL, | 3284 | * 1..MAX_USER_RT_PRIO-1, valid priority for SCHED_NORMAL, |
@@ -3443,6 +3445,26 @@ change: | |||
3443 | return 0; | 3445 | return 0; |
3444 | } | 3446 | } |
3445 | 3447 | ||
3448 | static int _sched_setscheduler(struct task_struct *p, int policy, | ||
3449 | const struct sched_param *param, bool check) | ||
3450 | { | ||
3451 | struct sched_attr attr = { | ||
3452 | .sched_policy = policy, | ||
3453 | .sched_priority = param->sched_priority, | ||
3454 | .sched_nice = PRIO_TO_NICE(p->static_prio), | ||
3455 | }; | ||
3456 | |||
3457 | /* | ||
3458 | * Fixup the legacy SCHED_RESET_ON_FORK hack | ||
3459 | */ | ||
3460 | if (policy & SCHED_RESET_ON_FORK) { | ||
3461 | attr.sched_flags |= SCHED_FLAG_RESET_ON_FORK; | ||
3462 | policy &= ~SCHED_RESET_ON_FORK; | ||
3463 | attr.sched_policy = policy; | ||
3464 | } | ||
3465 | |||
3466 | return __sched_setscheduler(p, &attr, check); | ||
3467 | } | ||
3446 | /** | 3468 | /** |
3447 | * sched_setscheduler - change the scheduling policy and/or RT priority of a thread. | 3469 | * sched_setscheduler - change the scheduling policy and/or RT priority of a thread. |
3448 | * @p: the task in question. | 3470 | * @p: the task in question. |
@@ -3456,12 +3478,7 @@ change: | |||
3456 | int sched_setscheduler(struct task_struct *p, int policy, | 3478 | int sched_setscheduler(struct task_struct *p, int policy, |
3457 | const struct sched_param *param) | 3479 | const struct sched_param *param) |
3458 | { | 3480 | { |
3459 | struct sched_attr attr = { | 3481 | return _sched_setscheduler(p, policy, param, true); |
3460 | .sched_policy = policy, | ||
3461 | .sched_priority = param->sched_priority, | ||
3462 | .sched_nice = PRIO_TO_NICE(p->static_prio), | ||
3463 | }; | ||
3464 | return __sched_setscheduler(p, &attr, true); | ||
3465 | } | 3482 | } |
3466 | EXPORT_SYMBOL_GPL(sched_setscheduler); | 3483 | EXPORT_SYMBOL_GPL(sched_setscheduler); |
3467 | 3484 | ||
@@ -3487,12 +3504,7 @@ EXPORT_SYMBOL_GPL(sched_setattr); | |||
3487 | int sched_setscheduler_nocheck(struct task_struct *p, int policy, | 3504 | int sched_setscheduler_nocheck(struct task_struct *p, int policy, |
3488 | const struct sched_param *param) | 3505 | const struct sched_param *param) |
3489 | { | 3506 | { |
3490 | struct sched_attr attr = { | 3507 | return _sched_setscheduler(p, policy, param, false); |
3491 | .sched_policy = policy, | ||
3492 | .sched_priority = param->sched_priority, | ||
3493 | .sched_nice = PRIO_TO_NICE(p->static_prio), | ||
3494 | }; | ||
3495 | return __sched_setscheduler(p, &attr, false); | ||
3496 | } | 3508 | } |
3497 | 3509 | ||
3498 | static int | 3510 | static int |
@@ -3792,6 +3804,8 @@ SYSCALL_DEFINE3(sched_getattr, pid_t, pid, struct sched_attr __user *, uattr, | |||
3792 | goto out_unlock; | 3804 | goto out_unlock; |
3793 | 3805 | ||
3794 | attr.sched_policy = p->policy; | 3806 | attr.sched_policy = p->policy; |
3807 | if (p->sched_reset_on_fork) | ||
3808 | attr.sched_flags |= SCHED_FLAG_RESET_ON_FORK; | ||
3795 | if (task_has_dl_policy(p)) | 3809 | if (task_has_dl_policy(p)) |
3796 | __getparam_dl(p, &attr); | 3810 | __getparam_dl(p, &attr); |
3797 | else if (task_has_rt_policy(p)) | 3811 | else if (task_has_rt_policy(p)) |