lkml.org 
[lkml]   [2012]   [Sep]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[ 008/127] ipv6: addrconf: Avoid calling netdevice notifiers with RCU read-side lock
    Date
    3.0-stable review patch.  If anyone has any objections, please let me know.

    ------------------


    From: Ben Hutchings <bhutchings@solarflare.com>

    [ Upstream commit 4acd4945cd1e1f92b20d14e349c6c6a52acbd42d ]

    Cong Wang reports that lockdep detected suspicious RCU usage while
    enabling IPV6 forwarding:

    [ 1123.310275] ===============================
    [ 1123.442202] [ INFO: suspicious RCU usage. ]
    [ 1123.558207] 3.6.0-rc1+ #109 Not tainted
    [ 1123.665204] -------------------------------
    [ 1123.768254] include/linux/rcupdate.h:430 Illegal context switch in RCU read-side critical section!
    [ 1123.992320]
    [ 1123.992320] other info that might help us debug this:
    [ 1123.992320]
    [ 1124.307382]
    [ 1124.307382] rcu_scheduler_active = 1, debug_locks = 0
    [ 1124.522220] 2 locks held by sysctl/5710:
    [ 1124.648364] #0: (rtnl_mutex){+.+.+.}, at: [<ffffffff81768498>] rtnl_trylock+0x15/0x17
    [ 1124.882211] #1: (rcu_read_lock){.+.+.+}, at: [<ffffffff81871df8>] rcu_lock_acquire+0x0/0x29
    [ 1125.085209]
    [ 1125.085209] stack backtrace:
    [ 1125.332213] Pid: 5710, comm: sysctl Not tainted 3.6.0-rc1+ #109
    [ 1125.441291] Call Trace:
    [ 1125.545281] [<ffffffff8109d915>] lockdep_rcu_suspicious+0x109/0x112
    [ 1125.667212] [<ffffffff8107c240>] rcu_preempt_sleep_check+0x45/0x47
    [ 1125.781838] [<ffffffff8107c260>] __might_sleep+0x1e/0x19b
    [...]
    [ 1127.445223] [<ffffffff81757ac5>] call_netdevice_notifiers+0x4a/0x4f
    [...]
    [ 1127.772188] [<ffffffff8175e125>] dev_disable_lro+0x32/0x6b
    [ 1127.885174] [<ffffffff81872d26>] dev_forward_change+0x30/0xcb
    [ 1128.013214] [<ffffffff818738c4>] addrconf_forward_change+0x85/0xc5
    [...]

    addrconf_forward_change() uses RCU iteration over the netdev list,
    which is unnecessary since it already holds the RTNL lock. We also
    cannot reasonably require netdevice notifier functions not to sleep.

    Reported-by: Cong Wang <amwang@redhat.com>
    Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    net/ipv6/addrconf.c | 4 +---
    1 file changed, 1 insertion(+), 3 deletions(-)

    --- a/net/ipv6/addrconf.c
    +++ b/net/ipv6/addrconf.c
    @@ -492,8 +492,7 @@ static void addrconf_forward_change(stru
    struct net_device *dev;
    struct inet6_dev *idev;

    - rcu_read_lock();
    - for_each_netdev_rcu(net, dev) {
    + for_each_netdev(net, dev) {
    idev = __in6_dev_get(dev);
    if (idev) {
    int changed = (!idev->cnf.forwarding) ^ (!newf);
    @@ -502,7 +501,6 @@ static void addrconf_forward_change(stru
    dev_forward_change(idev);
    }
    }
    - rcu_read_unlock();
    }

    static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int old)



    \
     
     \ /
      Last update: 2012-09-29 00:01    [W:4.363 / U:0.020 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site