| @@ -2946,14 +2946,71 @@ int mlx5e_stats_flower(struct mlx5e_priv *priv, · 2945 unmodified lines |
| 2946 | return 0; | 2946 | return 0; |
| 2947 | } | 2947 | } |
| 2948 | | 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 | |
| 2949 | int mlx5e_tc_nic_init(struct mlx5e_priv *priv) | 2995 | int mlx5e_tc_nic_init(struct mlx5e_priv *priv) |
| 2950 | { | 2996 | { |
| 2951 | struct mlx5e_tc_table *tc = &priv->fs.tc; | 2997 | struct mlx5e_tc_table *tc = &priv->fs.tc; |
| | 2998 | int err; |
| 2952 | | 2999 | |
| 2953 | hash_init(tc->mod_hdr_tbl); | 3000 | hash_init(tc->mod_hdr_tbl); |
| 2954 | hash_init(tc->hairpin_tbl); | 3001 | hash_init(tc->hairpin_tbl); |
| 2955 | | 3002 | |
| 2956 | 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; |
| 2957 | } | 3014 | } |
| 2958 | | 3015 | |
| 2959 | static void _mlx5e_tc_del_flow(void *ptr, void *arg) | 3016 | static void _mlx5e_tc_del_flow(void *ptr, void *arg) |
| @@ -2969,6 +3026,9 @@ void mlx5e_tc_nic_cleanup(struct mlx5e_priv *priv) · 9 unmodified lines |
| 2969 | { | 3026 | { |
| 2970 | struct mlx5e_tc_table *tc = &priv->fs.tc; | 3027 | struct mlx5e_tc_table *tc = &priv->fs.tc; |
| 2971 | | 3028 | |
| | 3029 | if (tc->netdevice_nb.notifier_call) |
| | 3030 | unregister_netdevice_notifier(&tc->netdevice_nb); |
| | 3031 | |
| 2972 | rhashtable_free_and_destroy(&tc->ht, _mlx5e_tc_del_flow, NULL); | 3032 | rhashtable_free_and_destroy(&tc->ht, _mlx5e_tc_del_flow, NULL); |
| 2973 | | 3033 | |
| 2974 | if (!IS_ERR_OR_NULL(tc->t)) { | 3034 | if (!IS_ERR_OR_NULL(tc->t)) { |