Message ID | 1440782540-7876-1-git-send-email-razor@blackwall.org |
---|---|
State | Changes Requested, archived |
Delegated to: | David Miller |
Headers | show |
From: Nikolay Aleksandrov <razor@blackwall.org> Date: Fri, 28 Aug 2015 10:22:20 -0700 > The problem is rcu_read_unlock_bh() which triggers a warning when > irqs are disabled. ndo_poll_controller can run with bh enabled, > disabled or irqs disabled so check if that is the case and acquire > rcu_read_lock_bh only when not running with disabled irqs. I would say that having hard irqs disabled is a strict requirement, as per the debugging test in netpoll_send_skb_on_dev(): WARN_ON_ONCE(!irqs_disabled()); If you want to add the same check to netpoll_send_udp(), that's fine. But what isn't fine is adding all of this conditional locking, we want ->poll_controller() implementations to be able to depend upon the IRQ environment they execute in, otherwise every single implementation might need to have ugly conditional locking as well. -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
> On Aug 28, 2015, at 2:13 PM, David Miller <davem@davemloft.net> wrote: > > From: Nikolay Aleksandrov <razor@blackwall.org> > Date: Fri, 28 Aug 2015 10:22:20 -0700 > >> The problem is rcu_read_unlock_bh() which triggers a warning when >> irqs are disabled. ndo_poll_controller can run with bh enabled, >> disabled or irqs disabled so check if that is the case and acquire >> rcu_read_lock_bh only when not running with disabled irqs. > > I would say that having hard irqs disabled is a strict requirement, as > per the debugging test in netpoll_send_skb_on_dev(): > > WARN_ON_ONCE(!irqs_disabled()); > > If you want to add the same check to netpoll_send_udp(), that's fine. > > But what isn't fine is adding all of this conditional locking, we want > ->poll_controller() implementations to be able to depend upon the IRQ > environment they execute in, otherwise every single implementation > might need to have ugly conditional locking as well. Great, that is what I wanted to know because I got confused by some older commits. This will simplify the fix and I will add the warn_on in netpoll_send_udp(). v3 coming up Thank you, Nik-- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index a98dd4f1b0e3..3197a2180978 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -974,12 +974,17 @@ static void bond_poll_controller(struct net_device *bond_dev) struct ad_info ad_info; struct netpoll_info *ni; const struct net_device_ops *ops; + bool rcubh_taken = false; if (BOND_MODE(bond) == BOND_MODE_8023AD) if (bond_3ad_get_active_agg_info(bond, &ad_info)) return; - rcu_read_lock_bh(); + if (!in_irq() && !irqs_disabled()) { + rcu_read_lock_bh(); + rcubh_taken = true; + } + rcu_read_lock(); bond_for_each_slave_rcu(bond, slave, iter) { ops = slave->dev->netdev_ops; if (!bond_slave_is_up(slave) || !ops->ndo_poll_controller) @@ -1000,7 +1005,9 @@ static void bond_poll_controller(struct net_device *bond_dev) ops->ndo_poll_controller(slave->dev); up(&ni->dev_lock); } - rcu_read_unlock_bh(); + rcu_read_unlock(); + if (rcubh_taken) + rcu_read_unlock_bh(); } static void bond_netpoll_cleanup(struct net_device *bond_dev)