From patchwork Fri Jan 19 21:34:44 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Saeed Mahameed X-Patchwork-Id: 863822 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3zNYyt4mtNz9s75 for ; Sat, 20 Jan 2018 08:35:34 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756628AbeASVfc (ORCPT ); Fri, 19 Jan 2018 16:35:32 -0500 Received: from mail-il-dmz.mellanox.com ([193.47.165.129]:54342 "EHLO mellanox.co.il" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1756471AbeASVfT (ORCPT ); Fri, 19 Jan 2018 16:35:19 -0500 Received: from Internal Mail-Server by MTLPINE1 (envelope-from saeedm@mellanox.com) with ESMTPS (AES256-SHA encrypted); 19 Jan 2018 23:35:13 +0200 Received: from sws.mtl.labs.mlnx (reg-l-vrt-045-015.mtl.labs.mlnx [10.135.45.15]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id w0JLZDCo009926; Fri, 19 Jan 2018 23:35:13 +0200 From: Saeed Mahameed To: "David S. Miller" Cc: netdev@vger.kernel.org, Or Gerlitz , Saeed Mahameed Subject: [net-next 02/15] net/mlx5e: Set per priority hairpin pairs Date: Fri, 19 Jan 2018 23:34:44 +0200 Message-Id: <20180119213457.23378-3-saeedm@mellanox.com> X-Mailer: git-send-email 2.13.0 In-Reply-To: <20180119213457.23378-1-saeedm@mellanox.com> References: <20180119213457.23378-1-saeedm@mellanox.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Or Gerlitz As part of the QoS model, on xmit, the HW mandates that all packets going through a given SQ have the same priority. To align hairpin SQs with that, we use the priority given as part of the matching for the hairpin hash key. This ensures that flows/packets mapped to different HW priorities will go through different hairpin instances. If no priority is given for matching, we treat that as an 8th priority, this is in order not to harm cases where priority is specified. Only the PCP priority trust model is supported. Signed-off-by: Or Gerlitz Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 64 ++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c index fac8c91c261b..cd54cd2b2328 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c @@ -112,6 +112,7 @@ struct mlx5e_hairpin_entry { struct list_head flows; u16 peer_vhca_id; + u8 prio; struct mlx5e_hairpin *hp; }; @@ -333,20 +334,63 @@ static void mlx5e_hairpin_destroy(struct mlx5e_hairpin *hp) kvfree(hp); } +static inline u32 hash_hairpin_info(u16 peer_vhca_id, u8 prio) +{ + return (peer_vhca_id << 16 | prio); +} + static struct mlx5e_hairpin_entry *mlx5e_hairpin_get(struct mlx5e_priv *priv, - u16 peer_vhca_id) + u16 peer_vhca_id, u8 prio) { struct mlx5e_hairpin_entry *hpe; + u32 hash_key = hash_hairpin_info(peer_vhca_id, prio); hash_for_each_possible(priv->fs.tc.hairpin_tbl, hpe, - hairpin_hlist, peer_vhca_id) { - if (hpe->peer_vhca_id == peer_vhca_id) + hairpin_hlist, hash_key) { + if (hpe->peer_vhca_id == peer_vhca_id && hpe->prio == prio) return hpe; } return NULL; } +#define UNKNOWN_MATCH_PRIO 8 + +static int mlx5e_hairpin_get_prio(struct mlx5e_priv *priv, + struct mlx5_flow_spec *spec, u8 *match_prio) +{ + void *headers_c, *headers_v; + u8 prio_val, prio_mask = 0; + bool vlan_present; + +#ifdef CONFIG_MLX5_CORE_EN_DCB + if (priv->dcbx_dp.trust_state != MLX5_QPTS_TRUST_PCP) { + netdev_warn(priv->netdev, + "only PCP trust state supported for hairpin\n"); + return -EOPNOTSUPP; + } +#endif + headers_c = MLX5_ADDR_OF(fte_match_param, spec->match_criteria, outer_headers); + headers_v = MLX5_ADDR_OF(fte_match_param, spec->match_value, outer_headers); + + vlan_present = MLX5_GET(fte_match_set_lyr_2_4, headers_v, cvlan_tag); + if (vlan_present) { + prio_mask = MLX5_GET(fte_match_set_lyr_2_4, headers_c, first_prio); + prio_val = MLX5_GET(fte_match_set_lyr_2_4, headers_v, first_prio); + } + + if (!vlan_present || !prio_mask) { + prio_val = UNKNOWN_MATCH_PRIO; + } else if (prio_mask != 0x7) { + netdev_warn(priv->netdev, + "masked priority match not supported for hairpin\n"); + return -EOPNOTSUPP; + } + + *match_prio = prio_val; + return 0; +} + static int mlx5e_hairpin_flow_add(struct mlx5e_priv *priv, struct mlx5e_tc_flow *flow, struct mlx5e_tc_flow_parse_attr *parse_attr) @@ -356,6 +400,7 @@ static int mlx5e_hairpin_flow_add(struct mlx5e_priv *priv, struct mlx5_core_dev *peer_mdev; struct mlx5e_hairpin_entry *hpe; struct mlx5e_hairpin *hp; + u8 match_prio; u16 peer_id; int err; @@ -366,7 +411,10 @@ static int mlx5e_hairpin_flow_add(struct mlx5e_priv *priv, } peer_id = MLX5_CAP_GEN(peer_mdev, vhca_id); - hpe = mlx5e_hairpin_get(priv, peer_id); + err = mlx5e_hairpin_get_prio(priv, &parse_attr->spec, &match_prio); + if (err) + return err; + hpe = mlx5e_hairpin_get(priv, peer_id, match_prio); if (hpe) goto attach_flow; @@ -376,6 +424,7 @@ static int mlx5e_hairpin_flow_add(struct mlx5e_priv *priv, INIT_LIST_HEAD(&hpe->flows); hpe->peer_vhca_id = peer_id; + hpe->prio = match_prio; params.log_data_size = 15; params.log_data_size = min_t(u8, params.log_data_size, @@ -390,12 +439,13 @@ static int mlx5e_hairpin_flow_add(struct mlx5e_priv *priv, goto create_hairpin_err; } - netdev_dbg(priv->netdev, "add hairpin: tirn %x rqn %x peer %s sqn %x log data size %d\n", + netdev_dbg(priv->netdev, "add hairpin: tirn %x rqn %x peer %s sqn %x prio %d log data size %d\n", hp->tirn, hp->pair->rqn, hp->pair->peer_mdev->priv.name, - hp->pair->sqn, params.log_data_size); + hp->pair->sqn, match_prio, params.log_data_size); hpe->hp = hp; - hash_add(priv->fs.tc.hairpin_tbl, &hpe->hairpin_hlist, peer_id); + hash_add(priv->fs.tc.hairpin_tbl, &hpe->hairpin_hlist, + hash_hairpin_info(peer_id, match_prio)); attach_flow: flow->nic_attr->hairpin_tirn = hpe->hp->tirn;