2011-02-03 14:17:54

by Peter Zijlstra

[permalink] [raw]
Subject: [PATCH 1/4] lockdep, timer: Fix del_timer_sync() annotation

Calling local_bh_enable() will want to actually start processing
softirqs, which isn't a good idea since this can get called with IRQs
disabled.

Cure this by using _local_bh_enable() which doesn't start processing
softirqs, and use raw_local_irq_save() to avoid any softirqs from
happending without letting lockdep think IRQs are in fact disabled.

Reported-by: Nick Bowler <[email protected]>
Signed-off-by: Peter Zijlstra <[email protected]>
LKML-Reference: <new-submission>
---
kernel/timer.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)

Index: linux-2.6/kernel/timer.c
===================================================================
--- linux-2.6.orig/kernel/timer.c
+++ linux-2.6/kernel/timer.c
@@ -969,10 +969,14 @@ EXPORT_SYMBOL(try_to_del_timer_sync);
int del_timer_sync(struct timer_list *timer)
{
#ifdef CONFIG_LOCKDEP
+ unsigned long flags;
+
+ raw_local_irq_save(flags);
local_bh_disable();
lock_map_acquire(&timer->lockdep_map);
lock_map_release(&timer->lockdep_map);
- local_bh_enable();
+ _local_bh_enable();
+ raw_local_irq_restore(flags);
#endif
/*
* don't use it in hardirq context, because it


2011-02-03 15:38:33

by Thomas Gleixner

[permalink] [raw]
Subject: Re: [PATCH 1/4] lockdep, timer: Fix del_timer_sync() annotation

On Thu, 3 Feb 2011, Peter Zijlstra wrote:

> Calling local_bh_enable() will want to actually start processing
> softirqs, which isn't a good idea since this can get called with IRQs
> disabled.
>
> Cure this by using _local_bh_enable() which doesn't start processing
> softirqs, and use raw_local_irq_save() to avoid any softirqs from
> happending without letting lockdep think IRQs are in fact disabled.
>
> Reported-by: Nick Bowler <[email protected]>

Nick, can you please test ?

Thanks,

tglx

> Signed-off-by: Peter Zijlstra <[email protected]>
> LKML-Reference: <new-submission>
> ---
> kernel/timer.c | 6 +++++-
> 1 file changed, 5 insertions(+), 1 deletion(-)
>
> Index: linux-2.6/kernel/timer.c
> ===================================================================
> --- linux-2.6.orig/kernel/timer.c
> +++ linux-2.6/kernel/timer.c
> @@ -969,10 +969,14 @@ EXPORT_SYMBOL(try_to_del_timer_sync);
> int del_timer_sync(struct timer_list *timer)
> {
> #ifdef CONFIG_LOCKDEP
> + unsigned long flags;
> +
> + raw_local_irq_save(flags);
> local_bh_disable();
> lock_map_acquire(&timer->lockdep_map);
> lock_map_release(&timer->lockdep_map);
> - local_bh_enable();
> + _local_bh_enable();
> + raw_local_irq_restore(flags);
> #endif
> /*
> * don't use it in hardirq context, because it
>
>

2011-02-04 03:28:52

by Yong Zhang

[permalink] [raw]
Subject: Re: [PATCH 1/4] lockdep, timer: Fix del_timer_sync() annotation

On Thu, Feb 03, 2011 at 03:09:41PM +0100, Peter Zijlstra wrote:
> Calling local_bh_enable() will want to actually start processing
> softirqs, which isn't a good idea since this can get called with IRQs
> disabled.
>
> Cure this by using _local_bh_enable() which doesn't start processing
> softirqs, and use raw_local_irq_save() to avoid any softirqs from
> happending without letting lockdep think IRQs are in fact disabled.
>
> Reported-by: Nick Bowler <[email protected]>
> Signed-off-by: Peter Zijlstra <[email protected]>
> LKML-Reference: <new-submission>
> ---
> kernel/timer.c | 6 +++++-
> 1 file changed, 5 insertions(+), 1 deletion(-)
>
> Index: linux-2.6/kernel/timer.c
> ===================================================================
> --- linux-2.6.orig/kernel/timer.c
> +++ linux-2.6/kernel/timer.c
> @@ -969,10 +969,14 @@ EXPORT_SYMBOL(try_to_del_timer_sync);
> int del_timer_sync(struct timer_list *timer)
> {
> #ifdef CONFIG_LOCKDEP
> + unsigned long flags;
> +
> + raw_local_irq_save(flags);
> local_bh_disable();
> lock_map_acquire(&timer->lockdep_map);
> lock_map_release(&timer->lockdep_map);
> - local_bh_enable();
> + _local_bh_enable();
> + raw_local_irq_restore(flags);

This is more cheap than what I have done ;)
I think it will cure the issue reported by Nick.
Thanks you anyway.

Reviewed-by: Yong Zhang <[email protected]>

2011-02-04 09:34:27

by Peter Zijlstra

[permalink] [raw]
Subject: [tip:timers/urgent] lockdep, timer: Fix del_timer_sync() annotation

Commit-ID: f266a5110d453b7987194460ac7edd31f1a5426c
Gitweb: http://git.kernel.org/tip/f266a5110d453b7987194460ac7edd31f1a5426c
Author: Peter Zijlstra <[email protected]>
AuthorDate: Thu, 3 Feb 2011 15:09:41 +0100
Committer: Thomas Gleixner <[email protected]>
CommitDate: Fri, 4 Feb 2011 10:31:22 +0100

lockdep, timer: Fix del_timer_sync() annotation

Calling local_bh_enable() will want to actually start processing
softirqs, which isn't a good idea since this can get called with IRQs
disabled.

Cure this by using _local_bh_enable() which doesn't start processing
softirqs, and use raw_local_irq_save() to avoid any softirqs from
happening without letting lockdep think IRQs are in fact disabled.

Reported-by: Nick Bowler <[email protected]>
Signed-off-by: Peter Zijlstra <[email protected]>
Reviewed-by: Yong Zhang <[email protected]>
LKML-Reference: <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
---
kernel/timer.c | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/kernel/timer.c b/kernel/timer.c
index 43ca993..d53ce66 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -969,10 +969,14 @@ EXPORT_SYMBOL(try_to_del_timer_sync);
int del_timer_sync(struct timer_list *timer)
{
#ifdef CONFIG_LOCKDEP
+ unsigned long flags;
+
+ raw_local_irq_save(flags);
local_bh_disable();
lock_map_acquire(&timer->lockdep_map);
lock_map_release(&timer->lockdep_map);
- local_bh_enable();
+ _local_bh_enable();
+ raw_local_irq_restore(flags);
#endif
/*
* don't use it in hardirq context, because it

2011-02-05 01:09:07

by Nick Bowler

[permalink] [raw]
Subject: Re: [PATCH 1/4] lockdep, timer: Fix del_timer_sync() annotation

On 2011-02-03 16:35 +0100, Thomas Gleixner wrote:
> On Thu, 3 Feb 2011, Peter Zijlstra wrote:
> > Calling local_bh_enable() will want to actually start processing
> > softirqs, which isn't a good idea since this can get called with IRQs
> > disabled.
> >
> > Cure this by using _local_bh_enable() which doesn't start processing
> > softirqs, and use raw_local_irq_save() to avoid any softirqs from
> > happending without letting lockdep think IRQs are in fact disabled.
> >
> > Reported-by: Nick Bowler <[email protected]>
>
> Nick, can you please test ?

Yes, this patch seems to solve the issue.

Thanks,
--
Nick Bowler, Elliptic Technologies (http://www.elliptictech.com/)