Commit-ID:  7479f3c9cf67edf5e8a76b21ea3726757f35cf53
Gitweb:     http://git.kernel.org/tip/7479f3c9cf67edf5e8a76b21ea3726757f35cf53
Author:     Peter Zijlstra <pet...@infradead.org>
AuthorDate: Wed, 15 Jan 2014 17:05:04 +0100
Committer:  Ingo Molnar <mi...@kernel.org>
CommitDate: Thu, 16 Jan 2014 09:27:17 +0100

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 <pet...@infradead.org>
Cc: Juri Lelli <juri.le...@gmail.com>
Cc: Dario Faggioli <raist...@linux.it>
Link: 
http://lkml.kernel.org/r/20140115162242.gj31...@twins.programming.kicks-ass.net
Signed-off-by: Ingo Molnar <mi...@kernel.org>
---
 include/uapi/linux/sched.h |  5 +++++
 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 2d5e49a..34f9d73 100644
--- a/include/uapi/linux/sched.h
+++ b/include/uapi/linux/sched.h
@@ -40,8 +40,13 @@
 /* SCHED_ISO: reserved but not implemented yet */
 #define SCHED_IDLE             5
 #define SCHED_DEADLINE         6
+
 /* Can be ORed in to make sure the process is reverted back to SCHED_NORMAL on 
fork */
 #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 */
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 5a6ccdf..93a2836 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -3267,8 +3267,7 @@ recheck:
                reset_on_fork = p->sched_reset_on_fork;
                policy = oldpolicy = p->policy;
        } else {
-               reset_on_fork = !!(policy & SCHED_RESET_ON_FORK);
-               policy &= ~SCHED_RESET_ON_FORK;
+               reset_on_fork = !!(attr->sched_flags & 
SCHED_FLAG_RESET_ON_FORK);
 
                if (policy != SCHED_DEADLINE &&
                                policy != SCHED_FIFO && policy != SCHED_RR &&
@@ -3277,6 +3276,9 @@ recheck:
                        return -EINVAL;
        }
 
+       if (attr->sched_flags & ~(SCHED_FLAG_RESET_ON_FORK))
+               return -EINVAL;
+
        /*
         * Valid priorities for SCHED_FIFO and SCHED_RR are
         * 1..MAX_USER_RT_PRIO-1, valid priority for SCHED_NORMAL,
@@ -3443,6 +3445,26 @@ change:
        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.
  * @p: the task in question.
@@ -3456,12 +3478,7 @@ change:
 int sched_setscheduler(struct task_struct *p, int policy,
                       const struct sched_param *param)
 {
-       struct sched_attr attr = {
-               .sched_policy   = policy,
-               .sched_priority = param->sched_priority,
-               .sched_nice     = PRIO_TO_NICE(p->static_prio),
-       };
-       return __sched_setscheduler(p, &attr, true);
+       return _sched_setscheduler(p, policy, param, true);
 }
 EXPORT_SYMBOL_GPL(sched_setscheduler);
 
@@ -3487,12 +3504,7 @@ EXPORT_SYMBOL_GPL(sched_setattr);
 int sched_setscheduler_nocheck(struct task_struct *p, int policy,
                               const struct sched_param *param)
 {
-       struct sched_attr attr = {
-               .sched_policy   = policy,
-               .sched_priority = param->sched_priority,
-               .sched_nice     = PRIO_TO_NICE(p->static_prio),
-       };
-       return __sched_setscheduler(p, &attr, false);
+       return _sched_setscheduler(p, policy, param, false);
 }
 
 static int
@@ -3792,6 +3804,8 @@ SYSCALL_DEFINE3(sched_getattr, pid_t, pid, struct 
sched_attr __user *, uattr,
                goto out_unlock;
 
        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))
                __getparam_dl(p, &attr);
        else if (task_has_rt_policy(p))
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to