|
@@ -4746,16 +4746,8 @@ __setscheduler(struct rq *rq, struct task_struct *p, int policy, int prio)
|
|
|
set_load_weight(p);
|
|
|
}
|
|
|
|
|
|
-/**
|
|
|
- * sched_setscheduler - change the scheduling policy and/or RT priority of a thread.
|
|
|
- * @p: the task in question.
|
|
|
- * @policy: new policy.
|
|
|
- * @param: structure containing the new RT priority.
|
|
|
- *
|
|
|
- * NOTE that the task may be already dead.
|
|
|
- */
|
|
|
-int sched_setscheduler(struct task_struct *p, int policy,
|
|
|
- struct sched_param *param)
|
|
|
+static int __sched_setscheduler(struct task_struct *p, int policy,
|
|
|
+ struct sched_param *param, bool user)
|
|
|
{
|
|
|
int retval, oldprio, oldpolicy = -1, on_rq, running;
|
|
|
unsigned long flags;
|
|
@@ -4787,7 +4779,7 @@ recheck:
|
|
|
/*
|
|
|
* Allow unprivileged RT tasks to decrease priority:
|
|
|
*/
|
|
|
- if (!capable(CAP_SYS_NICE)) {
|
|
|
+ if (user && !capable(CAP_SYS_NICE)) {
|
|
|
if (rt_policy(policy)) {
|
|
|
unsigned long rlim_rtprio;
|
|
|
|
|
@@ -4823,7 +4815,8 @@ recheck:
|
|
|
* Do not allow realtime tasks into groups that have no runtime
|
|
|
* assigned.
|
|
|
*/
|
|
|
- if (rt_policy(policy) && task_group(p)->rt_bandwidth.rt_runtime == 0)
|
|
|
+ if (user
|
|
|
+ && rt_policy(policy) && task_group(p)->rt_bandwidth.rt_runtime == 0)
|
|
|
return -EPERM;
|
|
|
#endif
|
|
|
|
|
@@ -4872,8 +4865,39 @@ recheck:
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
+
|
|
|
+/**
|
|
|
+ * sched_setscheduler - change the scheduling policy and/or RT priority of a thread.
|
|
|
+ * @p: the task in question.
|
|
|
+ * @policy: new policy.
|
|
|
+ * @param: structure containing the new RT priority.
|
|
|
+ *
|
|
|
+ * NOTE that the task may be already dead.
|
|
|
+ */
|
|
|
+int sched_setscheduler(struct task_struct *p, int policy,
|
|
|
+ struct sched_param *param)
|
|
|
+{
|
|
|
+ return __sched_setscheduler(p, policy, param, true);
|
|
|
+}
|
|
|
EXPORT_SYMBOL_GPL(sched_setscheduler);
|
|
|
|
|
|
+/**
|
|
|
+ * sched_setscheduler_nocheck - change the scheduling policy and/or RT priority of a thread from kernelspace.
|
|
|
+ * @p: the task in question.
|
|
|
+ * @policy: new policy.
|
|
|
+ * @param: structure containing the new RT priority.
|
|
|
+ *
|
|
|
+ * Just like sched_setscheduler, only don't bother checking if the
|
|
|
+ * current context has permission. For example, this is needed in
|
|
|
+ * stop_machine(): we create temporary high priority worker threads,
|
|
|
+ * but our caller might not have that capability.
|
|
|
+ */
|
|
|
+int sched_setscheduler_nocheck(struct task_struct *p, int policy,
|
|
|
+ struct sched_param *param)
|
|
|
+{
|
|
|
+ return __sched_setscheduler(p, policy, param, false);
|
|
|
+}
|
|
|
+
|
|
|
static int
|
|
|
do_sched_setscheduler(pid_t pid, int policy, struct sched_param __user *param)
|
|
|
{
|