diff options
author | David S. Miller <davem@davemloft.net> | 2018-10-03 01:20:24 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-10-03 01:20:24 -0400 |
commit | b9f1bcb22091aacc0202c9ff6181e696cd1dc7dc (patch) | |
tree | d79f0a088f80dcf1e7f4986dcef1983a1b939643 | |
parent | 31c73cb5e296fa56093c1df270e1ebc818cae211 (diff) | |
parent | cee26487620bc9bc3c7db21b6984d91f7bae12ae (diff) |
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>
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/en.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/en/fs.h | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 65 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/eswitch.c | 4 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/transobj.c | 5 | ||||
-rw-r--r-- | include/linux/mlx5/transobj.h | 2 |
7 files changed, 76 insertions, 5 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h index db2cfcd21d43..0f189f873859 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h | |||
@@ -54,6 +54,7 @@ | |||
54 | #include "en_stats.h" | 54 | #include "en_stats.h" |
55 | #include "en/fs.h" | 55 | #include "en/fs.h" |
56 | 56 | ||
57 | extern const struct net_device_ops mlx5e_netdev_ops; | ||
57 | struct page_pool; | 58 | struct page_pool; |
58 | 59 | ||
59 | #define MLX5E_METADATA_ETHER_TYPE (0x8CE4) | 60 | #define MLX5E_METADATA_ETHER_TYPE (0x8CE4) |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h b/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h index bbf69e859b78..1431232c9a09 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h | |||
@@ -16,6 +16,8 @@ struct mlx5e_tc_table { | |||
16 | 16 | ||
17 | DECLARE_HASHTABLE(mod_hdr_tbl, 8); | 17 | DECLARE_HASHTABLE(mod_hdr_tbl, 8); |
18 | DECLARE_HASHTABLE(hairpin_tbl, 8); | 18 | DECLARE_HASHTABLE(hairpin_tbl, 8); |
19 | |||
20 | struct notifier_block netdevice_nb; | ||
19 | }; | 21 | }; |
20 | 22 | ||
21 | struct mlx5e_flow_table { | 23 | struct mlx5e_flow_table { |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index 54118b77dc1f..f291d1bf1558 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c | |||
@@ -4315,7 +4315,7 @@ static int mlx5e_xdp(struct net_device *dev, struct netdev_bpf *xdp) | |||
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 | .ndo_open = mlx5e_open, | 4319 | .ndo_open = mlx5e_open, |
4320 | .ndo_stop = mlx5e_close, | 4320 | .ndo_stop = mlx5e_close, |
4321 | .ndo_start_xmit = mlx5e_xmit, | 4321 | .ndo_start_xmit = mlx5e_xmit, |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c index 9fed54017659..85796727093e 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | |||
@@ -1368,6 +1368,9 @@ static int __parse_cls_flower(struct mlx5e_priv *priv, | |||
1368 | 1368 | ||
1369 | *match_level = MLX5_MATCH_L2; | 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 | if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_CVLAN)) { | 1376 | if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_CVLAN)) { |
@@ -2946,14 +2949,71 @@ int mlx5e_stats_flower(struct mlx5e_priv *priv, | |||
2946 | return 0; | 2949 | return 0; |
2947 | } | 2950 | } |
2948 | 2951 | ||
2952 | static void mlx5e_tc_hairpin_update_dead_peer(struct mlx5e_priv *priv, | ||
2953 | struct mlx5e_priv *peer_priv) | ||
2954 | { | ||
2955 | struct mlx5_core_dev *peer_mdev = peer_priv->mdev; | ||
2956 | struct mlx5e_hairpin_entry *hpe; | ||
2957 | u16 peer_vhca_id; | ||
2958 | int bkt; | ||
2959 | |||
2960 | if (!same_hw_devs(priv, peer_priv)) | ||
2961 | return; | ||
2962 | |||
2963 | peer_vhca_id = MLX5_CAP_GEN(peer_mdev, vhca_id); | ||
2964 | |||
2965 | hash_for_each(priv->fs.tc.hairpin_tbl, bkt, hpe, hairpin_hlist) { | ||
2966 | if (hpe->peer_vhca_id == peer_vhca_id) | ||
2967 | hpe->hp->pair->peer_gone = true; | ||
2968 | } | ||
2969 | } | ||
2970 | |||
2971 | static int mlx5e_tc_netdev_event(struct notifier_block *this, | ||
2972 | unsigned long event, void *ptr) | ||
2973 | { | ||
2974 | struct net_device *ndev = netdev_notifier_info_to_dev(ptr); | ||
2975 | struct mlx5e_flow_steering *fs; | ||
2976 | struct mlx5e_priv *peer_priv; | ||
2977 | struct mlx5e_tc_table *tc; | ||
2978 | struct mlx5e_priv *priv; | ||
2979 | |||
2980 | if (ndev->netdev_ops != &mlx5e_netdev_ops || | ||
2981 | event != NETDEV_UNREGISTER || | ||
2982 | ndev->reg_state == NETREG_REGISTERED) | ||
2983 | return NOTIFY_DONE; | ||
2984 | |||
2985 | tc = container_of(this, struct mlx5e_tc_table, netdevice_nb); | ||
2986 | fs = container_of(tc, struct mlx5e_flow_steering, tc); | ||
2987 | priv = container_of(fs, struct mlx5e_priv, fs); | ||
2988 | peer_priv = netdev_priv(ndev); | ||
2989 | if (priv == peer_priv || | ||
2990 | !(priv->netdev->features & NETIF_F_HW_TC)) | ||
2991 | return NOTIFY_DONE; | ||
2992 | |||
2993 | mlx5e_tc_hairpin_update_dead_peer(priv, peer_priv); | ||
2994 | |||
2995 | return NOTIFY_DONE; | ||
2996 | } | ||
2997 | |||
2949 | int mlx5e_tc_nic_init(struct mlx5e_priv *priv) | 2998 | int mlx5e_tc_nic_init(struct mlx5e_priv *priv) |
2950 | { | 2999 | { |
2951 | struct mlx5e_tc_table *tc = &priv->fs.tc; | 3000 | struct mlx5e_tc_table *tc = &priv->fs.tc; |
3001 | int err; | ||
2952 | 3002 | ||
2953 | hash_init(tc->mod_hdr_tbl); | 3003 | hash_init(tc->mod_hdr_tbl); |
2954 | hash_init(tc->hairpin_tbl); | 3004 | hash_init(tc->hairpin_tbl); |
2955 | 3005 | ||
2956 | return rhashtable_init(&tc->ht, &tc_ht_params); | 3006 | err = rhashtable_init(&tc->ht, &tc_ht_params); |
3007 | if (err) | ||
3008 | return err; | ||
3009 | |||
3010 | tc->netdevice_nb.notifier_call = mlx5e_tc_netdev_event; | ||
3011 | if (register_netdevice_notifier(&tc->netdevice_nb)) { | ||
3012 | tc->netdevice_nb.notifier_call = NULL; | ||
3013 | mlx5_core_warn(priv->mdev, "Failed to register netdev notifier\n"); | ||
3014 | } | ||
3015 | |||
3016 | return err; | ||
2957 | } | 3017 | } |
2958 | 3018 | ||
2959 | static void _mlx5e_tc_del_flow(void *ptr, void *arg) | 3019 | static void _mlx5e_tc_del_flow(void *ptr, void *arg) |
@@ -2969,6 +3029,9 @@ void mlx5e_tc_nic_cleanup(struct mlx5e_priv *priv) | |||
2969 | { | 3029 | { |
2970 | struct mlx5e_tc_table *tc = &priv->fs.tc; | 3030 | struct mlx5e_tc_table *tc = &priv->fs.tc; |
2971 | 3031 | ||
3032 | if (tc->netdevice_nb.notifier_call) | ||
3033 | unregister_netdevice_notifier(&tc->netdevice_nb); | ||
3034 | |||
2972 | rhashtable_free_and_destroy(&tc->ht, _mlx5e_tc_del_flow, NULL); | 3035 | rhashtable_free_and_destroy(&tc->ht, _mlx5e_tc_del_flow, NULL); |
2973 | 3036 | ||
2974 | if (!IS_ERR_OR_NULL(tc->t)) { | 3037 | if (!IS_ERR_OR_NULL(tc->t)) { |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c index 2b252cde5cc2..ea7dedc2d5ad 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c | |||
@@ -2000,7 +2000,7 @@ static u32 calculate_vports_min_rate_divider(struct mlx5_eswitch *esw) | |||
2000 | u32 max_guarantee = 0; | 2000 | u32 max_guarantee = 0; |
2001 | int i; | 2001 | int i; |
2002 | 2002 | ||
2003 | for (i = 0; i <= esw->total_vports; i++) { | 2003 | for (i = 0; i < esw->total_vports; i++) { |
2004 | evport = &esw->vports[i]; | 2004 | evport = &esw->vports[i]; |
2005 | if (!evport->enabled || evport->info.min_rate < max_guarantee) | 2005 | if (!evport->enabled || evport->info.min_rate < max_guarantee) |
2006 | continue; | 2006 | continue; |
@@ -2020,7 +2020,7 @@ static int normalize_vports_min_rate(struct mlx5_eswitch *esw, u32 divider) | |||
2020 | int err; | 2020 | int err; |
2021 | int i; | 2021 | int i; |
2022 | 2022 | ||
2023 | for (i = 0; i <= esw->total_vports; i++) { | 2023 | for (i = 0; i < esw->total_vports; i++) { |
2024 | evport = &esw->vports[i]; | 2024 | evport = &esw->vports[i]; |
2025 | if (!evport->enabled) | 2025 | if (!evport->enabled) |
2026 | continue; | 2026 | continue; |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/transobj.c b/drivers/net/ethernet/mellanox/mlx5/core/transobj.c index d2f76070ea7c..a1ee9a8a769e 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/transobj.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/transobj.c | |||
@@ -475,7 +475,8 @@ static void mlx5_hairpin_destroy_queues(struct mlx5_hairpin *hp) | |||
475 | 475 | ||
476 | for (i = 0; i < hp->num_channels; i++) { | 476 | for (i = 0; i < hp->num_channels; i++) { |
477 | mlx5_core_destroy_rq(hp->func_mdev, hp->rqn[i]); | 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 | ||
@@ -567,6 +568,8 @@ static void mlx5_hairpin_unpair_queues(struct mlx5_hairpin *hp) | |||
567 | MLX5_RQC_STATE_RST, 0, 0); | 568 | MLX5_RQC_STATE_RST, 0, 0); |
568 | 569 | ||
569 | /* unset peer SQs */ | 570 | /* unset peer SQs */ |
571 | if (hp->peer_gone) | ||
572 | return; | ||
570 | for (i = 0; i < hp->num_channels; i++) | 573 | for (i = 0; i < hp->num_channels; i++) |
571 | mlx5_hairpin_modify_sq(hp->peer_mdev, hp->sqn[i], MLX5_SQC_STATE_RDY, | 574 | mlx5_hairpin_modify_sq(hp->peer_mdev, hp->sqn[i], MLX5_SQC_STATE_RDY, |
572 | MLX5_SQC_STATE_RST, 0, 0); | 575 | MLX5_SQC_STATE_RST, 0, 0); |
diff --git a/include/linux/mlx5/transobj.h b/include/linux/mlx5/transobj.h index 83a33a1873a6..7f5ca2cd3a32 100644 --- a/include/linux/mlx5/transobj.h +++ b/include/linux/mlx5/transobj.h | |||
@@ -90,6 +90,8 @@ struct mlx5_hairpin { | |||
90 | 90 | ||
91 | u32 *rqn; | 91 | u32 *rqn; |
92 | u32 *sqn; | 92 | u32 *sqn; |
93 | |||
94 | bool peer_gone; | ||
93 | }; | 95 | }; |
94 | 96 | ||
95 | struct mlx5_hairpin * | 97 | struct mlx5_hairpin * |