Skip to content

Commit c5b8b34

Browse files
committed
Merge branch 'bonding-team-offload'
Jiri Pirko says: ==================== bonding/team offload + mlxsw implementation This patchset introduces needed infrastructure for link aggregation offload - for both team and bonding. It also implements the offload in mlxsw driver. Particulary, this patchset introduces possibility for upper driver (bond/team/bridge/..) to pass type-specific info down to notifier listeners. Info is passed along with NETDEV_CHANGEUPPER/NETDEV_PRECHANGEUPPER notifiers. Listeners (drivers of netdevs being enslaved) can react accordingly. Other extension is for run-time use. This patchset introduces new netdev notifier type - NETDEV_CHANGELOWERSTATE. Along with this notification, the upper driver (bond/team/bridge/..) can pass some information about lower device change, particulary link-up and TX-enabled states. Listeners (drivers of netdevs being enslaved) can react accordingly. The last part of the patchset is implementation of LAG offload in mlxsw, using both previously introduced infrastructre extensions. Note that bond-speficic (and ugly) NETDEV_BONDING_INFO used by mlx4 can be removed and mlx4 can use the extensions this patchset adds. I plan to convert it and get rid of NETDEV_BONDING_INFO in a follow-up patchset. v2->v3: - one small fix in patch 1 v1->v2: - added patch 1 and 2 per Andy's request - couple of more or less cosmetic changes described in couple other patches ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents 3b19584 + 7458120 commit c5b8b34

File tree

26 files changed

+1288
-147
lines changed

26 files changed

+1288
-147
lines changed

Documentation/fault-injection/notifier-error-inject.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ Netdevice notifier events which can be failed are:
103103
* NETDEV_POST_INIT
104104
* NETDEV_PRECHANGEMTU
105105
* NETDEV_PRECHANGEUPPER
106+
* NETDEV_CHANGEUPPER
106107

107108
Example: Inject netdevice mtu change error (-22 == -EINVAL)
108109

drivers/net/bonding/bond_3ad.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,8 @@ enum ad_link_speed_type {
9393
AD_LINK_SPEED_10000MBPS,
9494
AD_LINK_SPEED_20000MBPS,
9595
AD_LINK_SPEED_40000MBPS,
96-
AD_LINK_SPEED_56000MBPS
96+
AD_LINK_SPEED_56000MBPS,
97+
AD_LINK_SPEED_100000MBPS,
9798
};
9899

99100
/* compare MAC addresses */
@@ -258,6 +259,7 @@ static inline int __check_agg_selection_timer(struct port *port)
258259
* %AD_LINK_SPEED_20000MBPS
259260
* %AD_LINK_SPEED_40000MBPS
260261
* %AD_LINK_SPEED_56000MBPS
262+
* %AD_LINK_SPEED_100000MBPS
261263
*/
262264
static u16 __get_link_speed(struct port *port)
263265
{
@@ -305,6 +307,10 @@ static u16 __get_link_speed(struct port *port)
305307
speed = AD_LINK_SPEED_56000MBPS;
306308
break;
307309

310+
case SPEED_100000:
311+
speed = AD_LINK_SPEED_100000MBPS;
312+
break;
313+
308314
default:
309315
/* unknown speed value from ethtool. shouldn't happen */
310316
speed = 0;
@@ -681,6 +687,9 @@ static u32 __get_agg_bandwidth(struct aggregator *aggregator)
681687
case AD_LINK_SPEED_56000MBPS:
682688
bandwidth = aggregator->num_of_ports * 56000;
683689
break;
690+
case AD_LINK_SPEED_100000MBPS:
691+
bandwidth = aggregator->num_of_ports * 100000;
692+
break;
684693
default:
685694
bandwidth = 0; /* to silence the compiler */
686695
}

drivers/net/bonding/bond_main.c

Lines changed: 79 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -830,7 +830,8 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
830830
}
831831

832832
new_active->delay = 0;
833-
bond_set_slave_link_state(new_active, BOND_LINK_UP);
833+
bond_set_slave_link_state(new_active, BOND_LINK_UP,
834+
BOND_SLAVE_NOTIFY_NOW);
834835

835836
if (BOND_MODE(bond) == BOND_MODE_8023AD)
836837
bond_3ad_handle_link_change(new_active, BOND_LINK_UP);
@@ -1198,26 +1199,43 @@ static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb)
11981199
return ret;
11991200
}
12001201

