netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] NETLABEL: Fix an RCU warning
@ 2010-03-25 11:06 David Howells
  2010-03-25 11:28 ` Eric Dumazet
  0 siblings, 1 reply; 10+ messages in thread
From: David Howells @ 2010-03-25 11:06 UTC (permalink / raw)
  To: paul.moore; +Cc: netdev, David Howells

Fix an RCU warning in the netlabel code due to missing rcu read locking around
an rcu_dereference() in netlbl_unlhsh_hash() when called from
netlbl_unlhsh_netdev_handler():

===================================================
[ INFO: suspicious rcu_dereference_check() usage. ]
---------------------------------------------------
net/netlabel/netlabel_unlabeled.c:246 invoked rcu_dereference_check() without protection!

other info that might help us debug this:


rcu_scheduler_active = 1, debug_locks = 0
2 locks held by ip/5108:
 #0:  (rtnl_mutex){+.+.+.}, at: [<ffffffff812c4a36>] rtnl_lock+0x12/0x14
 #1:  (netlbl_unlhsh_lock){+.+...}, at: [<ffffffff8134daa4>] netlbl_unlhsh_netdev_handler+0x1e/0x86

stack backtrace:
Pid: 5108, comm: ip Not tainted 2.6.34-rc2-cachefs #114
Call Trace:
 [<ffffffff8105121f>] lockdep_rcu_dereference+0xaa/0xb2
 [<ffffffff8134d781>] netlbl_unlhsh_hash+0x3e/0x50
 [<ffffffff8134d7a1>] netlbl_unlhsh_search_iface+0xe/0x84
 [<ffffffff8134daaf>] netlbl_unlhsh_netdev_handler+0x29/0x86
 [<ffffffff81048362>] notifier_call_chain+0x32/0x5e
 [<ffffffff810483fe>] raw_notifier_call_chain+0xf/0x11
 [<ffffffff812ba924>] call_netdevice_notifiers+0x16/0x18
 [<ffffffff812bac22>] __dev_notify_flags+0x37/0x5b
 [<ffffffff812bac8c>] dev_change_flags+0x46/0x52
 [<ffffffff812c41af>] do_setlink+0x250/0x3cd
 [<ffffffff812c4ee8>] rtnl_newlink+0x2b6/0x49d
 [<ffffffff812c4cdd>] ? rtnl_newlink+0xab/0x49d
 [<ffffffff812c4c17>] rtnetlink_rcv_msg+0x1b7/0x1d2
 [<ffffffff812c4a60>] ? rtnetlink_rcv_msg+0x0/0x1d2
 [<ffffffff812cc1dc>] netlink_rcv_skb+0x3e/0x8f
 [<ffffffff812c4a59>] rtnetlink_rcv+0x21/0x28
 [<ffffffff812cbefe>] netlink_unicast+0x218/0x28f
 [<ffffffff812cc76e>] netlink_sendmsg+0x26b/0x27a
 [<ffffffff812a9f1d>] sock_sendmsg+0xd4/0xf5
 [<ffffffff81096dca>] ? might_fault+0x4e/0x9e
 [<ffffffff81096dca>] ? might_fault+0x4e/0x9e
 [<ffffffff81096e13>] ? might_fault+0x97/0x9e
 [<ffffffff81096dca>] ? might_fault+0x4e/0x9e
 [<ffffffff812b4122>] ? verify_iovec+0x59/0x97
 [<ffffffff812aa1d9>] sys_sendmsg+0x209/0x273
 [<ffffffff810976dc>] ? __do_fault+0x395/0x3cd
 [<ffffffff8109928f>] ? handle_mm_fault+0x324/0x69d
 [<ffffffff81051e4e>] ? trace_hardirqs_on_caller+0x10c/0x130
 [<ffffffff81074972>] ? audit_syscall_entry+0x17d/0x1b0
 [<ffffffff81364154>] ? trace_hardirqs_on_thunk+0x3a/0x3f
 [<ffffffff81001eeb>] system_call_fastpath+0x16/0x1b

Signed-off-by: David Howells <dhowells@redhat.com>
---

 net/netlabel/netlabel_unlabeled.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c
index 852d9d7..7ea64e4 100644
--- a/net/netlabel/netlabel_unlabeled.c
+++ b/net/netlabel/netlabel_unlabeled.c
@@ -799,6 +799,7 @@ static int netlbl_unlhsh_netdev_handler(struct notifier_block *this,
 
 	/* XXX - should this be a check for NETDEV_DOWN or _UNREGISTER? */
 	if (event == NETDEV_DOWN) {
+		rcu_read_lock();
 		spin_lock(&netlbl_unlhsh_lock);
 		iface = netlbl_unlhsh_search_iface(dev->ifindex);
 		if (iface != NULL && iface->valid) {
@@ -807,6 +808,7 @@ static int netlbl_unlhsh_netdev_handler(struct notifier_block *this,
 		} else
 			iface = NULL;
 		spin_unlock(&netlbl_unlhsh_lock);
+		rcu_read_unlock();
 	}
 
 	if (iface != NULL)


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH] NETLABEL: Fix an RCU warning
  2010-03-25 11:06 [PATCH] NETLABEL: Fix an RCU warning David Howells
@ 2010-03-25 11:28 ` Eric Dumazet
  2010-03-25 11:37   ` David Howells
  2010-03-29 15:24   ` Paul E. McKenney
  0 siblings, 2 replies; 10+ messages in thread
