On Tue, 5 May 2015 18:08:01 +0200 (CEST)
Thomas Gleixner <t...@linutronix.de> wrote:

> Reported-by: Ronny Meeus <ronny.me...@gmail.com>
> Signed-off-by: Thomas Gleixner <t...@linutronix.de>
> ---
>  kernel/locking/rtmutex.c |   10 ++++++----
>  kernel/sched/core.c      |   11 +++++------
>  2 files changed, 11 insertions(+), 10 deletions(-)
> 
> Index: tip/kernel/locking/rtmutex.c
> ===================================================================
> --- tip.orig/kernel/locking/rtmutex.c
> +++ tip/kernel/locking/rtmutex.c
> @@ -265,15 +265,17 @@ struct task_struct *rt_mutex_get_top_tas
>  }
>  
>  /*
> - * Called by sched_setscheduler() to check whether the priority change
> - * is overruled by a possible priority boosting.
> + * Called by sched_setscheduler() to get the priority which will be
> + * effective after the change.
>   */
>  int rt_mutex_check_prio(struct task_struct *task, int newprio)
>  {
>       if (!task_has_pi_waiters(task))
> -             return 0;
> +             return newprio;
>  
> -     return task_top_pi_waiter(task)->task->prio <= newprio;
> +     if (task_top_pi_waiter(task)->task->prio <= newprio)
> +             return task_top_pi_waiter(task)->task->prio;
> +     return newprio;
>  }
>  
>  /*
> Index: tip/kernel/sched/core.c
> ===================================================================
> --- tip.orig/kernel/sched/core.c
> +++ tip/kernel/sched/core.c
> @@ -3414,7 +3414,7 @@ static int __sched_setscheduler(struct t
>       int newprio = dl_policy(attr->sched_policy) ? MAX_DL_PRIO - 1 :
>                     MAX_RT_PRIO - 1 - attr->sched_priority;
>       int retval, oldprio, oldpolicy = -1, queued, running;
> -     int policy = attr->sched_policy;
> +     int new_effective_prio, policy = attr->sched_policy;
>       unsigned long flags;
>       const struct sched_class *prev_class;
>       struct rq *rq;
> @@ -3596,15 +3596,14 @@ change:
>       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
> +      * Take priority boosted tasks into account. If the new
> +      * effective priority is unchanged, 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)) {
> +     new_effective_prio = rt_mutex_check_prio(p, newprio);
> +     if (new_effective_prio == oldprio) {

When I first heard of this problem, I started writing code to fix this
and came up with pretty much the exact same answer.

I got pulled onto other things so I never finished it, but one thing
that worried me about this fix is this:

        T1 - FIFO policy (prio = 10)
          lock(rtmutex);

        T2 (prio = 20)
          lock(rtmutex)
            boost T1 (prio = 20)

        TI (prio = 20)
          sys_sched_setscheduler(prio = 30)
          TI (prio = 30)

        T1 (prio = 30)
          sys_sched_setscheduler(SCHED_OTHER)
          new_effective_prio = 20, oldprio = 30

Before the code stopped at the rt_mutex_check_prio(), but now it
continues. Will having the policy change cause problems here?

-- Steve


>               __setscheduler_params(p, attr);
>               task_rq_unlock(rq, p, &flags);
>               return 0;

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to