1201-
static int bond_master_upper_dev_link(struct net_device *bond_dev,
1202-
struct net_device *slave_dev,
1203-
struct slave *slave)
1202+
static enum netdev_lag_tx_type bond_lag_tx_type(struct bonding *bond)
12041203
{
1204+
switch (BOND_MODE(bond)) {
1205+
case BOND_MODE_ROUNDROBIN:
1206+
return NETDEV_LAG_TX_TYPE_ROUNDROBIN;
1207+
case BOND_MODE_ACTIVEBACKUP:
1208+
return NETDEV_LAG_TX_TYPE_ACTIVEBACKUP;
1209+
case BOND_MODE_BROADCAST:
1210+
return NETDEV_LAG_TX_TYPE_BROADCAST;
1211+
case BOND_MODE_XOR:
1212+
case BOND_MODE_8023AD:
1213+
return NETDEV_LAG_TX_TYPE_HASH;
1214+
default:
1215+
return NETDEV_LAG_TX_TYPE_UNKNOWN;
1216+
}
1217+
}
1218+
1219+
static int bond_master_upper_dev_link(struct bonding *bond, struct slave *slave)
1220+
{
1221+
struct netdev_lag_upper_info lag_upper_info;
12051222
int err;
12061223

1207-
err = netdev_master_upper_dev_link_private(slave_dev, bond_dev, slave);
1224+
lag_upper_info.tx_type = bond_lag_tx_type(bond);
1225+
err = netdev_master_upper_dev_link(slave->dev, bond->dev, slave,
1226+
&lag_upper_info);
12081227
if (err)
12091228
return err;
1210-
slave_dev->flags |= IFF_SLAVE;
1211-
rtmsg_ifinfo(RTM_NEWLINK, slave_dev, IFF_SLAVE, GFP_KERNEL);
1229+
slave->dev->flags |= IFF_SLAVE;
1230+
rtmsg_ifinfo(RTM_NEWLINK, slave->dev, IFF_SLAVE, GFP_KERNEL);
12121231
return 0;
12131232
}
12141233

1215-
static void bond_upper_dev_unlink(struct net_device *bond_dev,
1216-
struct net_device *slave_dev)
1234+
static void bond_upper_dev_unlink(struct bonding *bond, struct slave *slave)
12171235
{
1218-
netdev_upper_dev_unlink(slave_dev, bond_dev);
1219-
slave_dev->flags &= ~IFF_SLAVE;
1220-
rtmsg_ifinfo(RTM_NEWLINK, slave_dev, IFF_SLAVE, GFP_KERNEL);
1236+
netdev_upper_dev_unlink(slave->dev, bond->dev);
1237+
slave->dev->flags &= ~IFF_SLAVE;
1238+
rtmsg_ifinfo(RTM_NEWLINK, slave->dev, IFF_SLAVE, GFP_KERNEL);
12211239
}
12221240

12231241
static struct slave *bond_alloc_slave(struct bonding *bond)
@@ -1299,6 +1317,16 @@ void bond_queue_slave_event(struct slave *slave)
12991317
queue_delayed_work(slave->bond->wq, &nnw->work, 0);
13001318
}
13011319

1320+
void bond_lower_state_changed(struct slave *slave)
1321+
{
1322+
struct netdev_lag_lower_state_info info;
1323+
1324+
info.link_up = slave->link == BOND_LINK_UP ||
1325+
slave->link == BOND_LINK_FAIL;
1326+
info.tx_enabled = bond_is_active_slave(slave);
1327+
netdev_lower_state_changed(slave->dev, &info);
1328+
}
1329+
13021330
/* enslave device <slave> to bond device <master> */
13031331
int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
13041332
{
@@ -1563,21 +1591,26 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
15631591
if (bond_check_dev_link(bond, slave_dev, 0) == BMSR_LSTATUS) {
15641592
if (bond->params.updelay) {
15651593
bond_set_slave_link_state(new_slave,
1566-
BOND_LINK_BACK);
1594+
BOND_LINK_BACK,
1595+
BOND_SLAVE_NOTIFY_NOW);
15671596
new_slave->delay = bond->params.updelay;
15681597
} else {
15691598
bond_set_slave_link_state(new_slave,
1570-
BOND_LINK_UP);
1599+
BOND_LINK_UP,
1600+
BOND_SLAVE_NOTIFY_NOW);
15711601
}
15721602
} else {
1573-
bond_set_slave_link_state(new_slave, BOND_LINK_DOWN);
1603+
bond_set_slave_link_state(new_slave, BOND_LINK_DOWN,
1604+
BOND_SLAVE_NOTIFY_NOW);
15741605
}
15751606
} else if (bond->params.arp_interval) {
15761607
bond_set_slave_link_state(new_slave,
15771608
(netif_carrier_ok(slave_dev) ?
1578-
BOND_LINK_UP : BOND_LINK_DOWN));
1609+
BOND_LINK_UP : BOND_LINK_DOWN),
1610+
BOND_SLAVE_NOTIFY_NOW);
15791611
} else {
1580-
bond_set_slave_link_state(new_slave, BOND_LINK_UP);
1612+
bond_set_slave_link_state(new_slave, BOND_LINK_UP,
1613+
BOND_SLAVE_NOTIFY_NOW);
15811614
}
15821615

