diff options
-rw-r--r-- | include/uapi/linux/sched.h | 5 | ||||
-rw-r--r-- | kernel/sched/core.c | 42 |
2 files changed, 33 insertions, 14 deletions
diff --git a/include/uapi/linux/sched.h b/include/uapi/linux/sched.h index 2d5e49a2a6d2..34f9d7387d13 100644 --- a/include/uapi/linux/sched.h +++ b/include/uapi/linux/sched.h | |||
@@ -40,8 +40,13 @@ | |||
40 | /* SCHED_ISO: reserved but not implemented yet */ | 40 | /* SCHED_ISO: reserved but not implemented yet */ |
41 | #define SCHED_IDLE 5 | 41 | #define SCHED_IDLE 5 |
42 | #define SCHED_DEADLINE 6 | 42 | #define SCHED_DEADLINE 6 |
43 | |||
43 | /* Can be ORed in to make sure the process is reverted back to SCHED_NORMAL on fork */ | 44 | /* Can be ORed in to make sure the process is reverted back to SCHED_NORMAL on fork */ |
44 | #define SCHED_RESET_ON_FORK 0x40000000 | 45 | #define SCHED_RESET_ON_FORK 0x40000000 |
45 | 46 | ||
47 | /* | ||
48 | * For the sched_{set,get}attr() calls | ||
49 | */ | ||
50 | #define SCHED_FLAG_RESET_ON_FORK 0x01 | ||
46 | 51 | ||
47 | #endif /* _UAPI_LINUX_SCHED_H */ | 52 | #endif /* _UAPI_LINUX_SCHED_H */ |
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)) |