diff options
Diffstat (limited to 'drivers/net/bonding/bond_main.c')
-rw-r--r-- | drivers/net/bonding/bond_main.c | 89 |
1 files changed, 59 insertions, 30 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 7703d35de65d..6b9a7bd8ec14 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 | ||
174 | cpumask_var_t netpoll_block_tx; | ||
175 | #endif | ||
176 | |||
172 | static const char * const version = | 177 | static const char * const version = |
173 | DRV_DESCRIPTION ": v" DRV_VERSION " (" DRV_RELDATE ")\n"; | 178 | DRV_DESCRIPTION ": v" DRV_VERSION " (" DRV_RELDATE ")\n"; |
174 | 179 | ||
@@ -179,9 +184,6 @@ static int arp_ip_count; | |||
179 | static int bond_mode = BOND_MODE_ROUNDROBIN; | 184 | static int bond_mode = BOND_MODE_ROUNDROBIN; |
180 | static int xmit_hashtype = BOND_XMIT_POLICY_LAYER2; | 185 | static int xmit_hashtype = BOND_XMIT_POLICY_LAYER2; |
181 | static int lacp_fast; | 186 | static int lacp_fast; |
182 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
183 | static int disable_netpoll = 1; | ||
184 | #endif | ||
185 | 187 | ||
186 | const struct bond_parm_tbl bond_lacp_tbl[] = { | 188 | const struct bond_parm_tbl bond_lacp_tbl[] = { |
187 | { "slow", AD_LACP_SLOW}, | 189 | { "slow", AD_LACP_SLOW}, |
@@ -310,6 +312,7 @@ static int bond_del_vlan(struct bonding *bond, unsigned short vlan_id) | |||
310 | 312 | ||
311 | pr_debug("bond: %s, vlan id %d\n", bond->dev->name, vlan_id); | 313 | pr_debug("bond: %s, vlan id %d\n", bond->dev->name, vlan_id); |
312 | 314 | ||
315 | block_netpoll_tx(); | ||
313 | write_lock_bh(&bond->lock); | 316 | write_lock_bh(&bond->lock); |
314 | 317 | ||
315 | list_for_each_entry(vlan, &bond->vlan_list, vlan_list) { | 318 | list_for_each_entry(vlan, &bond->vlan_list, vlan_list) { |
@@ -344,6 +347,7 @@ static int bond_del_vlan(struct bonding *bond, unsigned short vlan_id) | |||
344 | 347 | ||
345 | out: | 348 | out: |
346 | write_unlock_bh(&bond->lock); | 349 | write_unlock_bh(&bond->lock); |
350 | unblock_netpoll_tx(); | ||
347 | return res; | 351 | return res; |
348 | } | 352 | } |
349 | 353 | ||
@@ -449,11 +453,9 @@ int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, | |||
449 | if (unlikely(bond->dev->priv_flags & IFF_IN_NETPOLL)) { | 453 | if (unlikely(bond->dev->priv_flags & IFF_IN_NETPOLL)) { |
450 | struct netpoll *np = bond->dev->npinfo->netpoll; | 454 | struct netpoll *np = bond->dev->npinfo->netpoll; |
451 | slave_dev->npinfo = bond->dev->npinfo; | 455 | slave_dev->npinfo = bond->dev->npinfo; |
452 | np->real_dev = np->dev = skb->dev; | ||
453 | slave_dev->priv_flags |= IFF_IN_NETPOLL; | 456 | slave_dev->priv_flags |= IFF_IN_NETPOLL; |
454 | netpoll_send_skb(np, skb); | 457 | netpoll_send_skb_on_dev(np, skb, slave_dev); |
455 | slave_dev->priv_flags &= ~IFF_IN_NETPOLL; | 458 | slave_dev->priv_flags &= ~IFF_IN_NETPOLL; |
456 | np->dev = bond->dev; | ||
457 | } else | 459 | } else |
458 | #endif | 460 | #endif |
459 | dev_queue_xmit(skb); | 461 | dev_queue_xmit(skb); |
@@ -1332,9 +1334,14 @@ static bool slaves_support_netpoll(struct net_device *bond_dev) | |||
1332 | 1334 | ||
1333 | static void bond_poll_controller(struct net_device *bond_dev) | 1335 | static void bond_poll_controller(struct net_device *bond_dev) |
1334 | { | 1336 | { |
1335 | struct net_device *dev = bond_dev->npinfo->netpoll->real_dev; | 1337 | struct bonding *bond = netdev_priv(bond_dev); |
1336 | if (dev != bond_dev) | 1338 | struct slave *slave; |
1337 | netpoll_poll_dev(dev); | 1339 | int i; |
1340 | |||
1341 | bond_for_each_slave(bond, slave, i) { | ||
1342 | if (slave->dev && IS_UP(slave->dev)) | ||
1343 | netpoll_poll_dev(slave->dev); | ||
1344 | } | ||
1338 | } | 1345 | } |
1339 | 1346 | ||
1340 | static void bond_netpoll_cleanup(struct net_device *bond_dev) | 1347 | static void bond_netpoll_cleanup(struct net_device *bond_dev) |
@@ -1801,23 +1808,15 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1801 | bond_set_carrier(bond); | 1808 | bond_set_carrier(bond); |
1802 | 1809 | ||
1803 | #ifdef CONFIG_NET_POLL_CONTROLLER | 1810 | #ifdef CONFIG_NET_POLL_CONTROLLER |
1804 | /* | 1811 | if (slaves_support_netpoll(bond_dev)) { |
1805 | * Netpoll and bonding is broken, make sure it is not initialized | 1812 | bond_dev->priv_flags &= ~IFF_DISABLE_NETPOLL; |
1806 | * until it is fixed. | 1813 | if (bond_dev->npinfo) |
1807 | */ | 1814 | slave_dev->npinfo = bond_dev->npinfo; |
1808 | if (disable_netpoll) { | 1815 | } else if (!(bond_dev->priv_flags & IFF_DISABLE_NETPOLL)) { |
1809 | bond_dev->priv_flags |= IFF_DISABLE_NETPOLL; | 1816 | bond_dev->priv_flags |= IFF_DISABLE_NETPOLL; |
1810 | } else { | 1817 | pr_info("New slave device %s does not support netpoll\n", |
1811 | if (slaves_support_netpoll(bond_dev)) { | 1818 | slave_dev->name); |
1812 | bond_dev->priv_flags &= ~IFF_DISABLE_NETPOLL; | 1819 | pr_info("Disabling netpoll support for %s\n", bond_dev->name); |
1813 | if (bond_dev->npinfo) | ||
1814 | slave_dev->npinfo = bond_dev->npinfo; | ||
1815 | } else if (!(bond_dev->priv_flags & IFF_DISABLE_NETPOLL)) { | ||
1816 | bond_dev->priv_flags |= IFF_DISABLE_NETPOLL; | ||
1817 | pr_info("New slave device %s does not support netpoll\n", | ||
1818 | slave_dev->name); | ||
1819 | pr_info("Disabling netpoll support for %s\n", bond_dev->name); | ||
1820 | } | ||
1821 | } | 1820 | } |
1822 | #endif | 1821 | #endif |
1823 | read_unlock(&bond->lock); | 1822 | read_unlock(&bond->lock); |
@@ -1889,6 +1888,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1889 | return -EINVAL; | 1888 | return -EINVAL; |
1890 | } | 1889 | } |
1891 | 1890 | ||
1891 | block_netpoll_tx(); | ||
1892 | netdev_bonding_change(bond_dev, NETDEV_BONDING_DESLAVE); | 1892 | netdev_bonding_change(bond_dev, NETDEV_BONDING_DESLAVE); |
1893 | write_lock_bh(&bond->lock); | 1893 | write_lock_bh(&bond->lock); |
1894 | 1894 | ||
@@ -1898,6 +1898,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1898 | pr_info("%s: %s not enslaved\n", | 1898 | pr_info("%s: %s not enslaved\n", |
1899 | bond_dev->name, slave_dev->name); | 1899 | bond_dev->name, slave_dev->name); |
1900 | write_unlock_bh(&bond->lock); | 1900 | write_unlock_bh(&bond->lock); |
1901 | unblock_netpoll_tx(); | ||
1901 | return -EINVAL; | 1902 | return -EINVAL; |
1902 | } | 1903 | } |
1903 | 1904 | ||
@@ -1991,6 +1992,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1991 | } | 1992 | } |
1992 | 1993 | ||
1993 | write_unlock_bh(&bond->lock); | 1994 | write_unlock_bh(&bond->lock); |
1995 | unblock_netpoll_tx(); | ||
1994 | 1996 | ||
1995 | /* must do this from outside any spinlocks */ | 1997 | /* must do this from outside any spinlocks */ |
1996 | bond_destroy_slave_symlinks(bond_dev, slave_dev); | 1998 | bond_destroy_slave_symlinks(bond_dev, slave_dev); |
@@ -2021,10 +2023,8 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) | |||
2021 | #ifdef CONFIG_NET_POLL_CONTROLLER | 2023 | #ifdef CONFIG_NET_POLL_CONTROLLER |
2022 | read_lock_bh(&bond->lock); | 2024 | read_lock_bh(&bond->lock); |
2023 | 2025 | ||
2024 | /* Make sure netpoll over stays disabled until fixed. */ | 2026 | if (slaves_support_netpoll(bond_dev)) |
2025 | if (!disable_netpoll) | 2027 | bond_dev->priv_flags &= ~IFF_DISABLE_NETPOLL; |
2026 | if (slaves_support_netpoll(bond_dev)) | ||
2027 | bond_dev->priv_flags &= ~IFF_DISABLE_NETPOLL; | ||
2028 | read_unlock_bh(&bond->lock); | 2028 | read_unlock_bh(&bond->lock); |
2029 | if (slave_dev->netdev_ops->ndo_netpoll_cleanup) | 2029 | if (slave_dev->netdev_ops->ndo_netpoll_cleanup) |
2030 | slave_dev->netdev_ops->ndo_netpoll_cleanup(slave_dev); | 2030 | slave_dev->netdev_ops->ndo_netpoll_cleanup(slave_dev); |
@@ -2180,7 +2180,6 @@ static int bond_release_all(struct net_device *bond_dev) | |||
2180 | 2180 | ||
2181 | out: | 2181 | out: |
2182 | write_unlock_bh(&bond->lock); | 2182 | write_unlock_bh(&bond->lock); |
2183 | |||
2184 | return 0; | 2183 | return 0; |
2185 | } | 2184 | } |
2186 | 2185 | ||
@@ -2229,9 +2228,11 @@ static int bond_ioctl_change_active(struct net_device *bond_dev, struct net_devi | |||
2229 | (old_active) && | 2228 | (old_active) && |
2230 | (new_active->link == BOND_LINK_UP) && | 2229 | (new_active->link == BOND_LINK_UP) && |
2231 | IS_UP(new_active->dev)) { | 2230 | IS_UP(new_active->dev)) { |
2231 | block_netpoll_tx(); | ||
2232 | write_lock_bh(&bond->curr_slave_lock); | 2232 | write_lock_bh(&bond->curr_slave_lock); |
2233 | bond_change_active_slave(bond, new_active); | 2233 | bond_change_active_slave(bond, new_active); |
2234 | write_unlock_bh(&bond->curr_slave_lock); | 2234 | write_unlock_bh(&bond->curr_slave_lock); |
2235 | unblock_netpoll_tx(); | ||
2235 | } else | 2236 | } else |
2236 | res = -EINVAL; | 2237 | res = -EINVAL; |
2237 | 2238 | ||
@@ -2463,9 +2464,11 @@ static void bond_miimon_commit(struct bonding *bond) | |||
2463 | 2464 | ||
2464 | do_failover: | 2465 | do_failover: |
2465 | ASSERT_RTNL(); | 2466 | ASSERT_RTNL(); |
2467 | block_netpoll_tx(); | ||
2466 | write_lock_bh(&bond->curr_slave_lock); | 2468 | write_lock_bh(&bond->curr_slave_lock); |
2467 | bond_select_active_slave(bond); | 2469 | bond_select_active_slave(bond); |
2468 | write_unlock_bh(&bond->curr_slave_lock); | 2470 | write_unlock_bh(&bond->curr_slave_lock); |
2471 | unblock_netpoll_tx(); | ||
2469 | } | 2472 | } |
2470 | 2473 | ||
2471 | bond_set_carrier(bond); | 2474 | bond_set_carrier(bond); |
@@ -2908,11 +2911,13 @@ void bond_loadbalance_arp_mon(struct work_struct *work) | |||
2908 | } | 2911 | } |
2909 | 2912 | ||
2910 | if (do_failover) { | 2913 | if (do_failover) { |
2914 | block_netpoll_tx(); | ||
2911 | write_lock_bh(&bond->curr_slave_lock); | 2915 | write_lock_bh(&bond->curr_slave_lock); |
2912 | 2916 | ||
2913 | bond_select_active_slave(bond); | 2917 | bond_select_active_slave(bond); |
2914 | 2918 | ||
2915 | write_unlock_bh(&bond->curr_slave_lock); | 2919 | write_unlock_bh(&bond->curr_slave_lock); |
2920 | unblock_netpoll_tx(); | ||
2916 | } | 2921 | } |
2917 | 2922 | ||
2918 | re_arm: | 2923 | re_arm: |
@@ -3071,9 +3076,11 @@ static void bond_ab_arp_commit(struct bonding *bond, int delta_in_ticks) | |||
3071 | 3076 | ||
3072 | do_failover: | 3077 | do_failover: |
3073 | ASSERT_RTNL(); | 3078 | ASSERT_RTNL(); |
3079 | block_netpoll_tx(); | ||
3074 | write_lock_bh(&bond->curr_slave_lock); | 3080 | write_lock_bh(&bond->curr_slave_lock); |
3075 | bond_select_active_slave(bond); | 3081 | bond_select_active_slave(bond); |
3076 | write_unlock_bh(&bond->curr_slave_lock); | 3082 | write_unlock_bh(&bond->curr_slave_lock); |
3083 | unblock_netpoll_tx(); | ||
3077 | } | 3084 | } |
3078 | 3085 | ||
3079 | bond_set_carrier(bond); | 3086 | bond_set_carrier(bond); |
@@ -4561,6 +4568,13 @@ static netdev_tx_t bond_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
4561 | { | 4568 | { |
4562 | struct bonding *bond = netdev_priv(dev); | 4569 | struct bonding *bond = netdev_priv(dev); |
4563 | 4570 | ||
4571 | /* | ||
4572 | * If we risk deadlock from transmitting this in the | ||
4573 | * netpoll path, tell netpoll to queue the frame for later tx | ||
4574 | */ | ||
4575 | if (is_netpoll_tx_blocked(dev)) | ||
4576 | return NETDEV_TX_BUSY; | ||
4577 | |||
4564 | if (TX_QUEUE_OVERRIDE(bond->params.mode)) { | 4578 | if (TX_QUEUE_OVERRIDE(bond->params.mode)) { |
4565 | if (!bond_slave_override(bond, skb)) | 4579 | if (!bond_slave_override(bond, skb)) |
4566 | return NETDEV_TX_OK; | 4580 | return NETDEV_TX_OK; |
@@ -5283,6 +5297,13 @@ static int __init bonding_init(void) | |||
5283 | if (res) | 5297 | if (res) |
5284 | goto out; | 5298 | goto out; |
5285 | 5299 | ||
5300 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
5301 | if (!alloc_cpumask_var(&netpoll_block_tx, GFP_KERNEL)) { | ||
5302 | res = -ENOMEM; | ||
5303 | goto out; | ||
5304 | } | ||
5305 | #endif | ||
5306 | |||
5286 | res = register_pernet_subsys(&bond_net_ops); | 5307 | res = register_pernet_subsys(&bond_net_ops); |
5287 | if (res) | 5308 | if (res) |
5288 | goto out; | 5309 | goto out; |
@@ -5301,6 +5322,7 @@ static int __init bonding_init(void) | |||
5301 | if (res) | 5322 | if (res) |
5302 | goto err; | 5323 | goto err; |
5303 | 5324 | ||
5325 | |||
5304 | register_netdevice_notifier(&bond_netdev_notifier); | 5326 | register_netdevice_notifier(&bond_netdev_notifier); |
5305 | register_inetaddr_notifier(&bond_inetaddr_notifier); | 5327 | register_inetaddr_notifier(&bond_inetaddr_notifier); |
5306 | bond_register_ipv6_notifier(); | 5328 | bond_register_ipv6_notifier(); |
@@ -5310,6 +5332,9 @@ err: | |||
5310 | rtnl_link_unregister(&bond_link_ops); | 5332 | rtnl_link_unregister(&bond_link_ops); |
5311 | err_link: | 5333 | err_link: |
5312 | unregister_pernet_subsys(&bond_net_ops); | 5334 | unregister_pernet_subsys(&bond_net_ops); |
5335 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
5336 | free_cpumask_var(netpoll_block_tx); | ||
5337 | #endif | ||
5313 | goto out; | 5338 | goto out; |
5314 | 5339 | ||
5315 | } | 5340 | } |
@@ -5324,6 +5349,10 @@ static void __exit bonding_exit(void) | |||
5324 | 5349 | ||
5325 | rtnl_link_unregister(&bond_link_ops); | 5350 | rtnl_link_unregister(&bond_link_ops); |
5326 | unregister_pernet_subsys(&bond_net_ops); | 5351 | unregister_pernet_subsys(&bond_net_ops); |
5352 | |||
5353 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
5354 | free_cpumask_var(netpoll_block_tx); | ||
5355 | #endif | ||
5327 | } | 5356 | } |
5328 | 5357 | ||
5329 | module_init(bonding_init); | 5358 | module_init(bonding_init); |