15831616
if (new_slave->link != BOND_LINK_DOWN)
@@ -1662,7 +1695,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
16621695
goto err_detach;
16631696
}
16641697

1665-
res = bond_master_upper_dev_link(bond_dev, slave_dev, new_slave);
1698+
res = bond_master_upper_dev_link(bond, new_slave);
16661699
if (res) {
16671700
netdev_dbg(bond_dev, "Error %d calling bond_master_upper_dev_link\n", res);
16681701
goto err_unregister;
@@ -1698,7 +1731,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
16981731

16991732
/* Undo stages on error */
17001733
err_upper_unlink:
1701-
bond_upper_dev_unlink(bond_dev, slave_dev);
1734+
bond_upper_dev_unlink(bond, new_slave);
17021735

17031736
err_unregister:
17041737
netdev_rx_handler_unregister(slave_dev);
@@ -1799,12 +1832,14 @@ static int __bond_release_one(struct net_device *bond_dev,
17991832
return -EINVAL;
18001833
}
18011834

1835+
bond_set_slave_inactive_flags(slave, BOND_SLAVE_NOTIFY_NOW);
1836+
18021837
bond_sysfs_slave_del(slave);
18031838

18041839
/* recompute stats just before removing the slave */
18051840
bond_get_stats(bond->dev, &bond->bond_stats);
18061841

1807-
bond_upper_dev_unlink(bond_dev, slave_dev);
1842+
bond_upper_dev_unlink(bond, slave);
18081843
/* unregister rx_handler early so bond_handle_frame wouldn't be called
18091844
* for this slave anymore.
18101845
*/
@@ -1996,7 +2031,8 @@ static int bond_miimon_inspect(struct bonding *bond)
19962031
if (link_state)
19972032
continue;
19982033

1999-
bond_set_slave_link_state(slave, BOND_LINK_FAIL);
2034+
bond_set_slave_link_state(slave, BOND_LINK_FAIL,
2035+
BOND_SLAVE_NOTIFY_LATER);
20002036
slave->delay = bond->params.downdelay;
20012037
if (slave->delay) {
20022038
netdev_info(bond->dev, "link status down for %sinterface %s, disabling it in %d ms\n",
@@ -2011,7 +2047,8 @@ static int bond_miimon_inspect(struct bonding *bond)
20112047
case BOND_LINK_FAIL:
20122048
if (link_state) {
20132049
/* recovered before downdelay expired */
2014-
bond_set_slave_link_state(slave, BOND_LINK_UP);
2050+
bond_set_slave_link_state(slave, BOND_LINK_UP,
2051+
BOND_SLAVE_NOTIFY_LATER);
20152052
slave->last_link_up = jiffies;
20162053
netdev_info(bond->dev, "link status up again after %d ms for interface %s\n",
20172054
(bond->params.downdelay - slave->delay) *
@@ -2033,7 +2070,8 @@ static int bond_miimon_inspect(struct bonding *bond)
20332070
if (!link_state)
20342071
continue;
20352072

2036-
bond_set_slave_link_state(slave, BOND_LINK_BACK);
2073+
bond_set_slave_link_state(slave, BOND_LINK_BACK,
2074+
BOND_SLAVE_NOTIFY_LATER);
20372075
slave->delay = bond->params.updelay;
20382076

20392077
if (slave->delay) {
@@ -2047,7 +2085,8 @@ static int bond_miimon_inspect(struct bonding *bond)
20472085
case BOND_LINK_BACK:
20482086
if (!link_state) {
20492087
bond_set_slave_link_state(slave,
2050-
BOND_LINK_DOWN);
2088+
BOND_LINK_DOWN,
2089+
BOND_SLAVE_NOTIFY_LATER);
20512090
netdev_info(bond->dev, "link status down again after %d ms for interface %s\n",
20522091
(bond->params.updelay - slave->delay) *
20532092
bond->params.miimon,
@@ -2085,7 +2124,8 @@ static void bond_miimon_commit(struct bonding *bond)
20852124
continue;
20862125

20872126
case BOND_LINK_UP:
2088-
bond_set_slave_link_state(slave, BOND_LINK_UP);
2127+
bond_set_slave_link_state(slave, BOND_LINK_UP,
2128+
BOND_SLAVE_NOTIFY_NOW);
20892129
slave->last_link_up = jiffies;
20902130

20912131
primary = rtnl_dereference(bond->primary_slave);
@@ -2125,7 +2165,8 @@ static void bond_miimon_commit(struct bonding *bond)
21252165
if (slave->link_failure_count < UINT_MAX)
21262166
slave->link_failure_count++;
21272167

2128-
bond_set_slave_link_state(slave, BOND_LINK_DOWN);
2168+
bond_set_slave_link_state(slave, BOND_LINK_DOWN,
2169+
BOND_SLAVE_NOTIFY_NOW);
21292170

21302171
if (BOND_MODE(bond) == BOND_MODE_ACTIVEBACKUP ||
21312172
BOND_MODE(bond) == BOND_MODE_8023AD)
@@ -2708,7 +2749,8 @@ static void bond_ab_arp_commit(struct bonding *bond)
27082749
struct slave *current_arp_slave;
27092750

27102751
current_arp_slave = rtnl_dereference(bond->current_arp_slave);
2711-
bond_set_slave_link_state(slave, BOND_LINK_UP);
2752+
bond_set_slave_link_state(slave, BOND_LINK_UP,
2753+
BOND_SLAVE_NOTIFY_NOW);
27122754
if (current_arp_slave) {
27132755
bond_set_slave_inactive_flags(
27142756
current_arp_slave,
@@ -2731,7 +2773,8 @@ static void bond_ab_arp_commit(struct bonding *bond)
27312773
if (slave->link_failure_count < UINT_MAX)
27322774
slave->link_failure_count++;
27332775

2734-
bond_set_slave_link_state(slave, BOND_LINK_DOWN);
2776+
bond_set_slave_link_state(slave, BOND_LINK_DOWN,
2777+
BOND_SLAVE_NOTIFY_NOW);
27352778
bond_set_slave_inactive_flags(slave,
27362779
BOND_SLAVE_NOTIFY_NOW);
27372780

@@ -2810,7 +2853,8 @@ static bool bond_ab_arp_probe(struct bonding *bond)
28102853
* up when it is actually down
28112854
*/
28122855
if (!bond_slave_is_up(slave) && slave->link == BOND_LINK_UP) {
2813-
bond_set_slave_link_state(slave, BOND_LINK_DOWN);
2856+
bond_set_slave_link_state(slave, BOND_LINK_DOWN,
2857+
BOND_SLAVE_NOTIFY_LATER);
28142858
if (slave->link_failure_count < UINT_MAX)
28152859
slave->link_failure_count++;
28162860

@@ -2830,15 +2874,16 @@ static bool bond_ab_arp_probe(struct bonding *bond)
28302874
if (!new_slave)
28312875
goto check_state;
28322876

2833-
bond_set_slave_link_state(new_slave, BOND_LINK_BACK);
2877+
bond_set_slave_link_state(new_slave, BOND_LINK_BACK,
2878+
BOND_SLAVE_NOTIFY_LATER);
28342879
bond_set_slave_active_flags(new_slave, BOND_SLAVE_NOTIFY_LATER);
28352880
bond_arp_send_all(bond, new_slave);
28362881
new_slave->last_link_up = jiffies;
28372882
rcu_assign_pointer(bond->current_arp_slave, new_slave);
28382883

28392884
check_state:
28402885
bond_for_each_slave_rcu(bond, slave, iter) {
2841-
if (slave->should_notify) {
2886+
if (slave->should_notify || slave->should_notify_link) {
28422887
should_notify_rtnl = BOND_SLAVE_NOTIFY_NOW;
28432888
break;
28442889
}
@@ -2893,8 +2938,10 @@ static void bond_activebackup_arp_mon(struct work_struct *work)
28932938
if (should_notify_peers)
28942939
call_netdevice_notifiers(NETDEV_NOTIFY_PEERS,
28952940
bond->dev);
2896-
if (should_notify_rtnl)
2941+
if (should_notify_rtnl) {
28972942
bond_slave_state_notify(bond);
2943+
bond_slave_link_notify(bond);
2944+
}
28982945

28992946
rtnl_unlock();
29002947
}

0 commit comments

Comments
 (0)