From: Eric Dumazet @ 2010-03-25 11:28 UTC (permalink / raw)
  To: David Howells; +Cc: paul.moore, netdev

Le jeudi 25 mars 2010 à 11:06 +0000, David Howells a écrit :
> Fix an RCU warning in the netlabel code due to missing rcu read locking around
> an rcu_dereference() in netlbl_unlhsh_hash() when called from
> netlbl_unlhsh_netdev_handler():
> 
> ===================================================
> [ INFO: suspicious rcu_dereference_check() usage. ]
> ---------------------------------------------------
> net/netlabel/netlabel_unlabeled.c:246 invoked rcu_dereference_check() without protection!
> 
> other info that might help us debug this:
> 
> 
> rcu_scheduler_active = 1, debug_locks = 0
> 2 locks held by ip/5108:
>  #0:  (rtnl_mutex){+.+.+.}, at: [<ffffffff812c4a36>] rtnl_lock+0x12/0x14
>  #1:  (netlbl_unlhsh_lock){+.+...}, at: [<ffffffff8134daa4>] netlbl_unlhsh_netdev_handler+0x1e/0x86
> 
> stack backtrace:
> Pid: 5108, comm: ip Not tainted 2.6.34-rc2-cachefs #114
> Call Trace:
>  [<ffffffff8105121f>] lockdep_rcu_dereference+0xaa/0xb2
>  [<ffffffff8134d781>] netlbl_unlhsh_hash+0x3e/0x50
>  [<ffffffff8134d7a1>] netlbl_unlhsh_search_iface+0xe/0x84
>  [<ffffffff8134daaf>] netlbl_unlhsh_netdev_handler+0x29/0x86
>  [<ffffffff81048362>] notifier_call_chain+0x32/0x5e
>  [<ffffffff810483fe>] raw_notifier_call_chain+0xf/0x11
>  [<ffffffff812ba924>] call_netdevice_notifiers+0x16/0x18
>  [<ffffffff812bac22>] __dev_notify_flags+0x37/0x5b
>  [<ffffffff812bac8c>] dev_change_flags+0x46/0x52
>  [<ffffffff812c41af>] do_setlink+0x250/0x3cd
>  [<ffffffff812c4ee8>] rtnl_newlink+0x2b6/0x49d
>  [<ffffffff812c4cdd>] ? rtnl_newlink+0xab/0x49d
>  [<ffffffff812c4c17>] rtnetlink_rcv_msg+0x1b7/0x1d2
>  [<ffffffff812c4a60>] ? rtnetlink_rcv_msg+0x0/0x1d2
>  [<ffffffff812cc1dc>] netlink_rcv_skb+0x3e/0x8f
>  [<ffffffff812c4a59>] rtnetlink_rcv+0x21/0x28
>  [<ffffffff812cbefe>] netlink_unicast+0x218/0x28f
>  [<ffffffff812cc76e>] netlink_sendmsg+0x26b/0x27a
>  [<ffffffff812a9f1d>] sock_sendmsg+0xd4/0xf5
>  [<ffffffff81096dca>] ? might_fault+0x4e/0x9e
>  [<ffffffff81096dca>] ? might_fault+0x4e/0x9e
>  [<ffffffff81096e13>] ? might_fault+0x97/0x9e
>  [<ffffffff81096dca>] ? might_fault+0x4e/0x9e
>  [<ffffffff812b4122>] ? verify_iovec+0x59/0x97
>  [<ffffffff812aa1d9>] sys_sendmsg+0x209/0x273
>  [<ffffffff810976dc>] ? __do_fault+0x395/0x3cd
>  [<ffffffff8109928f>] ? handle_mm_fault+0x324/0x69d
>  [<ffffffff81051e4e>] ? trace_hardirqs_on_caller+0x10c/0x130
>  [<ffffffff81074972>] ? audit_syscall_entry+0x17d/0x1b0
>  [<ffffffff81364154>] ? trace_hardirqs_on_thunk+0x3a/0x3f
>  [<ffffffff81001eeb>] system_call_fastpath+0x16/0x1b
> 
> Signed-off-by: David Howells <dhowells@redhat.com>
> ---
> 
>  net/netlabel/netlabel_unlabeled.c |    2 ++
>  1 files changed, 2 insertions(+), 0 deletions(-)
> 
> diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c
> index 852d9d7..7ea64e4 100644
> --- a/net/netlabel/netlabel_unlabeled.c
> +++ b/net/netlabel/netlabel_unlabeled.c
> @@ -799,6 +799,7 @@ static int netlbl_unlhsh_netdev_handler(struct notifier_block *this,
>  
>  	/* XXX - should this be a check for NETDEV_DOWN or _UNREGISTER? */
>  	if (event == NETDEV_DOWN) {
> +		rcu_read_lock();
>  		spin_lock(&netlbl_unlhsh_lock);
>  		iface = netlbl_unlhsh_search_iface(dev->ifindex);
>  		if (iface != NULL && iface->valid) {
> @@ -807,6 +808,7 @@ static int netlbl_unlhsh_netdev_handler(struct notifier_block *this,
>  		} else
>  			iface = NULL;
>  		spin_unlock(&netlbl_unlhsh_lock);
> +		rcu_read_unlock();
>  	}
>  
>  	if (iface != NULL)
> 
> --

Sorry this is not the right fix.

Fix is to change the dereference check to take into account the lock
owned here.





^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] NETLABEL: Fix an RCU warning
  2010-03-25 11:28 ` Eric Dumazet
@ 2010-03-25 11:37   ` David Howells
  2010-03-25 13:32     ` Eric Dumazet
  2010-03-29 15:24   ` Paul E. McKenney
  1 sibling, 1 reply; 10+ messages in thread
From: David Howells @ 2010-03-25 11:37 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: dhowells, paul.moore, netdev

Eric Dumazet <eric.dumazet@gmail.com> wrote:

> Sorry this is not the right fix.
> 
> Fix is to change the dereference check to take into account the lock
> owned here.

Then the comments on netlbl_unlhsh_hash(), netlbl_unlhsh_search_iface(),
netlbl_unlhsh_search_iface_def() and netlbl_unlhsh_add_iface() are all wrong,
for all of them say:

	* The caller is responsible for calling the rcu_read_[un]lock()
	* functions.

Furthermore, netlabel_unlhsh_add() and netlabel_unlhsh_remove() _do_ wrap the
calls to those functions in rcu_read_lock'd sections.

David

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] NETLABEL: Fix an RCU warning
  2010-03-25 11:37   ` David Howells
@ 2010-03-25 13:32     ` Eric Dumazet
  2010-03-25 14:10       ` Paul Moore
  0 siblings, 1 reply; 10+ messages in thread
From: Eric Dumazet @ 2010-03-25 13:32 UTC (permalink / raw)
  To: David Howells; +Cc: paul.moore, netdev, Paul E. McKenney

Le jeudi 25 mars 2010 à 11:37 +0000, David Howells a écrit :
> Eric Dumazet <eric.dumazet@gmail.com> wrote:
> 
> > Sorry this is not the right fix.
> > 
> > Fix is to change the dereference check to take into account the lock
> > owned here.
> 
> Then the comments on netlbl_unlhsh_hash(), netlbl_unlhsh_search_iface(),
> netlbl_unlhsh_search_iface_def() and netlbl_unlhsh_add_iface() are all wrong,
> for all of them say:
> 
> 	* The caller is responsible for calling the rcu_read_[un]lock()
> 	* functions.
> 
> Furthermore, netlabel_unlhsh_add() and netlabel_unlhsh_remove() _do_ wrap the
> calls to those functions in rcu_read_lock'd sections.

Current code is probably fine.
Comments are not up to date (as many other comments BTW)

Only the dereference check is bad, as it assumes the rcu_read lock is
held.

Its not the case, we own a spinlock.

You suggest adding a surrounding rcu lock, but this surrounding lock
adds overhead on normal kernels, to correct checker warnings only.

If a mutex was protecting existing code, instead of a spinlock, then
adding rcu_read_lock() would be no correct anyway (existing code would
not be allowed to call a might_sleep function)

Please take a look at rcu_dereference_check() in :

__sk_free() (file net/core/sock.c) 
__in6_dev_get() (file include/net/addrconf.h)
rcu_dereference_check_fdtable (file include/linux/fdtable.h)
task_subsys_state() (file include/linux/cgroup.h)
rcu_dereference_check_sched_domain (file kernel/sched.c)
...

for examples of proper checks.

Yes, its more difficult, but its the right thing.



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] NETLABEL: Fix an RCU warning
  2010-03-25 13:32     ` Eric Dumazet
