The sched_setattr() syscall mandates that a policy is always specified.
This requires to always know which policy a task will have when
attributes are configured and this makes it impossible to add more
generic task attributes valid across different scheduling policies.
Reading the policy before setting generic tasks attributes is racy since
we cannot be sure it is not changed concurrently.

Introduce the required support to change generic task attributes without
affecting the current task policy. This is done by adding an attribute flag
(SCHED_FLAG_KEEP_POLICY) to enforce the usage of the current policy.

Add support for the SETPARAM_POLICY policy, which is already used by the
sched_setparam() POSIX syscall, to the sched_setattr() non-POSIX
syscall.

Signed-off-by: Patrick Bellasi <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Peter Zijlstra <[email protected]>

---
Changes in v9:
 Message-ID: <20190509145901.um7rrsslg7de4blf@e110439-lin>
 - get rid of not necessary SCHED_POLICY_MAX define
 - update sched_setattr() syscall to just force the current policy on
   SCHED_FLAG_KEEP_POLICY
---
 include/uapi/linux/sched.h | 4 +++-
 kernel/sched/core.c        | 2 ++
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/include/uapi/linux/sched.h b/include/uapi/linux/sched.h
index 22627f80063e..261b6e43846c 100644
--- a/include/uapi/linux/sched.h
+++ b/include/uapi/linux/sched.h
@@ -50,9 +50,11 @@
 #define SCHED_FLAG_RESET_ON_FORK       0x01
 #define SCHED_FLAG_RECLAIM             0x02
 #define SCHED_FLAG_DL_OVERRUN          0x04
+#define SCHED_FLAG_KEEP_POLICY         0x08
 
 #define SCHED_FLAG_ALL (SCHED_FLAG_RESET_ON_FORK       | \
                         SCHED_FLAG_RECLAIM             | \
-                        SCHED_FLAG_DL_OVERRUN)
+                        SCHED_FLAG_DL_OVERRUN          | \
+                        SCHED_FLAG_KEEP_POLICY)
 
 #endif /* _UAPI_LINUX_SCHED_H */
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index dac73a5959b6..43b29b2efa4c 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -4863,6 +4863,8 @@ SYSCALL_DEFINE3(sched_setattr, pid_t, pid, struct 
sched_attr __user *, uattr,
 
        if ((int)attr.sched_policy < 0)
                return -EINVAL;
+       if (attr.sched_flags & SCHED_FLAG_KEEP_POLICY)
+               attr.sched_policy = SETPARAM_POLICY;
 
        rcu_read_lock();
        retval = -ESRCH;
-- 
2.21.0

Reply via email to