Re: [PATCH] usbhid: Fix lockdep unannotated irqs-off warning

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



> What shall I do... play with lockdep (print_irqtrace_events) in
> del_timer_sync()?

I recalled that when Jiri was thinking towards a "compiler bug" that
the part in del_timer_sync() emebedded in the "ifdef CONFIG_LOCKDEP"
is somehow "mis-compiled".
Furthermore, I see that try_to_del_timer_sync() is invoked within
del_timer_sync() which does a spin_unlock_irqrestore().

[ kernel/time/timer.c ]

int del_timer_sync(struct timer_list *timer)
{
#ifdef CONFIG_LOCKDEP
unsigned long flags;

/*
* If lockdep gives a backtrace here, please reference
* the synchronization rules above.
*/
local_irq_save(flags);
lock_map_acquire(&timer->lockdep_map);
lock_map_release(&timer->lockdep_map);
local_irq_restore(flags);
#endif
/*
* don't use it in hardirq context, because it
* could lead to deadlock.
*/
WARN_ON(in_irq() && !(timer->flags & TIMER_IRQSAFE));
for (;;) {
int ret = try_to_del_timer_sync(timer);
if (ret >= 0)
return ret;
cpu_relax();
}
}
EXPORT_SYMBOL(del_timer_sync);
#endif
...
int try_to_del_timer_sync(struct timer_list *timer)
{
struct tvec_base *base;
unsigned long flags;
int ret = -1;

debug_assert_init(timer);

base = lock_timer_base(timer, &flags);

if (base->running_timer != timer) {
timer_stats_timer_clear_start_info(timer);
ret = detach_if_pending(timer, base, true);
}
spin_unlock_irqrestore(&base->lock, flags);

return ret;
}
EXPORT_SYMBOL(try_to_del_timer_sync);
...

Is the attached patch suitable for a test?

I remember I tried to turn lockdep kernel-config for amd64 but that
was somehow tricky.

Shall I ask timer folks?

Thoughts?

Thanks!

- Sedat -
From edb4cb72c631c5e588af40794830c5bb5d6a927a Mon Sep 17 00:00:00 2001
From: Sedat Dilek <sedat.dilek@xxxxxxxxx>
Date: Wed, 30 Sep 2015 08:20:15 +0200
Subject: [PATCH] timer: lockdep: Add WARN_ON(irqs_disabled()) to
 del_timer_sync()

---
 kernel/locking/lockdep.c | 1 +
 kernel/time/timer.c      | 3 +++
 2 files changed, 4 insertions(+)

diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index 8acfbf773e06..8b29b3dd518f 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -2410,6 +2410,7 @@ void print_irqtrace_events(struct task_struct *curr)
 	printk("softirqs last disabled at (%u): ", curr->softirq_disable_event);
 	print_ip_sym(curr->softirq_disable_ip);
 }
+EXPORT_SYMBOL(print_irqtrace_events);
 
 static int HARDIRQ_verbose(struct lock_class *class)
 {
diff --git a/kernel/time/timer.c b/kernel/time/timer.c
index 84190f02b521..f434b2dce642 100644
--- a/kernel/time/timer.c
+++ b/kernel/time/timer.c
@@ -1082,6 +1082,9 @@ int del_timer_sync(struct timer_list *timer)
 #ifdef CONFIG_LOCKDEP
 	unsigned long flags;
 
+	if(WARN_ON(irqs_disabled()))
+		print_irqtrace_events(current);
+
 	/*
 	 * If lockdep gives a backtrace here, please reference
 	 * the synchronization rules above.
-- 
2.5.3


[Index of Archives]     [Linux Media Devel]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Linux Wireless Networking]     [Linux Omap]

  Powered by Linux