• Taehee Yoo's avatar
    mld: fix suspicious RCU usage in __ipv6_dev_mc_dec() · aa8caa76
    Taehee Yoo authored
    __ipv6_dev_mc_dec() internally uses sleepable functions so that caller
    must not acquire atomic locks. But caller, which is addrconf_verify_rtnl()
    acquires rcu_read_lock_bh().
    So this warning occurs in the __ipv6_dev_mc_dec().
    
    Test commands:
        ip netns add A
        ip link add veth0 type veth peer name veth1
        ip link set veth1 netns A
        ip link set veth0 up
        ip netns exec A ip link set veth1 up
        ip a a 2001:db8::1/64 dev veth0 valid_lft 2 preferred_lft 1
    
    Splat looks like:
    ============================
    WARNING: suspicious RCU usage
    5.12.0-rc6+ #515 Not tainted
    -----------------------------
    kernel/sched/core.c:8294 Illegal context switch in RCU-bh read-side
    critical section!
    
    other info that might help us debug this:
    
    rcu_scheduler_active = 2, debug_locks = 1
    4 locks held by kworker/4:0/1997:
     #0: ffff88810bd72d48 ((wq_completion)ipv6_addrconf){+.+.}-{0:0}, at:
    process_one_work+0x761/0x1440
     #1: ffff888105c8fe00 ((addr_chk_work).work){+.+.}-{0:0}, at:
    process_one_work+0x795/0x1440
     #2: ffffffffb9279fb0 (rtnl_mutex){+.+.}-{3:3}, at:
    addrconf_verify_work+0xa/0x20
     #3: ffffffffb8e30860 (rcu_read_lock_bh){....}-{1:2}, at:
    addrconf_verify_rtnl+0x23/0xc60
    
    stack backtrace:
    CPU: 4 PID: 1997 Comm: kworker/4:0 Not tainted 5.12.0-rc6+ #515
    Workqueue: ipv6_addrconf addrconf_verify_work
    Call Trace:
     dump_stack+0xa4/0xe5
     ___might_sleep+0x27d/0x2b0
     __mutex_lock+0xc8/0x13f0
     ? lock_downgrade+0x690/0x690
     ? __ipv6_dev_mc_dec+0x49/0x2a0
     ? mark_held_locks+0xb7/0x120
     ? mutex_lock_io_nested+0x1270/0x1270
     ? lockdep_hardirqs_on_prepare+0x12c/0x3e0
     ? _raw_spin_unlock_irqrestore+0x47/0x50
     ? trace_hardirqs_on+0x41/0x120
     ? __wake_up_common_lock+0xc9/0x100
     ? __wake_up_common+0x620/0x620
     ? memset+0x1f/0x40
     ? netlink_broadcast_filtered+0x2c4/0xa70
     ? __ipv6_dev_mc_dec+0x49/0x2a0
     __ipv6_dev_mc_dec+0x49/0x2a0
     ? netlink_broadcast_filtered+0x2f6/0xa70
     addrconf_leave_solict.part.64+0xad/0xf0
     ? addrconf_join_solict.part.63+0xf0/0xf0
     ? nlmsg_notify+0x63/0x1b0
     __ipv6_ifa_notify+0x22c/0x9c0
     ? inet6_fill_ifaddr+0xbe0/0xbe0
     ? lockdep_hardirqs_on_prepare+0x12c/0x3e0
     ? __local_bh_enable_ip+0xa5/0xf0
     ? ipv6_del_addr+0x347/0x870
     ipv6_del_addr+0x3b1/0x870
     ? addrconf_ifdown+0xfe0/0xfe0
     ? rcu_read_lock_any_held.part.27+0x20/0x20
     addrconf_verify_rtnl+0x8a9/0xc60
     addrconf_verify_work+0xf/0x20
     process_one_work+0x84c/0x1440
    
    In order to avoid this problem, it uses rcu_read_unlock_bh() for
    a short time. RCU is used for avoiding freeing
    ifp(struct *inet6_ifaddr) while ifp is being used. But this will
    not be released even if rcu_read_unlock_bh() is used.
    Because before rcu_read_unlock_bh(), it uses in6_ifa_hold(ifp).
    So this is safe.
    
    Fixes: 63ed8de4 ("mld: add mc_lock for protecting per-interface mld data")
    Suggested-by: default avatarEric Dumazet <edumazet@google.com>
    Reported-by: default avatarEric Dumazet <edumazet@google.com>
    Signed-off-by: default avatarTaehee Yoo <ap420073@gmail.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    aa8caa76
addrconf.c 176 KB