aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/uapi/linux/sched.h5
-rw-r--r--kernel/sched/core.c42
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
3448static 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:
3456int sched_setscheduler(struct task_struct *p, int policy, 3478int 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}
3466EXPORT_SYMBOL_GPL(sched_setscheduler); 3483EXPORT_SYMBOL_GPL(sched_setscheduler);
3467 3484
@@ -3487,12 +3504,7 @@ EXPORT_SYMBOL_GPL(sched_setattr);
3487int sched_setscheduler_nocheck(struct task_struct *p, int policy, 3504int 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
3498static int 3510static 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))