@ 2010-03-25 14:10       ` Paul Moore
  0 siblings, 0 replies; 10+ messages in thread
From: Paul Moore @ 2010-03-25 14:10 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: David Howells, netdev, Paul E. McKenney

On Thursday 25 March 2010 09:32:20 am Eric Dumazet wrote:
> Le jeudi 25 mars 2010 à 11:37 +0000, David Howells a écrit :
> > Eric Dumazet <eric.dumazet@gmail.com> wrote:
> > > Sorry this is not the right fix.
> > > 
> > > Fix is to change the dereference check to take into account the lock
> > > owned here.
> > 
> > Then the comments on netlbl_unlhsh_hash(), netlbl_unlhsh_search_iface(),
> > netlbl_unlhsh_search_iface_def() and netlbl_unlhsh_add_iface() are all
> > wrong,
> > 
> > for all of them say:
> > 	* The caller is responsible for calling the rcu_read_[un]lock()
> > 	* functions.
> > 
> > Furthermore, netlabel_unlhsh_add() and netlabel_unlhsh_remove() _do_ wrap
> > the calls to those functions in rcu_read_lock'd sections.
> 
> Current code is probably fine.
> Comments are not up to date (as many other comments BTW)
> 
> Only the dereference check is bad, as it assumes the rcu_read lock is
> held.
> 
> Its not the case, we own a spinlock.
> 
> You suggest adding a surrounding rcu lock, but this surrounding lock
> adds overhead on normal kernels, to correct checker warnings only.

The rcu_dereference call, and the outdated comments for that matter, are 
likely artifacts from an early patch.  When the code was originally being 
developed I had assumed that you _always_ needed to hold the RCU read lock 
when doing RCU operations, regardless of if you were already holding the 
associated spinlock.  Thankfully, Paul McKenney was able to review the code 
and helped me to understand RCU a bit better, unfortunately, it looks like I 
still missed a few spots :/

Give me a day or two to go through the comments again and do some sanity 
checks and I'll send out a patch.  However, if you've already got something 
that is tested and ready to go don't let me stand in your way.

-- 
paul moore
linux @ hp

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] NETLABEL: Fix an RCU warning
  2010-03-25 11:28 ` Eric Dumazet
  2010-03-25 11:37   ` David Howells
@ 2010-03-29 15:24   ` Paul E. McKenney
  2010-03-29 15:30     ` Paul Moore
  1 sibling, 1 reply; 10+ messages in thread
From: Paul E. McKenney @ 2010-03-29 15:24 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: David Howells, paul.moore, netdev

On Thu, Mar 25, 2010 at 12:28:04PM +0100, Eric Dumazet wrote:
> Le jeudi 25 mars 2010 à 11:06 +0000, David Howells a écrit :
> > Fix an RCU warning in the netlabel code due to missing rcu read locking around
> > an rcu_dereference() in netlbl_unlhsh_hash() when called from
> > netlbl_unlhsh_netdev_handler():
> > 
> > ===================================================
> > [ INFO: suspicious rcu_dereference_check() usage. ]
> > ---------------------------------------------------
> > net/netlabel/netlabel_unlabeled.c:246 invoked rcu_dereference_check() without protection!
> > 
> > other info that might help us debug this:
> > 
> > 
> > rcu_scheduler_active = 1, debug_locks = 0
> > 2 locks held by ip/5108:
> >  #0:  (rtnl_mutex){+.+.+.}, at: [<ffffffff812c4a36>] rtnl_lock+0x12/0x14
> >  #1:  (netlbl_unlhsh_lock){+.+...}, at: [<ffffffff8134daa4>] netlbl_unlhsh_netdev_handler+0x1e/0x86
> > 
> > stack backtrace:
> > Pid: 5108, comm: ip Not tainted 2.6.34-rc2-cachefs #114
> > Call Trace:
> >  [<ffffffff8105121f>] lockdep_rcu_dereference+0xaa/0xb2
> >  [<ffffffff8134d781>] netlbl_unlhsh_hash+0x3e/0x50
> >  [<ffffffff8134d7a1>] netlbl_unlhsh_search_iface+0xe/0x84
> >  [<ffffffff8134daaf>] netlbl_unlhsh_netdev_handler+0x29/0x86
> >  [<ffffffff81048362>] notifier_call_chain+0x32/0x5e
> >  [<ffffffff810483fe>] raw_notifier_call_chain+0xf/0x11
> >  [<ffffffff812ba924>] call_netdevice_notifiers+0x16/0x18
> >  [<ffffffff812bac22>] __dev_notify_flags+0x37/0x5b
> >  [<ffffffff812bac8c>] dev_change_flags+0x46/0x52
> >  [<ffffffff812c41af>] do_setlink+0x250/0x3cd
> >  [<ffffffff812c4ee8>] rtnl_newlink+0x2b6/0x49d
> >  [<ffffffff812c4cdd>] ? rtnl_newlink+0xab/0x49d
> >  [<ffffffff812c4c17>] rtnetlink_rcv_msg+0x1b7/0x1d2
> >  [<ffffffff812c4a60>] ? rtnetlink_rcv_msg+0x0/0x1d2
> >  [<ffffffff812cc1dc>] netlink_rcv_skb+0x3e/0x8f
> >  [<ffffffff812c4a59>] rtnetlink_rcv+0x21/0x28
> >  [<ffffffff812cbefe>] netlink_unicast+0x218/0x28f
> >  [<ffffffff812cc76e>] netlink_sendmsg+0x26b/0x27a
> >  [<ffffffff812a9f1d>] sock_sendmsg+0xd4/0xf5
> >  [<ffffffff81096dca>] ? might_fault+0x4e/0x9e
> >  [<ffffffff81096dca>] ? might_fault+0x4e/0x9e
> >  [<ffffffff81096e13>] ? might_fault+0x97/0x9e
> >  [<ffffffff81096dca>] ? might_fault+0x4e/0x9e
> >  [<ffffffff812b4122>] ? verify_iovec+0x59/0x97
> >  [<ffffffff812aa1d9>] sys_sendmsg+0x209/0x273
> >  [<ffffffff810976dc>] ? __do_fault+0x395/0x3cd
> >  [<ffffffff8109928f>] ? handle_mm_fault+0x324/0x69d
> >  [<ffffffff81051e4e>] ? trace_hardirqs_on_caller+0x10c/0x130
> >  [<ffffffff81074972>] ? audit_syscall_entry+0x17d/0x1b0
> >  [<ffffffff81364154>] ? trace_hardirqs_on_thunk+0x3a/0x3f
> >  [<ffffffff81001eeb>] system_call_fastpath+0x16/0x1b
> > 
> > Signed-off-by: David Howells <dhowells@redhat.com>
> > ---
> > 
> >  net/netlabel/netlabel_unlabeled.c |    2 ++
> >  1 files changed, 2 insertions(+), 0 deletions(-)
> > 
> > diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c
> > index 852d9d7..7ea64e4 100644
> > --- a/net/netlabel/netlabel_unlabeled.c
> > +++ b/net/netlabel/netlabel_unlabeled.c
> > @@ -799,6 +799,7 @@ static int netlbl_unlhsh_netdev_handler(struct notifier_block *this,
> >  
> >  	/* XXX - should this be a check for NETDEV_DOWN or _UNREGISTER? */
> >  	if (event == NETDEV_DOWN) {
> > +		rcu_read_lock();
> >  		spin_lock(&netlbl_unlhsh_lock);
> >  		iface = netlbl_unlhsh_search_iface(dev->ifindex);
> >  		if (iface != NULL && iface->valid) {
> > @@ -807,6 +808,7 @@ static int netlbl_unlhsh_netdev_handler(struct notifier_block *this,
> >  		} else
> >  			iface = NULL;
> >  		spin_unlock(&netlbl_unlhsh_lock);
> > +		rcu_read_unlock();
> >  	}
> >  
> >  	if (iface != NULL)
> > 
> > --
> 
> Sorry this is not the right fix.
> 
> Fix is to change the dereference check to take into account the lock
> owned here.

So we need the rcu_dereference() in netlbl_unlhsh_search_iface()
to become someething like the following?

	bkt_list = &rcu_dereference_check(netlbl_unlhsh,
					  rcu_read_lock_held() ||
					  lockdep_is_held(&netlbl_unlhsh_lock))->tbl[bkt];

Or is this the wrong lock?

							Thanx, Paul

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] NETLABEL: Fix an RCU warning
  2010-03-29 15:24   ` Paul E. McKenney
