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 | #endif | 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 | static void debug_objects_fill_pool(void) | 758 | static void debug_objects_fill_pool(void) |
| 724 | { | 759 | { |
| 725 | if (!static_branch_likely(&obj_cache_enabled)) | 760 | if (!static_branch_likely(&obj_cache_enabled)) |
| @@ -734,18 +769,11 @@ static void debug_objects_fill_pool(void) · 8 unmodified lines | |||
| 734 | if (likely(!pool_should_refill(&pool_global))) | 769 | if (likely(!pool_should_refill(&pool_global))) |
| 735 | return; | 770 | return; |
| 736 | 771 | ||
| 737 | /* | 772 | if (can_fill_pool()) { |
| 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())) { | ||
| 745 | /* | 773 | /* |
| 746 | * Annotate away the spinlock_t inside raw_spinlock_t warning | 774 | * Annotate away the spinlock_t inside raw_spinlock_t warning |
| 747 | * by temporarily raising the wait-type to LD_WAIT_CONFIG, matching | 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 | static DEFINE_WAIT_OVERRIDE_MAP(fill_pool_map, LD_WAIT_CONFIG); | 778 | static DEFINE_WAIT_OVERRIDE_MAP(fill_pool_map, LD_WAIT_CONFIG); |
| 751 | lock_map_acquire_try(&fill_pool_map); | 779 | lock_map_acquire_try(&fill_pool_map); |