aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bonding/bond_main.c
diff options
context:
space:
mode:
authorNeil Horman <nhorman@tuxdriver.com>2010-10-13 12:01:50 -0400
committerDavid S. Miller <davem@davemloft.net>2010-10-18 11:32:07 -0400
commite843fa50887582c867d8b7995f81fe9c1a076806 (patch)
tree5a8e34f5afaeeed539d519b0e91b7a4c92268b11 /drivers/net/bonding/bond_main.c
parentc2355e1ab910278a94d487b78590ee3c8eecd08a (diff)
bonding: Fix deadlock in bonding driver resulting from internal locking when using netpoll
The monitoring paths in the bonding driver take write locks that are shared by the tx path. If netconsole is in use, these paths can call printk which puts us in the netpoll tx path, which, if netconsole is attached to the bonding driver, result in deadlock (the xmit_lock guards are useless in netpoll_send_skb, as the monitor paths in the bonding driver don't claim the xmit_lock, nor should they). The solution is to use a per cpu flag internal to the driver to indicate when a cpu is holding the lock in a path that might recusrse into the tx path for the driver via netconsole. By checking this flag on transmit, we can defer the sending of the netconsole frames until a later time using the retransmit feature of netpoll_send_skb that is triggered on the return code NETDEV_TX_BUSY. I've tested this and am able to transmit via netconsole while causing failover conditions on the bond slave links. Signed-off-by: Neil Horman <nhorman@tuxdriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bonding/bond_main.c')
-rw-r--r--drivers/net/bonding/bond_main.c46
1 files changed, 42 insertions, 4 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 813cc2f8edd..b46cb139477 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -76,6 +76,7 @@
76#include <linux/if_vlan.h> 76#include <linux/if_vlan.h>
77#include <linux/if_bonding.h> 77#include <linux/if_bonding.h>
78#include <linux/jiffies.h> 78#include <linux/jiffies.h>
79#include <linux/preempt.h>
79#include <net/route.h> 80#include <net/route.h>
80#include <net/net_namespace.h> 81#include <net/net_namespace.h>
81#include <net/netns/generic.h> 82#include <net/netns/generic.h>
@@ -169,6 +170,10 @@ MODULE_PARM_DESC(resend_igmp, "Number of IGMP membership reports to send on link
169 170
170/*----------------------------- Global variables ----------------------------*/ 171/*----------------------------- Global variables ----------------------------*/
171 172
173#ifdef CONFIG_NET_POLL_CONTROLLER
174cpumask_var_t netpoll_block_tx;
175#endif
176
172static const char * const version = 177static const char * const version =
173 DRV_DESCRIPTION ": v" DRV_VERSION " (" DRV_RELDATE ")\n"; 178 DRV_DESCRIPTION ": v" DRV_VERSION " (" DRV_RELDATE ")\n";
174 179
@@ -310,6 +315,7 @@ static int bond_del_vlan(struct bonding *bond, unsigned short vlan_id)
310 315
311 pr_debug("bond: %s, vlan id %d\n", bond->dev->name, vlan_id); 316 pr_debug("bond: %s, vlan id %d\n", bond->dev->name, vlan_id);
312 317
318 block_netpoll_tx();
313 write_lock_bh(&bond->lock); 319 write_lock_bh(&bond->lock);
314 320
315 list_for_each_entry(vlan, &bond->vlan_list, vlan_list) { 321 list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
@@ -344,6 +350,7 @@ static int bond_del_vlan(struct bonding *bond, unsigned short vlan_id)
344 350
345out: 351out:
346 write_unlock_bh(&bond->lock); 352 write_unlock_bh(&bond->lock);
353 unblock_netpoll_tx();
347 return res; 354 return res;
348} 355}
349 356
@@ -1804,10 +1811,6 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
1804 bond_set_carrier(bond); 1811 bond_set_carrier(bond);
1805 1812
1806#ifdef CONFIG_NET_POLL_CONTROLLER 1813#ifdef CONFIG_NET_POLL_CONTROLLER
1807 /*
1808 * Netpoll and bonding is broken, make sure it is not initialized
1809 * until it is fixed.
1810 */
1811 if (disable_netpoll) { 1814 if (disable_netpoll) {
1812 bond_dev->priv_flags |= IFF_DISABLE_NETPOLL; 1815 bond_dev->priv_flags |= IFF_DISABLE_NETPOLL;
1813 } else { 1816 } else {
@@ -1892,6 +1895,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
1892 return -EINVAL; 1895 return -EINVAL;
1893 } 1896 }
1894 1897
1898 block_netpoll_tx();
1895 netdev_bonding_change(bond_dev, NETDEV_BONDING_DESLAVE); 1899 netdev_bonding_change(bond_dev, NETDEV_BONDING_DESLAVE);
1896 write_lock_bh(&bond->lock); 1900 write_lock_bh(&bond->lock);
1897 1901
@@ -1901,6 +1905,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
1901 pr_info("%s: %s not enslaved\n", 1905 pr_info("%s: %s not enslaved\n",
1902 bond_dev->name, slave_dev->name); 1906 bond_dev->name, slave_dev->name);
1903 write_unlock_bh(&bond->lock); 1907 write_unlock_bh(&bond->lock);
1908 unblock_netpoll_tx();
1904 return -EINVAL; 1909 return -EINVAL;
1905 } 1910 }
1906 1911
@@ -1994,6 +1999,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
1994 } 1999 }
1995 2000
1996 write_unlock_bh(&bond->lock); 2001 write_unlock_bh(&bond->lock);
2002 unblock_netpoll_tx();
1997 2003
1998 /* must do this from outside any spinlocks */ 2004 /* must do this from outside any spinlocks */
1999 bond_destroy_slave_symlinks(bond_dev, slave_dev); 2005 bond_destroy_slave_symlinks(bond_dev, slave_dev);
@@ -2085,6 +2091,7 @@ static int bond_release_all(struct net_device *bond_dev)
2085 struct net_device *slave_dev; 2091 struct net_device *slave_dev;
2086 struct sockaddr addr; 2092 struct sockaddr addr;
2087 2093
2094 block_netpoll_tx();
2088 write_lock_bh(&bond->lock); 2095 write_lock_bh(&bond->lock);
2089 2096
2090 netif_carrier_off(bond_dev); 2097 netif_carrier_off(bond_dev);
@@ -2183,6 +2190,7 @@ static int bond_release_all(struct net_device *bond_dev)
2183 2190
2184out: 2191out:
2185 write_unlock_bh(&bond->lock); 2192 write_unlock_bh(&bond->lock);
2193 unblock_netpoll_tx();
2186 2194
2187 return 0; 2195 return 0;
2188} 2196}
@@ -2232,9 +2240,11 @@ static int bond_ioctl_change_active(struct net_device *bond_dev, struct net_devi
2232 (old_active) && 2240 (old_active) &&
2233 (new_active->link == BOND_LINK_UP) && 2241 (new_active->link == BOND_LINK_UP) &&
2234 IS_UP(new_active->dev)) { 2242 IS_UP(new_active->dev)) {
2243 block_netpoll_tx();
2235 write_lock_bh(&bond->curr_slave_lock); 2244 write_lock_bh(&bond->curr_slave_lock);
2236 bond_change_active_slave(bond, new_active); 2245 bond_change_active_slave(bond, new_active);
2237 write_unlock_bh(&bond->curr_slave_lock); 2246 write_unlock_bh(&bond->curr_slave_lock);
2247 unblock_netpoll_tx();
2238 } else 2248 } else
2239 res = -EINVAL; 2249 res = -EINVAL;
2240 2250
@@ -2466,9 +2476,11 @@ static void bond_miimon_commit(struct bonding *bond)
2466 2476
2467do_failover: 2477do_failover:
2468 ASSERT_RTNL(); 2478 ASSERT_RTNL();
2479 block_netpoll_tx();
2469 write_lock_bh(&bond->curr_slave_lock); 2480 write_lock_bh(&bond->curr_slave_lock);
2470 bond_select_active_slave(bond); 2481 bond_select_active_slave(bond);
2471 write_unlock_bh(&bond->curr_slave_lock); 2482 write_unlock_bh(&bond->curr_slave_lock);
2483 unblock_netpoll_tx();
2472 } 2484 }
2473 2485
2474 bond_set_carrier(bond); 2486 bond_set_carrier(bond);
@@ -2911,11 +2923,13 @@ void bond_loadbalance_arp_mon(struct work_struct *work)
2911 } 2923 }
2912 2924
2913 if (do_failover) { 2925 if (do_failover) {
2926 block_netpoll_tx();
2914 write_lock_bh(&bond->curr_slave_lock); 2927 write_lock_bh(&bond->curr_slave_lock);
2915 2928
2916 bond_select_active_slave(bond); 2929 bond_select_active_slave(bond);
2917 2930
2918 write_unlock_bh(&bond->curr_slave_lock); 2931 write_unlock_bh(&bond->curr_slave_lock);
2932 unblock_netpoll_tx();
2919 } 2933 }
2920 2934
2921re_arm: 2935re_arm:
@@ -3074,9 +3088,11 @@ static void bond_ab_arp_commit(struct bonding *bond, int delta_in_ticks)
3074 3088
3075do_failover: 3089do_failover:
3076 ASSERT_RTNL(); 3090 ASSERT_RTNL();
3091 block_netpoll_tx();
3077 write_lock_bh(&bond->curr_slave_lock); 3092 write_lock_bh(&bond->curr_slave_lock);
3078 bond_select_active_slave(bond); 3093 bond_select_active_slave(bond);
3079 write_unlock_bh(&bond->curr_slave_lock); 3094 write_unlock_bh(&bond->curr_slave_lock);
3095 unblock_netpoll_tx();
3080 } 3096 }
3081 3097
3082 bond_set_carrier(bond); 3098 bond_set_carrier(bond);
@@ -4564,6 +4580,13 @@ static netdev_tx_t bond_start_xmit(struct sk_buff *skb, struct net_device *dev)
4564{ 4580{
4565 struct bonding *bond = netdev_priv(dev); 4581 struct bonding *bond = netdev_priv(dev);
4566 4582
4583 /*
4584 * If we risk deadlock from transmitting this in the
4585 * netpoll path, tell netpoll to queue the frame for later tx
4586 */
4587 if (is_netpoll_tx_blocked(dev))
4588 return NETDEV_TX_BUSY;
4589
4567 if (TX_QUEUE_OVERRIDE(bond->params.mode)) { 4590 if (TX_QUEUE_OVERRIDE(bond->params.mode)) {
4568 if (!bond_slave_override(bond, skb)) 4591 if (!bond_slave_override(bond, skb))
4569 return NETDEV_TX_OK; 4592 return NETDEV_TX_OK;
@@ -5286,6 +5309,13 @@ static int __init bonding_init(void)
5286 if (res) 5309 if (res)
5287 goto out; 5310 goto out;
5288 5311
5312#ifdef CONFIG_NET_POLL_CONTROLLER
5313 if (!alloc_cpumask_var(&netpoll_block_tx, GFP_KERNEL)) {
5314 res = -ENOMEM;
5315 goto out;
5316 }
5317#endif
5318
5289 res = register_pernet_subsys(&bond_net_ops); 5319 res = register_pernet_subsys(&bond_net_ops);
5290 if (res) 5320 if (res)
5291 goto out; 5321 goto out;
@@ -5304,6 +5334,7 @@ static int __init bonding_init(void)
5304 if (res) 5334 if (res)
5305 goto err; 5335 goto err;
5306 5336
5337
5307 register_netdevice_notifier(&bond_netdev_notifier); 5338 register_netdevice_notifier(&bond_netdev_notifier);
5308 register_inetaddr_notifier(&bond_inetaddr_notifier); 5339 register_inetaddr_notifier(&bond_inetaddr_notifier);
5309 bond_register_ipv6_notifier(); 5340 bond_register_ipv6_notifier();
@@ -5313,6 +5344,9 @@ err:
5313 rtnl_link_unregister(&bond_link_ops); 5344 rtnl_link_unregister(&bond_link_ops);
5314err_link: 5345err_link:
5315 unregister_pernet_subsys(&bond_net_ops); 5346 unregister_pernet_subsys(&bond_net_ops);
5347#ifdef CONFIG_NET_POLL_CONTROLLER
5348 free_cpumask_var(netpoll_block_tx);
5349#endif
5316 goto out; 5350 goto out;
5317 5351
5318} 5352}
@@ -5327,6 +5361,10 @@ static void __exit bonding_exit(void)
5327 5361
5328 rtnl_link_unregister(&bond_link_ops); 5362 rtnl_link_unregister(&bond_link_ops);
5329 unregister_pernet_subsys(&bond_net_ops); 5363 unregister_pernet_subsys(&bond_net_ops);
5364
5365#ifdef CONFIG_NET_POLL_CONTROLLER
5366 free_cpumask_var(netpoll_block_tx);
5367#endif
5330} 5368}
5331 5369
5332module_init(bonding_init); 5370module_init(bonding_init);