Skip to content

Commit 992d8a4

Browse files
gal-pressmanSaeed Mahameed
authored andcommitted
net/mlx5e: Fix wrong features assignment in case of error
In case of an error in mlx5e_set_features(), 'netdev->features' must be updated with the correct state of the device to indicate which features were updated successfully. To do that we maintain a copy of 'netdev->features' and update it after successful feature changes, so we can assign it to back to 'netdev->features' if needed. However, since not all netdev features are handled by the driver (e.g. GRO/TSO/etc), some features may not be updated correctly in case of an error updating another feature. For example, while requesting to disable TSO (feature which is not handled by the driver) and enable HW-GRO, if an error occurs during HW-GRO enable, 'oper_features' will be assigned with 'netdev->features' and HW-GRO turned off. TSO will remain enabled in such case, which is a bug. To solve that, instead of using 'netdev->features' as the baseline of 'oper_features' and changing it on set feature success, use 'features' instead and update it in case of errors. Fixes: 75b81ce ("net/mlx5e: Don't override netdev features field unless in error flow") Signed-off-by: Gal Pressman <[email protected]> Signed-off-by: Saeed Mahameed <[email protected]>
1 parent 077cdda commit 992d8a4

File tree

1 file changed

+5
-6
lines changed
  • drivers/net/ethernet/mellanox/mlx5/core

1 file changed

+5
-6
lines changed

drivers/net/ethernet/mellanox/mlx5/core/en_main.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3741,35 +3741,34 @@ static int set_feature_arfs(struct net_device *netdev, bool enable)
37413741

37423742
static int mlx5e_handle_feature(struct net_device *netdev,
37433743
netdev_features_t *features,
3744-
netdev_features_t wanted_features,
37453744
netdev_features_t feature,
37463745
mlx5e_feature_handler feature_handler)
37473746
{
3748-
netdev_features_t changes = wanted_features ^ netdev->features;
3749-
bool enable = !!(wanted_features & feature);
3747+
netdev_features_t changes = *features ^ netdev->features;
3748+
bool enable = !!(*features & feature);
37503749
int err;
37513750

37523751
if (!(changes & feature))
37533752
return 0;
37543753

37553754
err = feature_handler(netdev, enable);
37563755
if (err) {
3756+
MLX5E_SET_FEATURE(features, feature, !enable);
37573757
netdev_err(netdev, "%s feature %pNF failed, err %d\n",
37583758
enable ? "Enable" : "Disable", &feature, err);
37593759
return err;
37603760
}
37613761

3762-
MLX5E_SET_FEATURE(features, feature, enable);
37633762
return 0;
37643763
}
37653764

37663765
int mlx5e_set_features(struct net_device *netdev, netdev_features_t features)
37673766
{
3768-
netdev_features_t oper_features = netdev->features;
3767+
netdev_features_t oper_features = features;
37693768
int err = 0;
37703769

37713770
#define MLX5E_HANDLE_FEATURE(feature, handler) \
3772-
mlx5e_handle_feature(netdev, &oper_features, features, feature, handler)
3771+
mlx5e_handle_feature(netdev, &oper_features, feature, handler)
37733772

37743773
err |= MLX5E_HANDLE_FEATURE(NETIF_F_LRO, set_feature_lro);
37753774
err |= MLX5E_HANDLE_FEATURE(NETIF_F_GRO_HW, set_feature_hw_gro);

0 commit comments

Comments
 (0)