aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/bonding/bond_main.c46
-rw-r--r--drivers/net/bonding/bond_sysfs.c8
-rw-r--r--drivers/net/bonding/bonding.h30
3 files changed, 80 insertions, 4 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 813cc2f8edd6..b46cb139477d 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);
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 01b4c3f5d9e7..8fd0174c5380 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -1066,6 +1066,7 @@ static ssize_t bonding_store_primary(struct device *d,
1066 1066
1067 if (!rtnl_trylock()) 1067 if (!rtnl_trylock())
1068 return restart_syscall(); 1068 return restart_syscall();
1069 block_netpoll_tx();
1069 read_lock(&bond->lock); 1070 read_lock(&bond->lock);
1070 write_lock_bh(&bond->curr_slave_lock); 1071 write_lock_bh(&bond->curr_slave_lock);
1071 1072
@@ -1101,6 +1102,7 @@ static ssize_t bonding_store_primary(struct device *d,
1101out: 1102out:
1102 write_unlock_bh(&bond->curr_slave_lock); 1103 write_unlock_bh(&bond->curr_slave_lock);
1103 read_unlock(&bond->lock); 1104 read_unlock(&bond->lock);
1105 unblock_netpoll_tx();
1104 rtnl_unlock(); 1106 rtnl_unlock();
1105 1107
1106 return count; 1108 return count;
@@ -1146,11 +1148,13 @@ static ssize_t bonding_store_primary_reselect(struct device *d,
1146 bond->dev->name, pri_reselect_tbl[new_value].modename, 1148 bond->dev->name, pri_reselect_tbl[new_value].modename,
1147 new_value); 1149 new_value);
1148 1150
1151 block_netpoll_tx();
1149 read_lock(&bond->lock); 1152 read_lock(&bond->lock);
1150 write_lock_bh(&bond->curr_slave_lock); 1153 write_lock_bh(&bond->curr_slave_lock);
1151 bond_select_active_slave(bond); 1154 bond_select_active_slave(bond);
1152 write_unlock_bh(&bond->curr_slave_lock); 1155 write_unlock_bh(&bond->curr_slave_lock);
1153 read_unlock(&bond->lock); 1156 read_unlock(&bond->lock);
1157 unblock_netpoll_tx();
1154out: 1158out:
1155 rtnl_unlock(); 1159 rtnl_unlock();
1156 return ret; 1160 return ret;
@@ -1232,6 +1236,8 @@ static ssize_t bonding_store_active_slave(struct device *d,
1232 1236
1233 if (!rtnl_trylock()) 1237 if (!rtnl_trylock())
1234 return restart_syscall(); 1238 return restart_syscall();
1239
1240 block_netpoll_tx();
1235 read_lock(&bond->lock); 1241 read_lock(&bond->lock);
1236 write_lock_bh(&bond->curr_slave_lock); 1242 write_lock_bh(&bond->curr_slave_lock);
1237 1243
@@ -1288,6 +1294,8 @@ static ssize_t bonding_store_active_slave(struct device *d,
1288 out: 1294 out:
1289 write_unlock_bh(&bond->curr_slave_lock); 1295 write_unlock_bh(&bond->curr_slave_lock);
1290 read_unlock(&bond->lock); 1296 read_unlock(&bond->lock);
1297 unblock_netpoll_tx();
1298
1291 rtnl_unlock(); 1299 rtnl_unlock();
1292 1300
1293 return count; 1301 return count;
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index c15f21347486..2c12a5f812f4 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -19,6 +19,7 @@
19#include <linux/proc_fs.h> 19#include <linux/proc_fs.h>
20#include <linux/if_bonding.h> 20#include <linux/if_bonding.h>
21#include <linux/kobject.h> 21#include <linux/kobject.h>
22#include <linux/cpumask.h>
22#include <linux/in6.h> 23#include <linux/in6.h>
23#include "bond_3ad.h" 24#include "bond_3ad.h"
24#include "bond_alb.h" 25#include "bond_alb.h"
@@ -117,6 +118,35 @@
117 bond_for_each_slave_from(bond, pos, cnt, (bond)->first_slave) 118 bond_for_each_slave_from(bond, pos, cnt, (bond)->first_slave)
118 119
119 120
121#ifdef CONFIG_NET_POLL_CONTROLLER
122extern cpumask_var_t netpoll_block_tx;
123
124static inline void block_netpoll_tx(void)
125{
126 preempt_disable();
127 BUG_ON(cpumask_test_and_set_cpu(smp_processor_id(),
128 netpoll_block_tx));
129}
130
131static inline void unblock_netpoll_tx(void)
132{
133 BUG_ON(!cpumask_test_and_clear_cpu(smp_processor_id(),
134 netpoll_block_tx));
135 preempt_enable();
136}
137
138static inline int is_netpoll_tx_blocked(struct net_device *dev)
139{
140 if (unlikely(dev->priv_flags & IFF_IN_NETPOLL))
141 return cpumask_test_cpu(smp_processor_id(), netpoll_block_tx);
142 return 0;
143}
144#else
145#define block_netpoll_tx()
146#define unblock_netpoll_tx()
147#define is_netpoll_tx_blocked(dev) (0)
148#endif
149
120struct bond_params { 150struct bond_params {
121 int mode; 151 int mode;
122 int xmit_policy; 152 int xmit_policy;