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>
This commit is contained in:
Peter Zijlstra 2014-01-15 17:05:04 +01:00 committed by Ingo Molnar
parent 0bb040a443
commit 7479f3c9cf
2 changed files with 33 additions and 14 deletions

View File

@ -40,8 +40,13 @@
/* SCHED_ISO: reserved but not implemented yet */ /* SCHED_ISO: reserved but not implemented yet */
#define SCHED_IDLE 5 #define SCHED_IDLE 5
#define SCHED_DEADLINE 6 #define SCHED_DEADLINE 6
/* Can be ORed in to make sure the process is reverted back to SCHED_NORMAL on fork */ /* Can be ORed in to make sure the process is reverted back to SCHED_NORMAL on fork */
#define SCHED_RESET_ON_FORK 0x40000000 #define SCHED_RESET_ON_FORK 0x40000000
/*
* For the sched_{set,get}attr() calls
*/
#define SCHED_FLAG_RESET_ON_FORK 0x01
#endif /* _UAPI_LINUX_SCHED_H */ #endif /* _UAPI_LINUX_SCHED_H */

View File

@ -3267,8 +3267,7 @@ recheck:
reset_on_fork = p->sched_reset_on_fork; reset_on_fork = p->sched_reset_on_fork;
policy = oldpolicy = p->policy; policy = oldpolicy = p->policy;
} else { } else {
reset_on_fork = !!(policy & SCHED_RESET_ON_FORK); reset_on_fork = !!(attr->sched_flags & SCHED_FLAG_RESET_ON_FORK);
policy &= ~SCHED_RESET_ON_FORK;
if (policy != SCHED_DEADLINE && if (policy != SCHED_DEADLINE &&
policy != SCHED_FIFO && policy != SCHED_RR && policy != SCHED_FIFO && policy != SCHED_RR &&
@ -3277,6 +3276,9 @@ recheck:
return -EINVAL; return -EINVAL;
} }
if (attr->sched_flags & ~(SCHED_FLAG_RESET_ON_FORK))
return -EINVAL;
/* /*
* Valid priorities for SCHED_FIFO and SCHED_RR are * Valid priorities for SCHED_FIFO and SCHED_RR are
* 1..MAX_USER_RT_PRIO-1, valid priority for SCHED_NORMAL, * 1..MAX_USER_RT_PRIO-1, valid priority for SCHED_NORMAL,
@ -3443,6 +3445,26 @@ change:
return 0; return 0;
} }
static int _sched_setscheduler(struct task_struct *p, int policy,
const struct sched_param *param, bool check)
{
struct sched_attr attr = {
.sched_policy = policy,
.sched_priority = param->sched_priority,
.sched_nice = PRIO_TO_NICE(p->static_prio),
};
/*
* Fixup the legacy SCHED_RESET_ON_FORK hack
*/
if (policy & SCHED_RESET_ON_FORK) {
attr.sched_flags |= SCHED_FLAG_RESET_ON_FORK;
policy &= ~SCHED_RESET_ON_FORK;
attr.sched_policy = policy;
}
return __sched_setscheduler(p, &attr, check);
}
/** /**
* sched_setscheduler - change the scheduling policy and/or RT priority of a thread. * sched_setscheduler - change the scheduling policy and/or RT priority of a thread.
* @p: the task in question. * @p: the task in question.
@ -3456,12 +3478,7 @@ change:
int sched_setscheduler(struct task_struct *p, int policy, int sched_setscheduler(struct task_struct *p, int policy,
const struct sched_param *param) const struct sched_param *param)
{ {
struct sched_attr attr = { return _sched_setscheduler(p, policy, param, true);
.sched_policy = policy,
.sched_priority = param->sched_priority,
.sched_nice = PRIO_TO_NICE(p->static_prio),
};
return __sched_setscheduler(p, &attr, true);
} }
EXPORT_SYMBOL_GPL(sched_setscheduler); EXPORT_SYMBOL_GPL(sched_setscheduler);
@ -3487,12 +3504,7 @@ EXPORT_SYMBOL_GPL(sched_setattr);
int sched_setscheduler_nocheck(struct task_struct *p, int policy, int sched_setscheduler_nocheck(struct task_struct *p, int policy,
const struct sched_param *param) const struct sched_param *param)
{ {
struct sched_attr attr = { return _sched_setscheduler(p, policy, param, false);
.sched_policy = policy,
.sched_priority = param->sched_priority,
.sched_nice = PRIO_TO_NICE(p->static_prio),
};
return __sched_setscheduler(p, &attr, false);
} }
static int static int
@ -3792,6 +3804,8 @@ SYSCALL_DEFINE3(sched_getattr, pid_t, pid, struct sched_attr __user *, uattr,
goto out_unlock; goto out_unlock;
attr.sched_policy = p->policy; attr.sched_policy = p->policy;
if (p->sched_reset_on_fork)
attr.sched_flags |= SCHED_FLAG_RESET_ON_FORK;
if (task_has_dl_policy(p)) if (task_has_dl_policy(p))
__getparam_dl(p, &attr); __getparam_dl(p, &attr);
else if (task_has_rt_policy(p)) else if (task_has_rt_policy(p))