aboutsummaryrefslogtreecommitdiffstats
path: root/net/dsa/slave.c
diff options
context:
space:
mode:
authorAndrew Lunn <andrew@lunn.ch>2015-05-05 19:09:56 -0400
committerDavid S. Miller <davem@davemloft.net>2015-05-09 16:05:54 -0400
commit448b4482c6713c5b62828622b7bf46900ff9569b (patch)
tree083fb1fc9545bce1eeb716bfa2963630d5258c11 /net/dsa/slave.c
parent16fe24fc43e8d32b76030c79c151c7db691865f6 (diff)
net: dsa: Add lockdep class to tx queues to avoid lockdep splat
DSA stacks an Ethernet device on top of an Ethernet device. This can cause false positive lockdep splats for the transmit queue: Acked-by: Florian Fainelli <f.fainelli@gmail.com> ============================================= [ INFO: possible recursive locking detected ] 4.0.0-rc7-01838-g70621a215fc7 #386 Not tainted --------------------------------------------- kworker/0:0/4 is trying to acquire lock: (_xmit_ETHER#2){+.-...}, at: [<c040e95c>] sch_direct_xmit+0xa8/0x1fc but task is already holding lock: (_xmit_ETHER#2){+.-...}, at: [<c03f4208>] __dev_queue_xmit+0x4d4/0x56c other info that might help us debug this: Possible unsafe locking scenario: CPU0 ---- lock(_xmit_ETHER#2); lock(_xmit_ETHER#2); To avoid this, walk the tq queues of the dsa slaves and set a lockdep class. Signed-off-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/dsa/slave.c')
-rw-r--r--net/dsa/slave.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 827cda560a55..03e041addea3 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -810,12 +810,19 @@ static int dsa_slave_phy_setup(struct dsa_slave_priv *p,
810 return 0; 810 return 0;
811} 811}
812 812
813static struct lock_class_key dsa_slave_netdev_xmit_lock_key;
814static void dsa_slave_set_lockdep_class_one(struct net_device *dev,
815 struct netdev_queue *txq,
816 void *_unused)
817{
818 lockdep_set_class(&txq->_xmit_lock,
819 &dsa_slave_netdev_xmit_lock_key);
820}
821
813int dsa_slave_suspend(struct net_device *slave_dev) 822int dsa_slave_suspend(struct net_device *slave_dev)
814{ 823{
815 struct dsa_slave_priv *p = netdev_priv(slave_dev); 824 struct dsa_slave_priv *p = netdev_priv(slave_dev);
816 825
817 netif_device_detach(slave_dev);
818
819 if (p->phy) { 826 if (p->phy) {
820 phy_stop(p->phy); 827 phy_stop(p->phy);
821 p->old_pause = -1; 828 p->old_pause = -1;
@@ -861,6 +868,9 @@ int dsa_slave_create(struct dsa_switch *ds, struct device *parent,
861 slave_dev->netdev_ops = &dsa_slave_netdev_ops; 868 slave_dev->netdev_ops = &dsa_slave_netdev_ops;
862 slave_dev->swdev_ops = &dsa_slave_swdev_ops; 869 slave_dev->swdev_ops = &dsa_slave_swdev_ops;
863 870
871 netdev_for_each_tx_queue(slave_dev, dsa_slave_set_lockdep_class_one,
872 NULL);
873
864 SET_NETDEV_DEV(slave_dev, parent); 874 SET_NETDEV_DEV(slave_dev, parent);
865 slave_dev->dev.of_node = ds->pd->port_dn[port]; 875 slave_dev->dev.of_node = ds->pd->port_dn[port];
866 slave_dev->vlan_features = master->vlan_features; 876 slave_dev->vlan_features = master->vlan_features;