@@ -1179,9 +1179,9 @@ EXPORT_SYMBOL_GPL(add_timer_on);
static void wait_for_running_timer(struct timer_list *timer)
{
struct timer_base *base;
- u32 tf = timer->flags;
+ u32 tf = READ_ONCE(timer->flags);
- if (tf & TIMER_MIGRATING)
+ if (tf & (TIMER_MIGRATING | TIMER_IRQSAFE))
return;
base = get_timer_base(tf);
@@ -1312,6 +1312,13 @@ int del_timer_sync(struct timer_list *timer)
* could lead to deadlock.
*/
WARN_ON(in_irq() && !(timer->flags & TIMER_IRQSAFE));
+ /*
+ * Must be able to sleep on PREEMPT_RT because of the slowpath in
+ * del_timer_wait_running().
+ */
+ if (IS_ENABLED(CONFIG_PREEMPT_RT) && !(timer->flags & TIMER_IRQSAFE))
+ might_sleep();
+
for (;;) {
int ret = try_to_del_timer_sync(timer);
if (ret >= 0)