diff options
Diffstat (limited to 'drivers/net/bonding/bond_main.c')
-rw-r--r-- | drivers/net/bonding/bond_main.c | 58 |
1 files changed, 38 insertions, 20 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index a11748b8d69b..2c5ed0a7cb18 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1811,7 +1811,7 @@ void bond_xdp_set_features(struct net_device *bond_dev) ASSERT_RTNL(); - if (!bond_xdp_check(bond)) { + if (!bond_xdp_check(bond) || !bond_has_slaves(bond)) { xdp_clear_features_flag(bond_dev); return; } @@ -2611,7 +2611,7 @@ static int bond_miimon_inspect(struct bonding *bond) bond_propose_link_state(slave, BOND_LINK_FAIL); commit++; slave->delay = bond->params.downdelay; - if (slave->delay) { + if (slave->delay && net_ratelimit()) { slave_info(bond->dev, slave->dev, "link status down for %sinterface, disabling it in %d ms\n", (BOND_MODE(bond) == BOND_MODE_ACTIVEBACKUP) ? @@ -2625,9 +2625,10 @@ static int bond_miimon_inspect(struct bonding *bond) /* recovered before downdelay expired */ bond_propose_link_state(slave, BOND_LINK_UP); slave->last_link_up = jiffies; - slave_info(bond->dev, slave->dev, "link status up again after %d ms\n", - (bond->params.downdelay - slave->delay) * - bond->params.miimon); + if (net_ratelimit()) + slave_info(bond->dev, slave->dev, "link status up again after %d ms\n", + (bond->params.downdelay - slave->delay) * + bond->params.miimon); commit++; continue; } @@ -2649,7 +2650,7 @@ static int bond_miimon_inspect(struct bonding *bond) commit++; slave->delay = bond->params.updelay; - if (slave->delay) { + if (slave->delay && net_ratelimit()) { slave_info(bond->dev, slave->dev, "link status up, enabling it in %d ms\n", ignore_updelay ? 0 : bond->params.updelay * @@ -2659,9 +2660,10 @@ static int bond_miimon_inspect(struct bonding *bond) case BOND_LINK_BACK: if (!link_state) { bond_propose_link_state(slave, BOND_LINK_DOWN); - slave_info(bond->dev, slave->dev, "link status down again after %d ms\n", - (bond->params.updelay - slave->delay) * - bond->params.miimon); + if (net_ratelimit()) + slave_info(bond->dev, slave->dev, "link status down again after %d ms\n", + (bond->params.updelay - slave->delay) * + bond->params.miimon); commit++; continue; } @@ -6305,6 +6307,7 @@ static int __init bond_check_params(struct bond_params *params) params->ad_actor_sys_prio = ad_actor_sys_prio; eth_zero_addr(params->ad_actor_system); params->ad_user_port_key = ad_user_port_key; + params->coupled_control = 1; if (packets_per_slave > 0) { params->reciprocal_packets_per_slave = reciprocal_value(packets_per_slave); @@ -6414,28 +6417,41 @@ static int __net_init bond_net_init(struct net *net) return 0; } -static void __net_exit bond_net_exit_batch(struct list_head *net_list) +/* According to commit 69b0216ac255 ("bonding: fix bonding_masters + * race condition in bond unloading") we need to remove sysfs files + * before we remove our devices (done later in bond_net_exit_batch_rtnl()) + */ +static void __net_exit bond_net_pre_exit(struct net *net) +{ + struct bond_net *bn = net_generic(net, bond_net_id); + + bond_destroy_sysfs(bn); +} + +static void __net_exit bond_net_exit_batch_rtnl(struct list_head *net_list, + struct list_head *dev_kill_list) { struct bond_net *bn; struct net *net; - LIST_HEAD(list); - - list_for_each_entry(net, net_list, exit_list) { - bn = net_generic(net, bond_net_id); - bond_destroy_sysfs(bn); - } /* Kill off any bonds created after unregistering bond rtnl ops */ - rtnl_lock(); list_for_each_entry(net, net_list, exit_list) { struct bonding *bond, *tmp_bond; bn = net_generic(net, bond_net_id); list_for_each_entry_safe(bond, tmp_bond, &bn->dev_list, bond_list) - unregister_netdevice_queue(bond->dev, &list); + unregister_netdevice_queue(bond->dev, dev_kill_list); } - unregister_netdevice_many(&list); - rtnl_unlock(); +} + +/* According to commit 23fa5c2caae0 ("bonding: destroy proc directory + * only after all bonds are gone") bond_destroy_proc_dir() is called + * after bond_net_exit_batch_rtnl() has completed. + */ +static void __net_exit bond_net_exit_batch(struct list_head *net_list) +{ + struct bond_net *bn; + struct net *net; list_for_each_entry(net, net_list, exit_list) { bn = net_generic(net, bond_net_id); @@ -6445,6 +6461,8 @@ static void __net_exit bond_net_exit_batch(struct list_head *net_list) static struct pernet_operations bond_net_ops = { .init = bond_net_init, + .pre_exit = bond_net_pre_exit, + .exit_batch_rtnl = bond_net_exit_batch_rtnl, .exit_batch = bond_net_exit_batch, .id = &bond_net_id, .size = sizeof(struct bond_net), |