public inbox for netdev@vger.kernel.org
 help / color / mirror / Atom feed
From: Hangbin Liu <liuhangbin@gmail.com>
To: Eric Dumazet <edumazet@google.com>
Cc: "David S . Miller" <davem@davemloft.net>,
	Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
	netdev@vger.kernel.org, eric.dumazet@gmail.com,
	syzbot <syzkaller@googlegroups.com>,
	Jay Vosburgh <j.vosburgh@gmail.com>,
	Veaceslav Falico <vfalico@gmail.com>,
	Andy Gospodarek <andy@greyhouse.net>
Subject: Re: [PATCH net] bonding: fix lockdep splat in bond_miimon_commit()
Date: Wed, 21 Dec 2022 11:33:56 +0800	[thread overview]
Message-ID: <Y6J+pOX5hAupkge2@Laptop-X1> (raw)
In-Reply-To: <20221220130831.1480888-1-edumazet@google.com>

On Tue, Dec 20, 2022 at 01:08:31PM +0000, Eric Dumazet wrote:
> bond_miimon_commit() is run while RTNL is held, not RCU.
> 
> WARNING: suspicious RCU usage
> 6.1.0-syzkaller-09671-g89529367293c #0 Not tainted
> -----------------------------
> drivers/net/bonding/bond_main.c:2704 suspicious rcu_dereference_check() usage!
> 
> Fixes: e95cc44763a4 ("bonding: do failover when high prio link up")
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Reported-by: syzbot <syzkaller@googlegroups.com>
> Cc: Hangbin Liu <liuhangbin@gmail.com>
> Cc: Jay Vosburgh <j.vosburgh@gmail.com>
> Cc: Veaceslav Falico <vfalico@gmail.com>
> Cc: Andy Gospodarek <andy@greyhouse.net>
> ---
>  drivers/net/bonding/bond_main.c | 8 +++++---
>  1 file changed, 5 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
> index b4c65783960a5aa14de5d64aeea190f02a04be44..0363ce597661422b82a7d33ef001151b275f9ada 100644
> --- a/drivers/net/bonding/bond_main.c
> +++ b/drivers/net/bonding/bond_main.c
> @@ -2654,10 +2654,12 @@ static void bond_miimon_link_change(struct bonding *bond,
>  
>  static void bond_miimon_commit(struct bonding *bond)
>  {
> -	struct slave *slave, *primary;
> +	struct slave *slave, *primary, *active;
>  	bool do_failover = false;
>  	struct list_head *iter;
>  
> +	ASSERT_RTNL();
> +
>  	bond_for_each_slave(bond, slave, iter) {
>  		switch (slave->link_new_state) {
>  		case BOND_LINK_NOCHANGE:
> @@ -2700,8 +2702,8 @@ static void bond_miimon_commit(struct bonding *bond)
>  
>  			bond_miimon_link_change(bond, slave, BOND_LINK_UP);
>  
> -			if (!rcu_access_pointer(bond->curr_active_slave) || slave == primary ||
> -			    slave->prio > rcu_dereference(bond->curr_active_slave)->prio)
> +			active = rtnl_dereference(bond->curr_active_slave);
> +			if (!active || slave == primary || slave->prio > active->prio)
>  				do_failover = true;

Hi Eric,

Thanks for the fix. I have some silly questions.

Is there an easy way or tool that could find if the functions is holding via
RTNL lock or RCU lock, except review all the call chains? I have faced
this issue in commit 9b80ccda233f ("bonding: fix missed rcu protection"),
which we though the function is under RTNL, while there is a call chain that
not hold rcu lock. Adding ASSERT_RTNL() could find it during running. I just
want to know if there is another way that we could find it in code review.


Another questions is, I'm still a little confused with the mixing usage of
rcu_access_pointer() and rtnl_dereference() under RTNL. e.g.

In bond_miimon_commit() we use rcu_access_pointer() to check the pointers.
                case BOND_LINK_DOWN:
                        if (slave == rcu_access_pointer(bond->curr_active_slave))
                                do_failover = true;

In bond_ab_arp_commit() we use rtnl_dereference() to check the pointer

                case BOND_LINK_DOWN:
                        if (slave == rtnl_dereference(bond->curr_active_slave)) {
                                RCU_INIT_POINTER(bond->current_arp_slave, NULL);
                                do_failover = true;
                        }
                case BOND_LINK_FAIL:
                        if (rtnl_dereference(bond->curr_active_slave))
                                RCU_INIT_POINTER(bond->current_arp_slave, NULL);

Does it matter to use which one? Should we change to rcu_access_pointer()
if there is no dereference?

Thanks
Hangbin

  reply	other threads:[~2022-12-21  3:34 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-12-20 13:08 [PATCH net] bonding: fix lockdep splat in bond_miimon_commit() Eric Dumazet
2022-12-21  3:33 ` Hangbin Liu [this message]
2022-12-22  9:39   ` Paolo Abeni
2022-12-22 10:00 ` patchwork-bot+netdevbpf

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Y6J+pOX5hAupkge2@Laptop-X1 \
    --to=liuhangbin@gmail.com \
    --cc=andy@greyhouse.net \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=eric.dumazet@gmail.com \
    --cc=j.vosburgh@gmail.com \
    --cc=kuba@kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=syzkaller@googlegroups.com \
    --cc=vfalico@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox