aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sched.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sched.c')
-rw-r--r--kernel/sched.c54
1 files changed, 46 insertions, 8 deletions
diff --git a/kernel/sched.c b/kernel/sched.c
index 7c9098d186e6..168b2680ae27 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -2614,9 +2614,32 @@ void sched_fork(struct task_struct *p, int clone_flags)
2614 set_task_cpu(p, cpu); 2614 set_task_cpu(p, cpu);
2615 2615
2616 /* 2616 /*
2617 * Make sure we do not leak PI boosting priority to the child: 2617 * Make sure we do not leak PI boosting priority to the child.
2618 */ 2618 */
2619 p->prio = current->normal_prio; 2619 p->prio = current->normal_prio;
2620
2621 /*
2622 * Revert to default priority/policy on fork if requested.
2623 */
2624 if (unlikely(p->sched_reset_on_fork)) {
2625 if (p->policy == SCHED_FIFO || p->policy == SCHED_RR)
2626 p->policy = SCHED_NORMAL;
2627
2628 if (p->normal_prio < DEFAULT_PRIO)
2629 p->prio = DEFAULT_PRIO;
2630
2631 if (PRIO_TO_NICE(p->static_prio) < 0) {
2632 p->static_prio = NICE_TO_PRIO(0);
2633 set_load_weight(p);
2634 }
2635
2636 /*
2637 * We don't need the reset flag anymore after the fork. It has
2638 * fulfilled its duty:
2639 */
2640 p->sched_reset_on_fork = 0;
2641 }
2642
2620 if (!rt_prio(p->prio)) 2643 if (!rt_prio(p->prio))
2621 p->sched_class = &fair_sched_class; 2644 p->sched_class = &fair_sched_class;
2622 2645
@@ -6100,17 +6123,25 @@ static int __sched_setscheduler(struct task_struct *p, int policy,
6100 unsigned long flags; 6123 unsigned long flags;
6101 const struct sched_class *prev_class = p->sched_class; 6124 const struct sched_class *prev_class = p->sched_class;
6102 struct rq *rq; 6125 struct rq *rq;
6126 int reset_on_fork;
6103 6127
6104 /* may grab non-irq protected spin_locks */ 6128 /* may grab non-irq protected spin_locks */
6105 BUG_ON(in_interrupt()); 6129 BUG_ON(in_interrupt());
6106recheck: 6130recheck:
6107 /* double check policy once rq lock held */ 6131 /* double check policy once rq lock held */
6108 if (policy < 0) 6132 if (policy < 0) {
6133 reset_on_fork = p->sched_reset_on_fork;
6109 policy = oldpolicy = p->policy; 6134 policy = oldpolicy = p->policy;
6110 else if (policy != SCHED_FIFO && policy != SCHED_RR && 6135 } else {
6111 policy != SCHED_NORMAL && policy != SCHED_BATCH && 6136 reset_on_fork = !!(policy & SCHED_RESET_ON_FORK);
6112 policy != SCHED_IDLE) 6137 policy &= ~SCHED_RESET_ON_FORK;
6113 return -EINVAL; 6138
6139 if (policy != SCHED_FIFO && policy != SCHED_RR &&
6140 policy != SCHED_NORMAL && policy != SCHED_BATCH &&
6141 policy != SCHED_IDLE)
6142 return -EINVAL;
6143 }
6144
6114 /* 6145 /*
6115 * Valid priorities for SCHED_FIFO and SCHED_RR are 6146 * Valid priorities for SCHED_FIFO and SCHED_RR are
6116 * 1..MAX_USER_RT_PRIO-1, valid priority for SCHED_NORMAL, 6147 * 1..MAX_USER_RT_PRIO-1, valid priority for SCHED_NORMAL,
@@ -6154,6 +6185,10 @@ recheck:
6154 /* can't change other user's priorities */ 6185 /* can't change other user's priorities */
6155 if (!check_same_owner(p)) 6186 if (!check_same_owner(p))
6156 return -EPERM; 6187 return -EPERM;
6188
6189 /* Normal users shall not reset the sched_reset_on_fork flag */
6190 if (p->sched_reset_on_fork && !reset_on_fork)
6191 return -EPERM;
6157 } 6192 }
6158 6193
6159 if (user) { 6194 if (user) {
@@ -6197,6 +6232,8 @@ recheck:
6197 if (running) 6232 if (running)
6198 p->sched_class->put_prev_task(rq, p); 6233 p->sched_class->put_prev_task(rq, p);
6199 6234
6235 p->sched_reset_on_fork = reset_on_fork;
6236
6200 oldprio = p->prio; 6237 oldprio = p->prio;
6201 __setscheduler(rq, p, policy, param->sched_priority); 6238 __setscheduler(rq, p, policy, param->sched_priority);
6202 6239
@@ -6313,14 +6350,15 @@ SYSCALL_DEFINE1(sched_getscheduler, pid_t, pid)
6313 if (p) { 6350 if (p) {
6314 retval = security_task_getscheduler(p); 6351 retval = security_task_getscheduler(p);
6315 if (!retval) 6352 if (!retval)
6316 retval = p->policy; 6353 retval = p->policy
6354 | (p->sched_reset_on_fork ? SCHED_RESET_ON_FORK : 0);
6317 } 6355 }
6318 read_unlock(&tasklist_lock); 6356 read_unlock(&tasklist_lock);
6319 return retval; 6357 return retval;
6320} 6358}
6321 6359
6322/** 6360/**
6323 * sys_sched_getscheduler - get the RT priority of a thread 6361 * sys_sched_getparam - get the RT priority of a thread
6324 * @pid: the pid in question. 6362 * @pid: the pid in question.
6325 * @param: structure containing the RT priority. 6363 * @param: structure containing the RT priority.
6326 */ 6364 */