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

Merge tag 'mlx5-fixes-2018-10-01' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux

Saeed Mahameed says:

====================
Mellanox, mlx5 fixes 2018-10-01

This pull request includes some fixes to mlx5 driver,
Please pull and let me know if there's any problem.

For -stable v4.11:
"6e0a4a23c59a ('net/mlx5: E-Switch, Fix out of bound access when setting vport rate')"

For -stable v4.18:
"98d6627c372a ('net/mlx5e: Set vlan masks for all offloaded TC rules')"
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+76 -5
+1
drivers/net/ethernet/mellanox/mlx5/core/en.h
··· 54 54 #include "en_stats.h" 55 55 #include "en/fs.h" 56 56 57 + extern const struct net_device_ops mlx5e_netdev_ops; 57 58 struct page_pool; 58 59 59 60 #define MLX5E_METADATA_ETHER_TYPE (0x8CE4)
+2
drivers/net/ethernet/mellanox/mlx5/core/en/fs.h
··· 16 16 17 17 DECLARE_HASHTABLE(mod_hdr_tbl, 8); 18 18 DECLARE_HASHTABLE(hairpin_tbl, 8); 19 + 20 + struct notifier_block netdevice_nb; 19 21 }; 20 22 21 23 struct mlx5e_flow_table {
+1 -1
drivers/net/ethernet/mellanox/mlx5/core/en_main.c
··· 4315 4315 } 4316 4316 } 4317 4317 4318 - static const struct net_device_ops mlx5e_netdev_ops = { 4318 + const struct net_device_ops mlx5e_netdev_ops = { 4319 4319 .ndo_open = mlx5e_open, 4320 4320 .ndo_stop = mlx5e_close, 4321 4321 .ndo_start_xmit = mlx5e_xmit,
+64 -1
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
··· 1368 1368 1369 1369 *match_level = MLX5_MATCH_L2; 1370 1370 } 1371 + } else { 1372 + MLX5_SET(fte_match_set_lyr_2_4, headers_c, svlan_tag, 1); 1373 + MLX5_SET(fte_match_set_lyr_2_4, headers_c, cvlan_tag, 1); 1371 1374 } 1372 1375 1373 1376 if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_CVLAN)) { ··· 2949 2946 return 0; 2950 2947 } 2951 2948 2949 + static void mlx5e_tc_hairpin_update_dead_peer(struct mlx5e_priv *priv, 2950 + struct mlx5e_priv *peer_priv) 2951 + { 2952 + struct mlx5_core_dev *peer_mdev = peer_priv->mdev; 2953 + struct mlx5e_hairpin_entry *hpe; 2954 + u16 peer_vhca_id; 2955 + int bkt; 2956 + 2957 + if (!same_hw_devs(priv, peer_priv)) 2958 + return; 2959 + 2960 + peer_vhca_id = MLX5_CAP_GEN(peer_mdev, vhca_id); 2961 + 2962 + hash_for_each(priv->fs.tc.hairpin_tbl, bkt, hpe, hairpin_hlist) { 2963 + if (hpe->peer_vhca_id == peer_vhca_id) 2964 + hpe->hp->pair->peer_gone = true; 2965 + } 2966 + } 2967 + 2968 + static int mlx5e_tc_netdev_event(struct notifier_block *this, 2969 + unsigned long event, void *ptr) 2970 + { 2971 + struct net_device *ndev = netdev_notifier_info_to_dev(ptr); 2972 + struct mlx5e_flow_steering *fs; 2973 + struct mlx5e_priv *peer_priv; 2974 + struct mlx5e_tc_table *tc; 2975 + struct mlx5e_priv *priv; 2976 + 2977 + if (ndev->netdev_ops != &mlx5e_netdev_ops || 2978 + event != NETDEV_UNREGISTER || 2979 + ndev->reg_state == NETREG_REGISTERED) 2980 + return NOTIFY_DONE; 2981 + 2982 + tc = container_of(this, struct mlx5e_tc_table, netdevice_nb); 2983 + fs = container_of(tc, struct mlx5e_flow_steering, tc); 2984 + priv = container_of(fs, struct mlx5e_priv, fs); 2985 + peer_priv = netdev_priv(ndev); 2986 + if (priv == peer_priv || 2987 + !(priv->netdev->features & NETIF_F_HW_TC)) 2988 + return NOTIFY_DONE; 2989 + 2990 + mlx5e_tc_hairpin_update_dead_peer(priv, peer_priv); 2991 + 2992 + return NOTIFY_DONE; 2993 + } 2994 + 2952 2995 int mlx5e_tc_nic_init(struct mlx5e_priv *priv) 2953 2996 { 2954 2997 struct mlx5e_tc_table *tc = &priv->fs.tc; 2998 + int err; 2955 2999 2956 3000 hash_init(tc->mod_hdr_tbl); 2957 3001 hash_init(tc->hairpin_tbl); 2958 3002 2959 - return rhashtable_init(&tc->ht, &tc_ht_params); 3003 + err = rhashtable_init(&tc->ht, &tc_ht_params); 3004 + if (err) 3005 + return err; 3006 + 3007 + tc->netdevice_nb.notifier_call = mlx5e_tc_netdev_event; 3008 + if (register_netdevice_notifier(&tc->netdevice_nb)) { 3009 + tc->netdevice_nb.notifier_call = NULL; 3010 + mlx5_core_warn(priv->mdev, "Failed to register netdev notifier\n"); 3011 + } 3012 + 3013 + return err; 2960 3014 } 2961 3015 2962 3016 static void _mlx5e_tc_del_flow(void *ptr, void *arg) ··· 3028 2968 void mlx5e_tc_nic_cleanup(struct mlx5e_priv *priv) 3029 2969 { 3030 2970 struct mlx5e_tc_table *tc = &priv->fs.tc; 2971 + 2972 + if (tc->netdevice_nb.notifier_call) 2973 + unregister_netdevice_notifier(&tc->netdevice_nb); 3031 2974 3032 2975 rhashtable_free_and_destroy(&tc->ht, _mlx5e_tc_del_flow, NULL); 3033 2976
+2 -2
drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
··· 2000 2000 u32 max_guarantee = 0; 2001 2001 int i; 2002 2002 2003 - for (i = 0; i <= esw->total_vports; i++) { 2003 + for (i = 0; i < esw->total_vports; i++) { 2004 2004 evport = &esw->vports[i]; 2005 2005 if (!evport->enabled || evport->info.min_rate < max_guarantee) 2006 2006 continue; ··· 2020 2020 int err; 2021 2021 int i; 2022 2022 2023 - for (i = 0; i <= esw->total_vports; i++) { 2023 + for (i = 0; i < esw->total_vports; i++) { 2024 2024 evport = &esw->vports[i]; 2025 2025 if (!evport->enabled) 2026 2026 continue;
+4 -1
drivers/net/ethernet/mellanox/mlx5/core/transobj.c
··· 475 475 476 476 for (i = 0; i < hp->num_channels; i++) { 477 477 mlx5_core_destroy_rq(hp->func_mdev, hp->rqn[i]); 478 - mlx5_core_destroy_sq(hp->peer_mdev, hp->sqn[i]); 478 + if (!hp->peer_gone) 479 + mlx5_core_destroy_sq(hp->peer_mdev, hp->sqn[i]); 479 480 } 480 481 } 481 482 ··· 568 567 MLX5_RQC_STATE_RST, 0, 0); 569 568 570 569 /* unset peer SQs */ 570 + if (hp->peer_gone) 571 + return; 571 572 for (i = 0; i < hp->num_channels; i++) 572 573 mlx5_hairpin_modify_sq(hp->peer_mdev, hp->sqn[i], MLX5_SQC_STATE_RDY, 573 574 MLX5_SQC_STATE_RST, 0, 0);
+2
include/linux/mlx5/transobj.h
··· 90 90 91 91 u32 *rqn; 92 92 u32 *sqn; 93 + 94 + bool peer_gone; 93 95 }; 94 96 95 97 struct mlx5_hairpin *