There's a valid ->pi_lock recursion issue where the actual PI code tries to wake up the stop task. Make lockdep aware so it doesn't complain about this.
Unified · Split
| @@ -2658,6 +2658,7 @@ int select_task_rq(struct task_struct *p, int cpu, int sd_flags, int wake_flags) · 2657 unmodified lines | |||
| 2658 | 2658 | ||
| 2659 | void sched_set_stop_task(int cpu, struct task_struct *stop) | 2659 | void sched_set_stop_task(int cpu, struct task_struct *stop) |
| 2660 | { | 2660 | { |
| 2661 | static struct lock_class_key stop_pi_lock; | ||
| 2661 | struct sched_param param = { .sched_priority = MAX_RT_PRIO - 1 }; | 2662 | struct sched_param param = { .sched_priority = MAX_RT_PRIO - 1 }; |
| 2662 | struct task_struct *old_stop = cpu_rq(cpu)->stop; | 2663 | struct task_struct *old_stop = cpu_rq(cpu)->stop; |
| 2663 | 2664 | ||
| @@ -2673,6 +2674,20 @@ void sched_set_stop_task(int cpu, struct task_struct *stop) · 9 unmodified lines | |||
| 2673 | sched_setscheduler_nocheck(stop, SCHED_FIFO, ¶m); | 2674 | sched_setscheduler_nocheck(stop, SCHED_FIFO, ¶m); |
| 2674 | 2675 | ||
| 2675 | stop->sched_class = &stop_sched_class; | 2676 | stop->sched_class = &stop_sched_class; |
| 2677 | |||
| 2678 | /* | ||
| 2679 | * The PI code calls rt_mutex_setprio() with ->pi_lock held to | ||
| 2680 | * adjust the effective priority of a task. As a result, | ||
| 2681 | * rt_mutex_setprio() can trigger (RT) balancing operations, | ||
| 2682 | * which can then trigger wakeups of the stop thread to push | ||
| 2683 | * around the current task. | ||
| 2684 | * | ||
| 2685 | * The stop task itself will never be part of the PI-chain, it | ||
| 2686 | * never blocks, therefore that ->pi_lock recursion is safe. | ||
| 2687 | * Tell lockdep about this by placing the stop->pi_lock in its | ||
| 2688 | * own class. | ||
| 2689 | */ | ||
| 2690 | lockdep_set_class(&stop->pi_lock, &stop_pi_lock); | ||
| 2676 | } | 2691 | } |
| 2677 | 2692 | ||
| 2678 | cpu_rq(cpu)->stop = stop; | 2693 | cpu_rq(cpu)->stop = stop; |