Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'mlx5-next' of git://git.kernel.org/pub/scm/linux/kernel/git/mellanox/linux

This merge includes updates to bonding driver needed for the rdma stack,
to avoid conflicts with the RDMA branch.

Maor Gottlieb Says:

====================
Bonding: Add support to get xmit slave

The following series adds support to get the LAG master xmit slave by
introducing new .ndo - ndo_get_xmit_slave. Every LAG module can
implement it and it first implemented in the bond driver.
This is follow-up to the RFC discussion [1].

The main motivation for doing this is for drivers that offload part
of the LAG functionality. For example, Mellanox Connect-X hardware
implements RoCE LAG which selects the TX affinity when the resources
are created and port is remapped when it goes down.

The first part of this patchset introduces the new .ndo and add the
support to the bonding module.

The second part adds support to get the RoCE LAG xmit slave by building
skb of the RoCE packet based on the AH attributes and call to the new
.ndo.

The third part change the mlx5 driver driver to set the QP's affinity
port according to the slave which found by the .ndo.
====================

Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>

+302 -100
+29 -12
drivers/net/bonding/bond_alb.c
··· 1331 1331 return bond_tx_drop(bond->dev, skb); 1332 1332 } 1333 1333 1334 - netdev_tx_t bond_tlb_xmit(struct sk_buff *skb, struct net_device *bond_dev) 1334 + struct slave *bond_xmit_tlb_slave_get(struct bonding *bond, 1335 + struct sk_buff *skb) 1335 1336 { 1336 - struct bonding *bond = netdev_priv(bond_dev); 1337 - struct ethhdr *eth_data; 1338 1337 struct slave *tx_slave = NULL; 1338 + struct ethhdr *eth_data; 1339 1339 u32 hash_index; 1340 1340 1341 1341 skb_reset_mac_header(skb); ··· 1357 1357 struct bond_up_slave *slaves; 1358 1358 unsigned int count; 1359 1359 1360 - slaves = rcu_dereference(bond->slave_arr); 1360 + slaves = rcu_dereference(bond->usable_slaves); 1361 1361 count = slaves ? READ_ONCE(slaves->count) : 0; 1362 1362 if (likely(count)) 1363 1363 tx_slave = slaves->arr[hash_index % ··· 1366 1366 break; 1367 1367 } 1368 1368 } 1369 + return tx_slave; 1370 + } 1371 + 1372 + netdev_tx_t bond_tlb_xmit(struct sk_buff *skb, struct net_device *bond_dev) 1373 + { 1374 + struct bonding *bond = netdev_priv(bond_dev); 1375 + struct slave *tx_slave; 1376 + 1377 + tx_slave = bond_xmit_tlb_slave_get(bond, skb); 1369 1378 return bond_do_alb_xmit(skb, bond, tx_slave); 1370 1379 } 1371 1380 1372 - netdev_tx_t bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev) 1381 + struct slave *bond_xmit_alb_slave_get(struct bonding *bond, 1382 + struct sk_buff *skb) 1373 1383 { 1374 - struct bonding *bond = netdev_priv(bond_dev); 1375 - struct ethhdr *eth_data; 1376 1384 struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); 1377 - struct slave *tx_slave = NULL; 1378 1385 static const __be32 ip_bcast = htonl(0xffffffff); 1379 - int hash_size = 0; 1380 - bool do_tx_balance = true; 1381 - u32 hash_index = 0; 1386 + struct slave *tx_slave = NULL; 1382 1387 const u8 *hash_start = NULL; 1388 + bool do_tx_balance = true; 1389 + struct ethhdr *eth_data; 1390 + u32 hash_index = 0; 1391 + int hash_size = 0; 1383 1392 1384 1393 skb_reset_mac_header(skb); 1385 1394 eth_data = eth_hdr(skb); ··· 1500 1491 struct bond_up_slave *slaves; 1501 1492 unsigned int count; 1502 1493 1503 - slaves = rcu_dereference(bond->slave_arr); 1494 + slaves = rcu_dereference(bond->usable_slaves); 1504 1495 count = slaves ? READ_ONCE(slaves->count) : 0; 1505 1496 if (likely(count)) 1506 1497 tx_slave = slaves->arr[bond_xmit_hash(bond, skb) % 1507 1498 count]; 1508 1499 } 1509 1500 } 1501 + return tx_slave; 1502 + } 1510 1503 1504 + netdev_tx_t bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev) 1505 + { 1506 + struct bonding *bond = netdev_priv(bond_dev); 1507 + struct slave *tx_slave = NULL; 1508 + 1509 + tx_slave = bond_xmit_alb_slave_get(bond, skb); 1511 1510 return bond_do_alb_xmit(skb, bond, tx_slave); 1512 1511 } 1513 1512
+186 -66
drivers/net/bonding/bond_main.c
··· 3923 3923 } 3924 3924 3925 3925 /** 3926 - * bond_xmit_slave_id - transmit skb through slave with slave_id 3926 + * bond_get_slave_by_id - get xmit slave with slave_id 3927 3927 * @bond: bonding device that is transmitting 3928 - * @skb: buffer to transmit 3929 3928 * @slave_id: slave id up to slave_cnt-1 through which to transmit 3930 3929 * 3931 - * This function tries to transmit through slave with slave_id but in case 3930 + * This function tries to get slave with slave_id but in case 3932 3931 * it fails, it tries to find the first available slave for transmission. 3933 - * The skb is consumed in all cases, thus the function is void. 3934 3932 */ 3935 - static netdev_tx_t bond_xmit_slave_id(struct bonding *bond, struct sk_buff *skb, int slave_id) 3933 + static struct slave *bond_get_slave_by_id(struct bonding *bond, 3934 + int slave_id) 3936 3935 { 3937 3936 struct list_head *iter; 3938 3937 struct slave *slave; ··· 3941 3942 bond_for_each_slave_rcu(bond, slave, iter) { 3942 3943 if (--i < 0) { 3943 3944 if (bond_slave_can_tx(slave)) 3944 - return bond_dev_queue_xmit(bond, skb, slave->dev); 3945 + return slave; 3945 3946 } 3946 3947 } 3947 3948 ··· 3951 3952 if (--i < 0) 3952 3953 break; 3953 3954 if (bond_slave_can_tx(slave)) 3954 - return bond_dev_queue_xmit(bond, skb, slave->dev); 3955 + return slave; 3955 3956 } 3956 3957 /* no slave that can tx has been found */ 3957 - return bond_tx_drop(bond->dev, skb); 3958 + return NULL; 3958 3959 } 3959 3960 3960 3961 /** ··· 3990 3991 return slave_id; 3991 3992 } 3992 3993 3993 - static netdev_tx_t bond_xmit_roundrobin(struct sk_buff *skb, 3994 - struct net_device *bond_dev) 3994 + static struct slave *bond_xmit_roundrobin_slave_get(struct bonding *bond, 3995 + struct sk_buff *skb) 3995 3996 { 3996 - struct bonding *bond = netdev_priv(bond_dev); 3997 3997 struct slave *slave; 3998 3998 int slave_cnt; 3999 3999 u32 slave_id; ··· 4014 4016 if (iph->protocol == IPPROTO_IGMP) { 4015 4017 slave = rcu_dereference(bond->curr_active_slave); 4016 4018 if (slave) 4017 - return bond_dev_queue_xmit(bond, skb, slave->dev); 4018 - return bond_xmit_slave_id(bond, skb, 0); 4019 + return slave; 4020 + return bond_get_slave_by_id(bond, 0); 4019 4021 } 4020 4022 } 4021 4023 4022 4024 non_igmp: 4023 4025 slave_cnt = READ_ONCE(bond->slave_cnt); 4024 4026 if (likely(slave_cnt)) { 4025 - slave_id = bond_rr_gen_slave_id(bond); 4026 - return bond_xmit_slave_id(bond, skb, slave_id % slave_cnt); 4027 + slave_id = bond_rr_gen_slave_id(bond) % slave_cnt; 4028 + return bond_get_slave_by_id(bond, slave_id); 4027 4029 } 4030 + return NULL; 4031 + } 4032 + 4033 + static netdev_tx_t bond_xmit_roundrobin(struct sk_buff *skb, 4034 + struct net_device *bond_dev) 4035 + { 4036 + struct bonding *bond = netdev_priv(bond_dev); 4037 + struct slave *slave; 4038 + 4039 + slave = bond_xmit_roundrobin_slave_get(bond, skb); 4040 + if (likely(slave)) 4041 + return bond_dev_queue_xmit(bond, skb, slave->dev); 4042 + 4028 4043 return bond_tx_drop(bond_dev, skb); 4044 + } 4045 + 4046 + static struct slave *bond_xmit_activebackup_slave_get(struct bonding *bond, 4047 + struct sk_buff *skb) 4048 + { 4049 + return rcu_dereference(bond->curr_active_slave); 4029 4050 } 4030 4051 4031 4052 /* In active-backup mode, we know that bond->curr_active_slave is always valid if ··· 4056 4039 struct bonding *bond = netdev_priv(bond_dev); 4057 4040 struct slave *slave; 4058 4041 4059 - slave = rcu_dereference(bond->curr_active_slave); 4042 + slave = bond_xmit_activebackup_slave_get(bond, skb); 4060 4043 if (slave) 4061 4044 return bond_dev_queue_xmit(bond, skb, slave->dev); 4062 4045 ··· 4094 4077 bond_slave_arr_work_rearm(bond, 1); 4095 4078 } 4096 4079 4080 + static void bond_skip_slave(struct bond_up_slave *slaves, 4081 + struct slave *skipslave) 4082 + { 4083 + int idx; 4084 + 4085 + /* Rare situation where caller has asked to skip a specific 4086 + * slave but allocation failed (most likely!). BTW this is 4087 + * only possible when the call is initiated from 4088 + * __bond_release_one(). In this situation; overwrite the 4089 + * skipslave entry in the array with the last entry from the 4090 + * array to avoid a situation where the xmit path may choose 4091 + * this to-be-skipped slave to send a packet out. 4092 + */ 4093 + for (idx = 0; slaves && idx < slaves->count; idx++) { 4094 + if (skipslave == slaves->arr[idx]) { 4095 + slaves->arr[idx] = 4096 + slaves->arr[slaves->count - 1]; 4097 + slaves->count--; 4098 + break; 4099 + } 4100 + } 4101 + } 4102 + 4103 + static void bond_set_slave_arr(struct bonding *bond, 4104 + struct bond_up_slave *usable_slaves, 4105 + struct bond_up_slave *all_slaves) 4106 + { 4107 + struct bond_up_slave *usable, *all; 4108 + 4109 + usable = rtnl_dereference(bond->usable_slaves); 4110 + rcu_assign_pointer(bond->usable_slaves, usable_slaves); 4111 + kfree_rcu(usable, rcu); 4112 + 4113 + all = rtnl_dereference(bond->all_slaves); 4114 + rcu_assign_pointer(bond->all_slaves, all_slaves); 4115 + kfree_rcu(all, rcu); 4116 + } 4117 + 4118 + static void bond_reset_slave_arr(struct bonding *bond) 4119 + { 4120 + struct bond_up_slave *usable, *all; 4121 + 4122 + usable = rtnl_dereference(bond->usable_slaves); 4123 + if (usable) { 4124 + RCU_INIT_POINTER(bond->usable_slaves, NULL); 4125 + kfree_rcu(usable, rcu); 4126 + } 4127 + 4128 + all = rtnl_dereference(bond->all_slaves); 4129 + if (all) { 4130 + RCU_INIT_POINTER(bond->all_slaves, NULL); 4131 + kfree_rcu(all, rcu); 4132 + } 4133 + } 4134 + 4097 4135 /* Build the usable slaves array in control path for modes that use xmit-hash 4098 4136 * to determine the slave interface - 4099 4137 * (a) BOND_MODE_8023AD ··· 4159 4087 */ 4160 4088 int bond_update_slave_arr(struct bonding *bond, struct slave *skipslave) 4161 4089 { 4090 + struct bond_up_slave *usable_slaves = NULL, *all_slaves = NULL; 4162 4091 struct slave *slave; 4163 4092 struct list_head *iter; 4164 - struct bond_up_slave *new_arr, *old_arr; 4165 4093 int agg_id = 0; 4166 4094 int ret = 0; 4167 4095 ··· 4169 4097 WARN_ON(lockdep_is_held(&bond->mode_lock)); 4170 4098 #endif 4171 4099 4172 - new_arr = kzalloc(offsetof(struct bond_up_slave, arr[bond->slave_cnt]), 4173 - GFP_KERNEL); 4174 - if (!new_arr) { 4100 + usable_slaves = kzalloc(struct_size(usable_slaves, arr, 4101 + bond->slave_cnt), GFP_KERNEL); 4102 + all_slaves = kzalloc(struct_size(all_slaves, arr, 4103 + bond->slave_cnt), GFP_KERNEL); 4104 + if (!usable_slaves || !all_slaves) { 4175 4105 ret = -ENOMEM; 4176 - pr_err("Failed to build slave-array.\n"); 4177 4106 goto out; 4178 4107 } 4179 4108 if (BOND_MODE(bond) == BOND_MODE_8023AD) { ··· 4182 4109 4183 4110 if (bond_3ad_get_active_agg_info(bond, &ad_info)) { 4184 4111 pr_debug("bond_3ad_get_active_agg_info failed\n"); 4185 - kfree_rcu(new_arr, rcu); 4186 4112 /* No active aggragator means it's not safe to use 4187 4113 * the previous array. 4188 4114 */ 4189 - old_arr = rtnl_dereference(bond->slave_arr); 4190 - if (old_arr) { 4191 - RCU_INIT_POINTER(bond->slave_arr, NULL); 4192 - kfree_rcu(old_arr, rcu); 4193 - } 4115 + bond_reset_slave_arr(bond); 4194 4116 goto out; 4195 4117 } 4196 4118 agg_id = ad_info.aggregator_id; 4197 4119 } 4198 4120 bond_for_each_slave(bond, slave, iter) { 4121 + if (skipslave == slave) 4122 + continue; 4123 + 4124 + all_slaves->arr[all_slaves->count++] = slave; 4199 4125 if (BOND_MODE(bond) == BOND_MODE_8023AD) { 4200 4126 struct aggregator *agg; 4201 4127 ··· 4204 4132 } 4205 4133 if (!bond_slave_can_tx(slave)) 4206 4134 continue; 4207 - if (skipslave == slave) 4208 - continue; 4209 4135 4210 4136 slave_dbg(bond->dev, slave->dev, "Adding slave to tx hash array[%d]\n", 4211 - new_arr->count); 4137 + usable_slaves->count); 4212 4138 4213 - new_arr->arr[new_arr->count++] = slave; 4139 + usable_slaves->arr[usable_slaves->count++] = slave; 4214 4140 } 4215 4141 4216 - old_arr = rtnl_dereference(bond->slave_arr); 4217 - rcu_assign_pointer(bond->slave_arr, new_arr); 4218 - if (old_arr) 4219 - kfree_rcu(old_arr, rcu); 4142 + bond_set_slave_arr(bond, usable_slaves, all_slaves); 4143 + return ret; 4220 4144 out: 4221 4145 if (ret != 0 && skipslave) { 4222 - int idx; 4223 - 4224 - /* Rare situation where caller has asked to skip a specific 4225 - * slave but allocation failed (most likely!). BTW this is 4226 - * only possible when the call is initiated from 4227 - * __bond_release_one(). In this situation; overwrite the 4228 - * skipslave entry in the array with the last entry from the 4229 - * array to avoid a situation where the xmit path may choose 4230 - * this to-be-skipped slave to send a packet out. 4231 - */ 4232 - old_arr = rtnl_dereference(bond->slave_arr); 4233 - for (idx = 0; old_arr != NULL && idx < old_arr->count; idx++) { 4234 - if (skipslave == old_arr->arr[idx]) { 4235 - old_arr->arr[idx] = 4236 - old_arr->arr[old_arr->count-1]; 4237 - old_arr->count--; 4238 - break; 4239 - } 4240 - } 4146 + bond_skip_slave(rtnl_dereference(bond->all_slaves), 4147 + skipslave); 4148 + bond_skip_slave(rtnl_dereference(bond->usable_slaves), 4149 + skipslave); 4241 4150 } 4151 + kfree_rcu(all_slaves, rcu); 4152 + kfree_rcu(usable_slaves, rcu); 4153 + 4242 4154 return ret; 4155 + } 4156 + 4157 + static struct slave *bond_xmit_3ad_xor_slave_get(struct bonding *bond, 4158 + struct sk_buff *skb, 4159 + struct bond_up_slave *slaves) 4160 + { 4161 + struct slave *slave; 4162 + unsigned int count; 4163 + u32 hash; 4164 + 4165 + hash = bond_xmit_hash(bond, skb); 4166 + count = slaves ? READ_ONCE(slaves->count) : 0; 4167 + if (unlikely(!count)) 4168 + return NULL; 4169 + 4170 + slave = slaves->arr[hash % count]; 4171 + return slave; 4243 4172 } 4244 4173 4245 4174 /* Use this Xmit function for 3AD as well as XOR modes. The current ··· 4251 4178 struct net_device *dev) 4252 4179 { 4253 4180 struct bonding *bond = netdev_priv(dev); 4254 - struct slave *slave; 4255 4181 struct bond_up_slave *slaves; 4256 - unsigned int count; 4182 + struct slave *slave; 4257 4183 4258 - slaves = rcu_dereference(bond->slave_arr); 4259 - count = slaves ? READ_ONCE(slaves->count) : 0; 4260 - if (likely(count)) { 4261 - slave = slaves->arr[bond_xmit_hash(bond, skb) % count]; 4184 + slaves = rcu_dereference(bond->usable_slaves); 4185 + slave = bond_xmit_3ad_xor_slave_get(bond, skb, slaves); 4186 + if (likely(slave)) 4262 4187 return bond_dev_queue_xmit(bond, skb, slave->dev); 4263 - } 4188 + 4264 4189 return bond_tx_drop(dev, skb); 4265 4190 } 4266 4191 ··· 4338 4267 } while (txq >= dev->real_num_tx_queues); 4339 4268 } 4340 4269 return txq; 4270 + } 4271 + 4272 + static struct net_device *bond_xmit_get_slave(struct net_device *master_dev, 4273 + struct sk_buff *skb, 4274 + bool all_slaves) 4275 + { 4276 + struct bonding *bond = netdev_priv(master_dev); 4277 + struct bond_up_slave *slaves; 4278 + struct slave *slave = NULL; 4279 + 4280 + switch (BOND_MODE(bond)) { 4281 + case BOND_MODE_ROUNDROBIN: 4282 + slave = bond_xmit_roundrobin_slave_get(bond, skb); 4283 + break; 4284 + case BOND_MODE_ACTIVEBACKUP: 4285 + slave = bond_xmit_activebackup_slave_get(bond, skb); 4286 + break; 4287 + case BOND_MODE_8023AD: 4288 + case BOND_MODE_XOR: 4289 + if (all_slaves) 4290 + slaves = rcu_dereference(bond->all_slaves); 4291 + else 4292 + slaves = rcu_dereference(bond->usable_slaves); 4293 + slave = bond_xmit_3ad_xor_slave_get(bond, skb, slaves); 4294 + break; 4295 + case BOND_MODE_BROADCAST: 4296 + break; 4297 + case BOND_MODE_ALB: 4298 + slave = bond_xmit_alb_slave_get(bond, skb); 4299 + break; 4300 + case BOND_MODE_TLB: 4301 + slave = bond_xmit_tlb_slave_get(bond, skb); 4302 + break; 4303 + default: 4304 + /* Should never happen, mode already checked */ 4305 + WARN_ONCE(true, "Unknown bonding mode"); 4306 + break; 4307 + } 4308 + 4309 + if (slave) 4310 + return slave->dev; 4311 + return NULL; 4341 4312 } 4342 4313 4343 4314 static netdev_tx_t __bond_start_xmit(struct sk_buff *skb, struct net_device *dev) ··· 4502 4389 .ndo_del_slave = bond_release, 4503 4390 .ndo_fix_features = bond_fix_features, 4504 4391 .ndo_features_check = passthru_features_check, 4392 + .ndo_get_xmit_slave = bond_xmit_get_slave, 4505 4393 }; 4506 4394 4507 4395 static const struct device_type bond_type = { ··· 4570 4456 static void bond_uninit(struct net_device *bond_dev) 4571 4457 { 4572 4458 struct bonding *bond = netdev_priv(bond_dev); 4459 + struct bond_up_slave *usable, *all; 4573 4460 struct list_head *iter; 4574 4461 struct slave *slave; 4575 - struct bond_up_slave *arr; 4576 4462 4577 4463 bond_netpoll_cleanup(bond_dev); 4578 4464 ··· 4581 4467 __bond_release_one(bond_dev, slave->dev, true, true); 4582 4468 netdev_info(bond_dev, "Released all slaves\n"); 4583 4469 4584 - arr = rtnl_dereference(bond->slave_arr); 4585 - if (arr) { 4586 - RCU_INIT_POINTER(bond->slave_arr, NULL); 4587 - kfree_rcu(arr, rcu); 4470 + usable = rtnl_dereference(bond->usable_slaves); 4471 + if (usable) { 4472 + RCU_INIT_POINTER(bond->usable_slaves, NULL); 4473 + kfree_rcu(usable, rcu); 4474 + } 4475 + 4476 + all = rtnl_dereference(bond->all_slaves); 4477 + if (all) { 4478 + RCU_INIT_POINTER(bond->all_slaves, NULL); 4479 + kfree_rcu(all, rcu); 4588 4480 } 4589 4481 4590 4482 list_del(&bond->bond_list);
+45 -21
drivers/net/ethernet/mellanox/mlx5/core/lag.c
··· 42 42 * Beware of lock dependencies (preferably, no locks should be acquired 43 43 * under it). 44 44 */ 45 - static DEFINE_MUTEX(lag_mutex); 45 + static DEFINE_SPINLOCK(lag_lock); 46 46 47 47 static int mlx5_cmd_create_lag(struct mlx5_core_dev *dev, u8 remap_port1, 48 48 u8 remap_port2) ··· 274 274 if (!dev0 || !dev1) 275 275 return; 276 276 277 - mutex_lock(&lag_mutex); 277 + spin_lock(&lag_lock); 278 278 tracker = ldev->tracker; 279 - mutex_unlock(&lag_mutex); 279 + spin_unlock(&lag_lock); 280 280 281 281 do_bond = tracker.is_bonded && mlx5_lag_check_prereq(ldev); 282 282 ··· 458 458 break; 459 459 } 460 460 461 - mutex_lock(&lag_mutex); 461 + spin_lock(&lag_lock); 462 462 ldev->tracker = tracker; 463 - mutex_unlock(&lag_mutex); 463 + spin_unlock(&lag_lock); 464 464 465 465 if (changed) 466 466 mlx5_queue_bond_work(ldev, 0); ··· 502 502 if (fn >= MLX5_MAX_PORTS) 503 503 return; 504 504 505 - mutex_lock(&lag_mutex); 505 + spin_lock(&lag_lock); 506 506 ldev->pf[fn].dev = dev; 507 507 ldev->pf[fn].netdev = netdev; 508 508 ldev->tracker.netdev_state[fn].link_up = 0; ··· 510 510 511 511 dev->priv.lag = ldev; 512 512 513 - mutex_unlock(&lag_mutex); 513 + spin_unlock(&lag_lock); 514 514 } 515 515 516 516 static void mlx5_lag_dev_remove_pf(struct mlx5_lag *ldev, ··· 525 525 if (i == MLX5_MAX_PORTS) 526 526 return; 527 527 528 - mutex_lock(&lag_mutex); 528 + spin_lock(&lag_lock); 529 529 memset(&ldev->pf[i], 0, sizeof(*ldev->pf)); 530 530 531 531 dev->priv.lag = NULL; 532 - mutex_unlock(&lag_mutex); 532 + spin_unlock(&lag_lock); 533 533 } 534 534 535 535 /* Must be called with intf_mutex held */ ··· 607 607 struct mlx5_lag *ldev; 608 608 bool res; 609 609 610 - mutex_lock(&lag_mutex); 610 + spin_lock(&lag_lock); 611 611 ldev = mlx5_lag_dev_get(dev); 612 612 res = ldev && __mlx5_lag_is_roce(ldev); 613 - mutex_unlock(&lag_mutex); 613 + spin_unlock(&lag_lock); 614 614 615 615 return res; 616 616 } ··· 621 621 struct mlx5_lag *ldev; 622 622 bool res; 623 623 624 - mutex_lock(&lag_mutex); 624 + spin_lock(&lag_lock); 625 625 ldev = mlx5_lag_dev_get(dev); 626 626 res = ldev && __mlx5_lag_is_active(ldev); 627 - mutex_unlock(&lag_mutex); 627 + spin_unlock(&lag_lock); 628 628 629 629 return res; 630 630 } ··· 635 635 struct mlx5_lag *ldev; 636 636 bool res; 637 637 638 - mutex_lock(&lag_mutex); 638 + spin_lock(&lag_lock); 639 639 ldev = mlx5_lag_dev_get(dev); 640 640 res = ldev && __mlx5_lag_is_sriov(ldev); 641 - mutex_unlock(&lag_mutex); 641 + spin_unlock(&lag_lock); 642 642 643 643 return res; 644 644 } ··· 664 664 struct net_device *ndev = NULL; 665 665 struct mlx5_lag *ldev; 666 666 667 - mutex_lock(&lag_mutex); 667 + spin_lock(&lag_lock); 668 668 ldev = mlx5_lag_dev_get(dev); 669 669 670 670 if (!(ldev && __mlx5_lag_is_roce(ldev))) ··· 681 681 dev_hold(ndev); 682 682 683 683 unlock: 684 - mutex_unlock(&lag_mutex); 684 + spin_unlock(&lag_lock); 685 685 686 686 return ndev; 687 687 } 688 688 EXPORT_SYMBOL(mlx5_lag_get_roce_netdev); 689 + 690 + u8 mlx5_lag_get_slave_port(struct mlx5_core_dev *dev, 691 + struct net_device *slave) 692 + { 693 + struct mlx5_lag *ldev; 694 + u8 port = 0; 695 + 696 + spin_lock(&lag_lock); 697 + ldev = mlx5_lag_dev_get(dev); 698 + if (!(ldev && __mlx5_lag_is_roce(ldev))) 699 + goto unlock; 700 + 701 + if (ldev->pf[MLX5_LAG_P1].netdev == slave) 702 + port = MLX5_LAG_P1; 703 + else 704 + port = MLX5_LAG_P2; 705 + 706 + port = ldev->v2p_map[port]; 707 + 708 + unlock: 709 + spin_unlock(&lag_lock); 710 + return port; 711 + } 712 + EXPORT_SYMBOL(mlx5_lag_get_slave_port); 689 713 690 714 bool mlx5_lag_intf_add(struct mlx5_interface *intf, struct mlx5_priv *priv) 691 715 { ··· 747 723 748 724 memset(values, 0, sizeof(*values) * num_counters); 749 725 750 - mutex_lock(&lag_mutex); 726 + spin_lock(&lag_lock); 751 727 ldev = mlx5_lag_dev_get(dev); 752 728 if (ldev && __mlx5_lag_is_roce(ldev)) { 753 729 num_ports = MLX5_MAX_PORTS; ··· 757 733 num_ports = 1; 758 734 mdev[MLX5_LAG_P1] = dev; 759 735 } 736 + spin_unlock(&lag_lock); 760 737 761 738 for (i = 0; i < num_ports; ++i) { 762 739 u32 in[MLX5_ST_SZ_DW(query_cong_statistics_in)] = {}; ··· 767 742 ret = mlx5_cmd_exec_inout(mdev[i], query_cong_statistics, in, 768 743 out); 769 744 if (ret) 770 - goto unlock; 745 + goto free; 771 746 772 747 for (j = 0; j < num_counters; ++j) 773 748 values[j] += be64_to_cpup((__be64 *)(out + offsets[j])); 774 749 } 775 750 776 - unlock: 777 - mutex_unlock(&lag_mutex); 751 + free: 778 752 kvfree(out); 779 753 return ret; 780 754 }
+2
include/linux/mlx5/driver.h
··· 1074 1074 bool mlx5_lag_is_multipath(struct mlx5_core_dev *dev); 1075 1075 bool mlx5_lag_is_active(struct mlx5_core_dev *dev); 1076 1076 struct net_device *mlx5_lag_get_roce_netdev(struct mlx5_core_dev *dev); 1077 + u8 mlx5_lag_get_slave_port(struct mlx5_core_dev *dev, 1078 + struct net_device *slave); 1077 1079 int mlx5_lag_query_cong_counters(struct mlx5_core_dev *dev, 1078 1080 u64 *values, 1079 1081 int num_counters,
+12
include/linux/netdevice.h
··· 1148 1148 * int (*ndo_del_slave)(struct net_device *dev, struct net_device *slave_dev); 1149 1149 * Called to release previously enslaved netdev. 1150 1150 * 1151 + * struct net_device *(*ndo_get_xmit_slave)(struct net_device *dev, 1152 + * struct sk_buff *skb, 1153 + * bool all_slaves); 1154 + * Get the xmit slave of master device. If all_slaves is true, function 1155 + * assume all the slaves can transmit. 1156 + * 1151 1157 * Feature/offload setting functions. 1152 1158 * netdev_features_t (*ndo_fix_features)(struct net_device *dev, 1153 1159 * netdev_features_t features); ··· 1397 1391 struct netlink_ext_ack *extack); 1398 1392 int (*ndo_del_slave)(struct net_device *dev, 1399 1393 struct net_device *slave_dev); 1394 + struct net_device* (*ndo_get_xmit_slave)(struct net_device *dev, 1395 + struct sk_buff *skb, 1396 + bool all_slaves); 1400 1397 netdev_features_t (*ndo_fix_features)(struct net_device *dev, 1401 1398 netdev_features_t features); 1402 1399 int (*ndo_set_features)(struct net_device *dev, ··· 2754 2745 void synchronize_net(void); 2755 2746 int init_dummy_netdev(struct net_device *dev); 2756 2747 2748 + struct net_device *netdev_get_xmit_slave(struct net_device *dev, 2749 + struct sk_buff *skb, 2750 + bool all_slaves); 2757 2751 struct net_device *dev_get_by_index(struct net *net, int ifindex); 2758 2752 struct net_device *__dev_get_by_index(struct net *net, int ifindex); 2759 2753 struct net_device *dev_get_by_index_rcu(struct net *net, int ifindex);
+4
include/net/bond_alb.h
··· 158 158 void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave); 159 159 int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev); 160 160 int bond_tlb_xmit(struct sk_buff *skb, struct net_device *bond_dev); 161 + struct slave *bond_xmit_alb_slave_get(struct bonding *bond, 162 + struct sk_buff *skb); 163 + struct slave *bond_xmit_tlb_slave_get(struct bonding *bond, 164 + struct sk_buff *skb); 161 165 void bond_alb_monitor(struct work_struct *); 162 166 int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr); 163 167 void bond_alb_clear_vlan(struct bonding *bond, unsigned short vlan_id);
+2 -1
include/net/bonding.h
··· 200 200 struct slave __rcu *curr_active_slave; 201 201 struct slave __rcu *current_arp_slave; 202 202 struct slave __rcu *primary_slave; 203 - struct bond_up_slave __rcu *slave_arr; /* Array of usable slaves */ 203 + struct bond_up_slave __rcu *usable_slaves; 204 + struct bond_up_slave __rcu *all_slaves; 204 205 bool force_primary; 205 206 s32 slave_cnt; /* never change this value outside the attach/detach wrappers */ 206 207 int (*recv_probe)(const struct sk_buff *, struct bonding *,
+22
net/core/dev.c
··· 7861 7861 } 7862 7862 EXPORT_SYMBOL(netdev_bonding_info_change); 7863 7863 7864 + /** 7865 + * netdev_get_xmit_slave - Get the xmit slave of master device 7866 + * @skb: The packet 7867 + * @all_slaves: assume all the slaves are active 7868 + * 7869 + * The reference counters are not incremented so the caller must be 7870 + * careful with locks. The caller must hold RCU lock. 7871 + * %NULL is returned if no slave is found. 7872 + */ 7873 + 7874 + struct net_device *netdev_get_xmit_slave(struct net_device *dev, 7875 + struct sk_buff *skb, 7876 + bool all_slaves) 7877 + { 7878 + const struct net_device_ops *ops = dev->netdev_ops; 7879 + 7880 + if (!ops->ndo_get_xmit_slave) 7881 + return NULL; 7882 + return ops->ndo_get_xmit_slave(dev, skb, all_slaves); 7883 + } 7884 + EXPORT_SYMBOL(netdev_get_xmit_slave); 7885 + 7864 7886 static void netdev_adjacent_add_links(struct net_device *dev) 7865 7887 { 7866 7888 struct netdev_adjacent *iter;