@ 2010-03-29 15:30     ` Paul Moore
  2010-03-29 15:58       ` Paul E. McKenney
  0 siblings, 1 reply; 10+ messages in thread
From: Paul Moore @ 2010-03-29 15:30 UTC (permalink / raw)
  To: paulmck; +Cc: Eric Dumazet, David Howells, netdev

On Monday 29 March 2010 11:24:53 am Paul E. McKenney wrote:
> On Thu, Mar 25, 2010 at 12:28:04PM +0100, Eric Dumazet wrote:
> > Le jeudi 25 mars 2010 à 11:06 +0000, David Howells a écrit :
> > > Fix an RCU warning in the netlabel code due to missing rcu read locking
> > > around an rcu_dereference() in netlbl_unlhsh_hash() when called from
> > > netlbl_unlhsh_netdev_handler():
> > > 
> > > ===================================================
> > > [ INFO: suspicious rcu_dereference_check() usage. ]
> > > ---------------------------------------------------
> > > net/netlabel/netlabel_unlabeled.c:246 invoked rcu_dereference_check()
> > > without protection!
> > > 
> > > other info that might help us debug this:
> > > 
> > > 
> > > rcu_scheduler_active = 1, debug_locks = 0
> > > 
> > > 2 locks held by ip/5108:
> > >  #0:  (rtnl_mutex){+.+.+.}, at: [<ffffffff812c4a36>]
> > >  rtnl_lock+0x12/0x14 #1:  (netlbl_unlhsh_lock){+.+...}, at:
> > >  [<ffffffff8134daa4>] netlbl_unlhsh_netdev_handler+0x1e/0x86
> > > 
> > > stack backtrace:
> > > Pid: 5108, comm: ip Not tainted 2.6.34-rc2-cachefs #114
> > > 
> > > Call Trace:
> > >  [<ffffffff8105121f>] lockdep_rcu_dereference+0xaa/0xb2
> > >  [<ffffffff8134d781>] netlbl_unlhsh_hash+0x3e/0x50
> > >  [<ffffffff8134d7a1>] netlbl_unlhsh_search_iface+0xe/0x84
> > >  [<ffffffff8134daaf>] netlbl_unlhsh_netdev_handler+0x29/0x86
> > >  [<ffffffff81048362>] notifier_call_chain+0x32/0x5e
> > >  [<ffffffff810483fe>] raw_notifier_call_chain+0xf/0x11
> > >  [<ffffffff812ba924>] call_netdevice_notifiers+0x16/0x18
> > >  [<ffffffff812bac22>] __dev_notify_flags+0x37/0x5b
> > >  [<ffffffff812bac8c>] dev_change_flags+0x46/0x52
> > >  [<ffffffff812c41af>] do_setlink+0x250/0x3cd
> > >  [<ffffffff812c4ee8>] rtnl_newlink+0x2b6/0x49d
> > >  [<ffffffff812c4cdd>] ? rtnl_newlink+0xab/0x49d
> > >  [<ffffffff812c4c17>] rtnetlink_rcv_msg+0x1b7/0x1d2
> > >  [<ffffffff812c4a60>] ? rtnetlink_rcv_msg+0x0/0x1d2
> > >  [<ffffffff812cc1dc>] netlink_rcv_skb+0x3e/0x8f
> > >  [<ffffffff812c4a59>] rtnetlink_rcv+0x21/0x28
> > >  [<ffffffff812cbefe>] netlink_unicast+0x218/0x28f
> > >  [<ffffffff812cc76e>] netlink_sendmsg+0x26b/0x27a
> > >  [<ffffffff812a9f1d>] sock_sendmsg+0xd4/0xf5
> > >  [<ffffffff81096dca>] ? might_fault+0x4e/0x9e
> > >  [<ffffffff81096dca>] ? might_fault+0x4e/0x9e
> > >  [<ffffffff81096e13>] ? might_fault+0x97/0x9e
> > >  [<ffffffff81096dca>] ? might_fault+0x4e/0x9e
> > >  [<ffffffff812b4122>] ? verify_iovec+0x59/0x97
> > >  [<ffffffff812aa1d9>] sys_sendmsg+0x209/0x273
> > >  [<ffffffff810976dc>] ? __do_fault+0x395/0x3cd
> > >  [<ffffffff8109928f>] ? handle_mm_fault+0x324/0x69d
> > >  [<ffffffff81051e4e>] ? trace_hardirqs_on_caller+0x10c/0x130
> > >  [<ffffffff81074972>] ? audit_syscall_entry+0x17d/0x1b0
> > >  [<ffffffff81364154>] ? trace_hardirqs_on_thunk+0x3a/0x3f
> > >  [<ffffffff81001eeb>] system_call_fastpath+0x16/0x1b
> > > 
> > > Signed-off-by: David Howells <dhowells@redhat.com>
> > > ---
> > > 
> > >  net/netlabel/netlabel_unlabeled.c |    2 ++
> > >  1 files changed, 2 insertions(+), 0 deletions(-)
> > > 
> > > diff --git a/net/netlabel/netlabel_unlabeled.c
> > > b/net/netlabel/netlabel_unlabeled.c index 852d9d7..7ea64e4 100644
> > > --- a/net/netlabel/netlabel_unlabeled.c
> > > +++ b/net/netlabel/netlabel_unlabeled.c
> > > @@ -799,6 +799,7 @@ static int netlbl_unlhsh_netdev_handler(struct
> > > notifier_block *this,
> > > 
> > >  	/* XXX - should this be a check for NETDEV_DOWN or _UNREGISTER? */
> > >  	if (event == NETDEV_DOWN) {
> > > 
> > > +		rcu_read_lock();
> > > 
> > >  		spin_lock(&netlbl_unlhsh_lock);
> > >  		iface = netlbl_unlhsh_search_iface(dev->ifindex);
> > >  		if (iface != NULL && iface->valid) {
> > > 
> > > @@ -807,6 +808,7 @@ static int netlbl_unlhsh_netdev_handler(struct
> > > notifier_block *this,
> > > 
> > >  		} else
> > >  		
> > >  			iface = NULL;
> > >  		
> > >  		spin_unlock(&netlbl_unlhsh_lock);
> > > 
> > > +		rcu_read_unlock();
> > > 
> > >  	}
> > >  	
> > >  	if (iface != NULL)
> > > 
> > > --
> > 
> > Sorry this is not the right fix.
> > 
> > Fix is to change the dereference check to take into account the lock
> > owned here.
> 
> So we need the rcu_dereference() in netlbl_unlhsh_search_iface()
> to become someething like the following?
> 
> 	bkt_list = &rcu_dereference_check(netlbl_unlhsh,
> 					  rcu_read_lock_held() ||
> 					  lockdep_is_held(&netlbl_unlhsh_lock))->tbl[bkt];
> 
> Or is this the wrong lock?

As Eric pointed out in response to the message above, I believe the solution 
is to simply remove the rcu_dereference() call in the netlbl_unlhsh_hash() 
function.

-- 
paul moore
linux @ hp

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] NETLABEL: Fix an RCU warning
  2010-03-29 15:30     ` Paul Moore
@ 2010-03-29 15:58       ` Paul E. McKenney
  2010-03-29 20:05         ` Paul Moore
  0 siblings, 1 reply; 10+ messages in thread
From: Paul E. McKenney @ 2010-03-29 15:58 UTC (permalink / raw)
  To: Paul Moore; +Cc: Eric Dumazet, David Howells, netdev

On Mon, Mar 29, 2010 at 11:30:10AM -0400, Paul Moore wrote:
> On Monday 29 March 2010 11:24:53 am Paul E. McKenney wrote:
> > On Thu, Mar 25, 2010 at 12:28:04PM +0100, Eric Dumazet wrote:
> > > Le jeudi 25 mars 2010 à 11:06 +0000, David Howells a écrit :
> > > > Fix an RCU warning in the netlabel code due to missing rcu read locking
> > > > around an rcu_dereference() in netlbl_unlhsh_hash() when called from
> > > > netlbl_unlhsh_netdev_handler():
> > > > 
> > > > ===================================================
> > > > [ INFO: suspicious rcu_dereference_check() usage. ]
> > > > ---------------------------------------------------
> > > > net/netlabel/netlabel_unlabeled.c:246 invoked rcu_dereference_check()
> > > > without protection!
> > > > 
> > > > other info that might help us debug this:
> > > > 
> > > > 
> > > > rcu_scheduler_active = 1, debug_locks = 0
> > > > 
> > > > 2 locks held by ip/5108:
> > > >  #0:  (rtnl_mutex){+.+.+.}, at: [<ffffffff812c4a36>]
> > > >  rtnl_lock+0x12/0x14 #1:  (netlbl_unlhsh_lock){+.+...}, at:
> > > >  [<ffffffff8134daa4>] netlbl_unlhsh_netdev_handler+0x1e/0x86
> > > > 
> > > > stack backtrace:
> > > > Pid: 5108, comm: ip Not tainted 2.6.34-rc2-cachefs #114
> > > > 
> > > > Call Trace:
> > > >  [<ffffffff8105121f>] lockdep_rcu_dereference+0xaa/0xb2
> > > >  [<ffffffff8134d781>] netlbl_unlhsh_hash+0x3e/0x50
> > > >  [<ffffffff8134d7a1>] netlbl_unlhsh_search_iface+0xe/0x84
> > > >  [<ffffffff8134daaf>] netlbl_unlhsh_netdev_handler+0x29/0x86
> > > >  [<ffffffff81048362>] notifier_call_chain+0x32/0x5e
> > > >  [<ffffffff810483fe>] raw_notifier_call_chain+0xf/0x11
> > > >  [<ffffffff812ba924>] call_netdevice_notifiers+0x16/0x18
> > > >  [<ffffffff812bac22>] __dev_notify_flags+0x37/0x5b
> > > >  [<ffffffff812bac8c>] dev_change_flags+0x46/0x52
> > > >  [<ffffffff812c41af>] do_setlink+0x250/0x3cd
> > > >  [<ffffffff812c4ee8>] rtnl_newlink+0x2b6/0x49d
> > > >  [<ffffffff812c4cdd>] ? rtnl_newlink+0xab/0x49d
> > > >  [<ffffffff812c4c17>] rtnetlink_rcv_msg+0x1b7/0x1d2
> > > >  [<ffffffff812c4a60>] ? rtnetlink_rcv_msg+0x0/0x1d2
> > > >  [<ffffffff812cc1dc>] netlink_rcv_skb+0x3e/0x8f
> > > >  [<ffffffff812c4a59>] rtnetlink_rcv+0x21/0x28
> > > >  [<ffffffff812cbefe>] netlink_unicast+0x218/0x28f
> > > >  [<ffffffff812cc76e>] netlink_sendmsg+0x26b/0x27a
> > > >  [<ffffffff812a9f1d>] sock_sendmsg+0xd4/0xf5
> > > >  [<ffffffff81096dca>] ? might_fault+0x4e/0x9e
> > > >  [<ffffffff81096dca>] ? might_fault+0x4e/0x9e
> > > >  [<ffffffff81096e13>] ? might_fault+0x97/0x9e
> > > >  [<ffffffff81096dca>] ? might_fault+0x4e/0x9e
> > > >  [<ffffffff812b4122>] ? verify_iovec+0x59/0x97
> > > >  [<ffffffff812aa1d9>] sys_sendmsg+0x209/0x273
> > > >  [<ffffffff810976dc>] ? __do_fault+0x395/0x3cd
> > > >  [<ffffffff8109928f>] ? handle_mm_fault+0x324/0x69d
> > > >  [<ffffffff81051e4e>] ? trace_hardirqs_on_caller+0x10c/0x130
> > > >  [<ffffffff81074972>] ? audit_syscall_entry+0x17d/0x1b0
> > > >  [<ffffffff81364154>] ? trace_hardirqs_on_thunk+0x3a/0x3f
> > > >  [<ffffffff81001eeb>] system_call_fastpath+0x16/0x1b
> > > > 
> > > > Signed-off-by: David Howells <dhowells@redhat.com>
> > > > ---
> > > > 
> > > >  net/netlabel/netlabel_unlabeled.c |    2 ++
> > > >  1 files changed, 2 insertions(+), 0 deletions(-)
> > > > 
> > > > diff --git a/net/netlabel/netlabel_unlabeled.c
> > > > b/net/netlabel/netlabel_unlabeled.c index 852d9d7..7ea64e4 100644
> > > > --- a/net/netlabel/netlabel_unlabeled.c
> > > > +++ b/net/netlabel/netlabel_unlabeled.c
> > > > @@ -799,6 +799,7 @@ static int netlbl_unlhsh_netdev_handler(struct
> > > > notifier_block *this,
> > > > 
> > > >  	/* XXX - should this be a check for NETDEV_DOWN or _UNREGISTER? */
> > > >  	if (event == NETDEV_DOWN) {
> > > > 
> > > > +		rcu_read_lock();
> > > > 
> > > >  		spin_lock(&netlbl_unlhsh_lock);
> > > >  		iface = netlbl_unlhsh_search_iface(dev->ifindex);
> > > >  		if (iface != NULL && iface->valid) {
> > > > 
> > > > @@ -807,6 +808,7 @@ static int netlbl_unlhsh_netdev_handler(struct
> > > > notifier_block *this,
> > > > 
> > > >  		} else
> > > >  		
> > > >  			iface = NULL;
> > > >  		
> > > >  		spin_unlock(&netlbl_unlhsh_lock);
> > > > 
> > > > +		rcu_read_unlock();
> > > > 
> > > >  	}
> > > >  	
> > > >  	if (iface != NULL)
> > > > 
> > > > --
> > > 
> > > Sorry this is not the right fix.
> > > 
> > > Fix is to change the dereference check to take into account the lock
> > > owned here.
> > 
> > So we need the rcu_dereference() in netlbl_unlhsh_search_iface()
> > to become someething like the following?
> > 
> > 	bkt_list = &rcu_dereference_check(netlbl_unlhsh,
> > 					  rcu_read_lock_held() ||
> > 					  lockdep_is_held(&netlbl_unlhsh_lock))->tbl[bkt];
> > 
> > Or is this the wrong lock?
> 
> As Eric pointed out in response to the message above, I believe the solution 
> is to simply remove the rcu_dereference() call in the netlbl_unlhsh_hash() 
> function.

It would be at the moment, but this will break once Arnd Bergmann gets
his sparse-based checks done.  With these checks, we decorate RCU-protected
pointers, and then sparse yells if you access such a pointer without the
proper rcu_dereference() invocation.

							Thanx, Paul

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] NETLABEL: Fix an RCU warning
  2010-03-29 15:58       ` Paul E. McKenney
@ 2010-03-29 20:05         ` Paul Moore
  2010-03-29 20:19           ` Eric Dumazet
  0 siblings, 1 reply; 10+ messages in thread
From: Paul Moore @ 2010-03-29 20:05 UTC (permalink / raw)
  To: paulmck; +Cc: Eric Dumazet, David Howells, netdev

On Monday 29 March 2010 11:58:57 am Paul E. McKenney wrote:
> On Mon, Mar 29, 2010 at 11:30:10AM -0400, Paul Moore wrote:
> > On Monday 29 March 2010 11:24:53 am Paul E. McKenney wrote:
> > > On Thu, Mar 25, 2010 at 12:28:04PM +0100, Eric Dumazet wrote:
> > > > Le jeudi 25 mars 2010 à 11:06 +0000, David Howells a écrit :
> > > > > Fix an RCU warning in the netlabel code due to missing rcu read
> > > > > locking around an rcu_dereference() in netlbl_unlhsh_hash() when
> > > > > called from netlbl_unlhsh_netdev_handler():
> > > > > 
> > > > > ===================================================
> > > > > [ INFO: suspicious rcu_dereference_check() usage. ]
> > > > > ---------------------------------------------------
> > > > > net/netlabel/netlabel_unlabeled.c:246 invoked
> > > > > rcu_dereference_check() without protection!

...

> > As Eric pointed out in response to the message above, I believe the
> > solution is to simply remove the rcu_dereference() call in the
> > netlbl_unlhsh_hash() function.
> 
> It would be at the moment, but this will break once Arnd Bergmann gets
> his sparse-based checks done.  With these checks, we decorate RCU-protected
> pointers, and then sparse yells if you access such a pointer without the
> proper rcu_dereference() invocation.

Okay, is there a recommended approach towards accessing RCU-protected pointers 
both under a RCU read lock and under only a spinlock (or similar lock 
construct)?  I know I could do something based on querying the state of the 
RCU/etc. locks but that seems like a hack and could interfere with some of the 
logic used to detect coding problems.

-- 
paul moore
linux @ hp

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] NETLABEL: Fix an RCU warning
  2010-03-29 20:05         ` Paul Moore
@ 2010-03-29 20:19           ` Eric Dumazet
  0 siblings, 0 replies; 10+ messages in thread
