Pull debugobjects fix from Ingo Molnar: - Fix potential debugobjects deadlock on PREEMPT_RT kernels (Waiman Long) * tag 'core-urgent-2026-06-13' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: debugobjects: Don't call fill_pool() in early boot hardirq context
Showing the changes to lib/debugobjects.c (1 of 1 file). Show all
Unified · Split
| @@ -720,6 +720,41 @@ static inline bool debug_objects_is_pi_blocked_on(void) · 719 unmodified lines | ||
| 720 | 720 | #endif |
| 721 | 721 | } |
| 722 | 722 | |
| 723 | +static inline bool can_fill_pool(void) | |
| 724 | +{ | |
| 725 | + /* | |
| 726 | + * On !RT enabled kernels there are no restrictions and spinlock_t and | |
| 727 | + * raw_spinlock_t are the same types. | |
| 728 | + */ | |
| 729 | + if (!IS_ENABLED(CONFIG_PREEMPT_RT)) | |
| 730 | + return true; | |
| 731 | + | |
| 732 | + /* | |
| 733 | + * On RT enabled kernels, the task must not be blocked on a lock as | |
| 734 | + * that could corrupt the PI state when blocking on a lock in the | |
| 735 | + * allocation path. | |
| 736 | + */ | |
| 737 | + if (debug_objects_is_pi_blocked_on()) | |
| 738 | + return false; | |
| 739 | + | |
| 740 | + /* | |
| 741 | + * On RT enabled kernels the pool refill should happen in preemptible | |
| 742 | + * context. | |
| 743 | + */ | |
| 744 | + if (preemptible()) | |
| 745 | + return true; | |
| 746 | + | |
| 747 | + /* | |
| 748 | + * Though during system boot before scheduling is set up, preemption is | |
| 749 | + * disabled and the pool can get exhausted. Before scheduling is active | |
| 750 | + * a task cannot be blocked on a sleeping lock, but it might hold a lock | |
| 751 | + * and if interrupted then hard interrupt context might run into a lock | |
| 752 | + * inversion. So exclude hard interrupt context from allocations before | |
| 753 | + * scheduling is active. | |
| 754 | + */ | |
| 755 | + return system_state < SYSTEM_SCHEDULING && !in_hardirq(); | |
| 756 | +} | |
| 757 | + | |
| 723 | 758 | static void debug_objects_fill_pool(void) |
| 724 | 759 | { |
| 725 | 760 | if (!static_branch_likely(&obj_cache_enabled)) |
| @@ -734,18 +769,11 @@ static void debug_objects_fill_pool(void) · 8 unmodified lines | ||
| 734 | 769 | if (likely(!pool_should_refill(&pool_global))) |
| 735 | 770 | return; |
| 736 | 771 | |
| 737 | − /* | |
| 738 | − * On RT enabled kernels the pool refill must happen in preemptible | |
| 739 | − * context and not enqueued on an rt_mutex -- for !RT kernels we rely | |
| 740 | − * on the fact that spinlock_t and raw_spinlock_t are basically the | |
| 741 | − * same type and this lock-type inversion works just fine. | |
| 742 | − */ | |
| 743 | − if (!IS_ENABLED(CONFIG_PREEMPT_RT) || system_state < SYSTEM_SCHEDULING || | |
| 744 | − (preemptible() && !debug_objects_is_pi_blocked_on())) { | |
| 772 | + if (can_fill_pool()) { | |
| 745 | 773 | /* |
| 746 | 774 | * Annotate away the spinlock_t inside raw_spinlock_t warning |
| 747 | 775 | * by temporarily raising the wait-type to LD_WAIT_CONFIG, matching |
| 748 | − * the preemptible() condition above. | |
| 776 | + * the preemptible() condition in can_fill_pool(). | |
| 749 | 777 | */ |
| 750 | 778 | static DEFINE_WAIT_OVERRIDE_MAP(fill_pool_map, LD_WAIT_CONFIG); |
| 751 | 779 | lock_map_acquire_try(&fill_pool_map); |