diff options
Diffstat (limited to 'kernel/sched.c')
-rw-r--r-- | kernel/sched.c | 48 |
1 files changed, 36 insertions, 12 deletions
diff --git a/kernel/sched.c b/kernel/sched.c index c74b0d23c752..2317a2178104 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -4995,16 +4995,8 @@ __setscheduler(struct rq *rq, struct task_struct *p, int policy, int prio) | |||
4995 | set_load_weight(p); | 4995 | set_load_weight(p); |
4996 | } | 4996 | } |
4997 | 4997 | ||
4998 | /** | 4998 | static int __sched_setscheduler(struct task_struct *p, int policy, |
4999 | * sched_setscheduler - change the scheduling policy and/or RT priority of a thread. | 4999 | struct sched_param *param, bool user) |
5000 | * @p: the task in question. | ||
5001 | * @policy: new policy. | ||
5002 | * @param: structure containing the new RT priority. | ||
5003 | * | ||
5004 | * NOTE that the task may be already dead. | ||
5005 | */ | ||
5006 | int sched_setscheduler(struct task_struct *p, int policy, | ||
5007 | struct sched_param *param) | ||
5008 | { | 5000 | { |
5009 | int retval, oldprio, oldpolicy = -1, on_rq, running; | 5001 | int retval, oldprio, oldpolicy = -1, on_rq, running; |
5010 | unsigned long flags; | 5002 | unsigned long flags; |
@@ -5036,7 +5028,7 @@ recheck: | |||
5036 | /* | 5028 | /* |
5037 | * Allow unprivileged RT tasks to decrease priority: | 5029 | * Allow unprivileged RT tasks to decrease priority: |
5038 | */ | 5030 | */ |
5039 | if (!capable(CAP_SYS_NICE)) { | 5031 | if (user && !capable(CAP_SYS_NICE)) { |
5040 | if (rt_policy(policy)) { | 5032 | if (rt_policy(policy)) { |
5041 | unsigned long rlim_rtprio; | 5033 | unsigned long rlim_rtprio; |
5042 | 5034 | ||
@@ -5072,7 +5064,8 @@ recheck: | |||
5072 | * Do not allow realtime tasks into groups that have no runtime | 5064 | * Do not allow realtime tasks into groups that have no runtime |
5073 | * assigned. | 5065 | * assigned. |
5074 | */ | 5066 | */ |
5075 | if (rt_policy(policy) && task_group(p)->rt_bandwidth.rt_runtime == 0) | 5067 | if (user |
5068 | && rt_policy(policy) && task_group(p)->rt_bandwidth.rt_runtime == 0) | ||
5076 | return -EPERM; | 5069 | return -EPERM; |
5077 | #endif | 5070 | #endif |
5078 | 5071 | ||
@@ -5121,8 +5114,39 @@ recheck: | |||
5121 | 5114 | ||
5122 | return 0; | 5115 | return 0; |
5123 | } | 5116 | } |
5117 | |||
5118 | /** | ||
5119 | * sched_setscheduler - change the scheduling policy and/or RT priority of a thread. | ||
5120 | * @p: the task in question. | ||
5121 | * @policy: new policy. | ||
5122 | * @param: structure containing the new RT priority. | ||
5123 | * | ||
5124 | * NOTE that the task may be already dead. | ||
5125 | */ | ||
5126 | int sched_setscheduler(struct task_struct *p, int policy, | ||
5127 | struct sched_param *param) | ||
5128 | { | ||
5129 | return __sched_setscheduler(p, policy, param, true); | ||
5130 | } | ||
5124 | EXPORT_SYMBOL_GPL(sched_setscheduler); | 5131 | EXPORT_SYMBOL_GPL(sched_setscheduler); |
5125 | 5132 | ||
5133 | /** | ||
5134 | * sched_setscheduler_nocheck - change the scheduling policy and/or RT priority of a thread from kernelspace. | ||
5135 | * @p: the task in question. | ||
5136 | * @policy: new policy. | ||
5137 | * @param: structure containing the new RT priority. | ||
5138 | * | ||
5139 | * Just like sched_setscheduler, only don't bother checking if the | ||
5140 | * current context has permission. For example, this is needed in | ||
5141 | * stop_machine(): we create temporary high priority worker threads, | ||
5142 | * but our caller might not have that capability. | ||
5143 | */ | ||
5144 | int sched_setscheduler_nocheck(struct task_struct *p, int policy, | ||
5145 | struct sched_param *param) | ||
5146 | { | ||
5147 | return __sched_setscheduler(p, policy, param, false); | ||
5148 | } | ||
5149 | |||
5126 | static int | 5150 | static int |
5127 | do_sched_setscheduler(pid_t pid, int policy, struct sched_param __user *param) | 5151 | do_sched_setscheduler(pid_t pid, int policy, struct sched_param __user *param) |
5128 | { | 5152 | { |