|
@@ -2902,7 +2902,8 @@ EXPORT_SYMBOL(sleep_on_timeout);
|
|
|
* This function changes the 'effective' priority of a task. It does
|
|
|
* not touch ->normal_prio like __setscheduler().
|
|
|
*
|
|
|
- * Used by the rt_mutex code to implement priority inheritance logic.
|
|
|
+ * Used by the rt_mutex code to implement priority inheritance
|
|
|
+ * logic. Call site only calls if the priority of the task changed.
|
|
|
*/
|
|
|
void rt_mutex_setprio(struct task_struct *p, int prio)
|
|
|
{
|
|
@@ -3171,9 +3172,8 @@ __setparam_dl(struct task_struct *p, const struct sched_attr *attr)
|
|
|
dl_se->dl_new = 1;
|
|
|
}
|
|
|
|
|
|
-/* Actually do priority change: must hold pi & rq lock. */
|
|
|
-static void __setscheduler(struct rq *rq, struct task_struct *p,
|
|
|
- const struct sched_attr *attr)
|
|
|
+static void __setscheduler_params(struct task_struct *p,
|
|
|
+ const struct sched_attr *attr)
|
|
|
{
|
|
|
int policy = attr->sched_policy;
|
|
|
|
|
@@ -3193,9 +3193,14 @@ static void __setscheduler(struct rq *rq, struct task_struct *p,
|
|
|
* getparam()/getattr() don't report silly values for !rt tasks.
|
|
|
*/
|
|
|
p->rt_priority = attr->sched_priority;
|
|
|
+ set_load_weight(p);
|
|
|
+}
|
|
|
|
|
|
- p->normal_prio = normal_prio(p);
|
|
|
- p->prio = rt_mutex_getprio(p);
|
|
|
+/* Actually do priority change: must hold pi & rq lock. */
|
|
|
+static void __setscheduler(struct rq *rq, struct task_struct *p,
|
|
|
+ const struct sched_attr *attr)
|
|
|
+{
|
|
|
+ __setscheduler_params(p, attr);
|
|
|
|
|
|
if (dl_prio(p->prio))
|
|
|
p->sched_class = &dl_sched_class;
|
|
@@ -3203,8 +3208,6 @@ static void __setscheduler(struct rq *rq, struct task_struct *p,
|
|
|
p->sched_class = &rt_sched_class;
|
|
|
else
|
|
|
p->sched_class = &fair_sched_class;
|
|
|
-
|
|
|
- set_load_weight(p);
|
|
|
}
|
|
|
|
|
|
static void
|
|
@@ -3257,6 +3260,7 @@ static int __sched_setscheduler(struct task_struct *p,
|
|
|
const struct sched_attr *attr,
|
|
|
bool user)
|
|
|
{
|
|
|
+ int newprio = MAX_RT_PRIO - 1 - attr->sched_priority;
|
|
|
int retval, oldprio, oldpolicy = -1, on_rq, running;
|
|
|
int policy = attr->sched_policy;
|
|
|
unsigned long flags;
|
|
@@ -3427,6 +3431,24 @@ change:
|
|
|
return -EBUSY;
|
|
|
}
|
|
|
|
|
|
+ p->sched_reset_on_fork = reset_on_fork;
|
|
|
+ oldprio = p->prio;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Special case for priority boosted tasks.
|
|
|
+ *
|
|
|
+ * If the new priority is lower or equal (user space view)
|
|
|
+ * than the current (boosted) priority, we just store the new
|
|
|
+ * normal parameters and do not touch the scheduler class and
|
|
|
+ * the runqueue. This will be done when the task deboost
|
|
|
+ * itself.
|
|
|
+ */
|
|
|
+ if (rt_mutex_check_prio(p, newprio)) {
|
|
|
+ __setscheduler_params(p, attr);
|
|
|
+ task_rq_unlock(rq, p, &flags);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
on_rq = p->on_rq;
|
|
|
running = task_current(rq, p);
|
|
|
if (on_rq)
|
|
@@ -3434,9 +3456,6 @@ change:
|
|
|
if (running)
|
|
|
p->sched_class->put_prev_task(rq, p);
|
|
|
|
|
|
- p->sched_reset_on_fork = reset_on_fork;
|
|
|
-
|
|
|
- oldprio = p->prio;
|
|
|
prev_class = p->sched_class;
|
|
|
__setscheduler(rq, p, attr);
|
|
|
|