diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/fork.c | 1 | ||||
| -rw-r--r-- | kernel/locking/rtmutex.c | 29 | ||||
| -rw-r--r-- | kernel/sched/core.c | 2 |
3 files changed, 24 insertions, 8 deletions
diff --git a/kernel/fork.c b/kernel/fork.c index 6c463c80e93d..b30196a00b0d 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
| @@ -1438,6 +1438,7 @@ static void rt_mutex_init_task(struct task_struct *p) | |||
| 1438 | #ifdef CONFIG_RT_MUTEXES | 1438 | #ifdef CONFIG_RT_MUTEXES |
| 1439 | p->pi_waiters = RB_ROOT; | 1439 | p->pi_waiters = RB_ROOT; |
| 1440 | p->pi_waiters_leftmost = NULL; | 1440 | p->pi_waiters_leftmost = NULL; |
| 1441 | p->pi_top_task = NULL; | ||
| 1441 | p->pi_blocked_on = NULL; | 1442 | p->pi_blocked_on = NULL; |
| 1442 | #endif | 1443 | #endif |
| 1443 | } | 1444 | } |
diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c index 71ecf0624410..bc05b104eaed 100644 --- a/kernel/locking/rtmutex.c +++ b/kernel/locking/rtmutex.c | |||
| @@ -323,6 +323,19 @@ rt_mutex_dequeue_pi(struct task_struct *task, struct rt_mutex_waiter *waiter) | |||
| 323 | } | 323 | } |
| 324 | 324 | ||
| 325 | /* | 325 | /* |
| 326 | * Must hold both p->pi_lock and task_rq(p)->lock. | ||
| 327 | */ | ||
| 328 | void rt_mutex_update_top_task(struct task_struct *p) | ||
| 329 | { | ||
| 330 | if (!task_has_pi_waiters(p)) { | ||
| 331 | p->pi_top_task = NULL; | ||
| 332 | return; | ||
| 333 | } | ||
| 334 | |||
| 335 | p->pi_top_task = task_top_pi_waiter(p)->task; | ||
| 336 | } | ||
| 337 | |||
| 338 | /* | ||
| 326 | * Calculate task priority from the waiter tree priority | 339 | * Calculate task priority from the waiter tree priority |
| 327 | * | 340 | * |
| 328 | * Return task->normal_prio when the waiter tree is empty or when | 341 | * Return task->normal_prio when the waiter tree is empty or when |
| @@ -337,12 +350,12 @@ int rt_mutex_getprio(struct task_struct *task) | |||
| 337 | task->normal_prio); | 350 | task->normal_prio); |
| 338 | } | 351 | } |
| 339 | 352 | ||
| 353 | /* | ||
| 354 | * Must hold either p->pi_lock or task_rq(p)->lock. | ||
| 355 | */ | ||
| 340 | struct task_struct *rt_mutex_get_top_task(struct task_struct *task) | 356 | struct task_struct *rt_mutex_get_top_task(struct task_struct *task) |
| 341 | { | 357 | { |
| 342 | if (likely(!task_has_pi_waiters(task))) | 358 | return task->pi_top_task; |
| 343 | return NULL; | ||
| 344 | |||
| 345 | return task_top_pi_waiter(task)->task; | ||
| 346 | } | 359 | } |
| 347 | 360 | ||
| 348 | /* | 361 | /* |
| @@ -351,12 +364,12 @@ struct task_struct *rt_mutex_get_top_task(struct task_struct *task) | |||
| 351 | */ | 364 | */ |
| 352 | int rt_mutex_get_effective_prio(struct task_struct *task, int newprio) | 365 | int rt_mutex_get_effective_prio(struct task_struct *task, int newprio) |
| 353 | { | 366 | { |
| 354 | if (!task_has_pi_waiters(task)) | 367 | struct task_struct *top_task = rt_mutex_get_top_task(task); |
| 368 | |||
| 369 | if (!top_task) | ||
| 355 | return newprio; | 370 | return newprio; |
| 356 | 371 | ||
| 357 | if (task_top_pi_waiter(task)->task->prio <= newprio) | 372 | return min(top_task->prio, newprio); |
| 358 | return task_top_pi_waiter(task)->task->prio; | ||
| 359 | return newprio; | ||
| 360 | } | 373 | } |
| 361 | 374 | ||
| 362 | /* | 375 | /* |
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index ab9f6ac099a7..e1f44ec701c8 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c | |||
| @@ -3713,6 +3713,8 @@ void rt_mutex_setprio(struct task_struct *p, int prio) | |||
| 3713 | goto out_unlock; | 3713 | goto out_unlock; |
| 3714 | } | 3714 | } |
| 3715 | 3715 | ||
| 3716 | rt_mutex_update_top_task(p); | ||
| 3717 | |||
| 3716 | trace_sched_pi_setprio(p, prio); | 3718 | trace_sched_pi_setprio(p, prio); |
| 3717 | oldprio = p->prio; | 3719 | oldprio = p->prio; |
| 3718 | 3720 | ||