From: Eric Dumazet @ 2010-03-29 20:19 UTC (permalink / raw)
  To: Paul Moore; +Cc: paulmck, David Howells, netdev

Le lundi 29 mars 2010 à 16:05 -0400, Paul Moore a écrit :

> Okay, is there a recommended approach towards accessing RCU-protected pointers 
> both under a RCU read lock and under only a spinlock (or similar lock 
> construct)?  I know I could do something based on querying the state of the 
> RCU/etc. locks but that seems like a hack and could interfere with some of the 
> logic used to detect coding problems.
> 

Say you use a common function func1(), that use RCU protection, from a
pure reader, and from a pure writer.

pure_reader()
{
	rcu_read_lock();
	res = func1();
	rcu_read_unlock();
}

pure_writer()
{
	spin_lock(&some_lock);
	res = func1();
	spin_unlock(&some_lock);
}

then, func1 could use

func1()
{
 ..... ptr = rcu_dereference_check(xxx->ptr,
				   rcu_read_lock_held() || 
				   lockdep_is_held(&some_lock));
...
}


They are numerous examples in tree.
If some iterators use implicit rcu_dereference(), you'll probably need
to define new iterators, so that full condition can be tested.

rcu_dereference() is a shorthand for 
	rcu_dereference_check(p, rcu_read_lock_held())

This only deals for pure readers, not potential pure writer :)




^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2010-03-29 20:19 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-03-25 11:06 [PATCH] NETLABEL: Fix an RCU warning David Howells
2010-03-25 11:28 ` Eric Dumazet
2010-03-25 11:37   ` David Howells
2010-03-25 13:32     ` Eric Dumazet
2010-03-25 14:10       ` Paul Moore
2010-03-29 15:24   ` Paul E. McKenney
2010-03-29 15:30     ` Paul Moore
2010-03-29 15:58       ` Paul E. McKenney
2010-03-29 20:05         ` Paul Moore
2010-03-29 20:19           ` Eric Dumazet

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).