Skip to content

Commit 106be53

Browse files
ogerlitzSaeed Mahameed
authored andcommitted
net/mlx5e: Set per priority hairpin pairs
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 <[email protected]> Signed-off-by: Saeed Mahameed <[email protected]>
1 parent d882286 commit 106be53

File tree

1 file changed

+57
-7
lines changed
  • drivers/net/ethernet/mellanox/mlx5/core

1 file changed

+57
-7
lines changed

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

Lines changed: 57 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ struct mlx5e_hairpin_entry {
112112
struct list_head flows;
113113

114114
u16 peer_vhca_id;
115+
u8 prio;
115116
struct mlx5e_hairpin *hp;
116117
};
117118

@@ -333,20 +334,63 @@ static void mlx5e_hairpin_destroy(struct mlx5e_hairpin *hp)
333334
kvfree(hp);
334335
}
335336

337+
static inline u32 hash_hairpin_info(u16 peer_vhca_id, u8 prio)
338+
{
339+
return (peer_vhca_id << 16 | prio);
340+
}
341+
336342
static struct mlx5e_hairpin_entry *mlx5e_hairpin_get(struct mlx5e_priv *priv,
337-
u16 peer_vhca_id)
343+
u16 peer_vhca_id, u8 prio)
338344
{
339345
struct mlx5e_hairpin_entry *hpe;
346+
u32 hash_key = hash_hairpin_info(peer_vhca_id, prio);
340347

341348
hash_for_each_possible(priv->fs.tc.hairpin_tbl, hpe,
342-
hairpin_hlist, peer_vhca_id) {
343-
if (hpe->peer_vhca_id == peer_vhca_id)
349+
hairpin_hlist, hash_key) {
350+
if (hpe->peer_vhca_id == peer_vhca_id && hpe->prio == prio)
344351
return hpe;
345352
}
346353

347354
return NULL;
348355
}
349356

357+
#define UNKNOWN_MATCH_PRIO 8
358+
359+
static int mlx5e_hairpin_get_prio(struct mlx5e_priv *priv,
360+
struct mlx5_flow_spec *spec, u8 *match_prio)
361+
{
362+
void *headers_c, *headers_v;
363+
u8 prio_val, prio_mask = 0;
364+
bool vlan_present;
365+
366+
#ifdef CONFIG_MLX5_CORE_EN_DCB
367+
if (priv->dcbx_dp.trust_state != MLX5_QPTS_TRUST_PCP) {
368+
netdev_warn(priv->netdev,
369+
"only PCP trust state supported for hairpin\n");
370+
return -EOPNOTSUPP;
371+
}
372+
#endif
373+
headers_c = MLX5_ADDR_OF(fte_match_param, spec->match_criteria, outer_headers);
374+
headers_v = MLX5_ADDR_OF(fte_match_param, spec->match_value, outer_headers);
375+
376+
vlan_present = MLX5_GET(fte_match_set_lyr_2_4, headers_v, cvlan_tag);
377+
if (vlan_present) {
378+
prio_mask = MLX5_GET(fte_match_set_lyr_2_4, headers_c, first_prio);
379+
prio_val = MLX5_GET(fte_match_set_lyr_2_4, headers_v, first_prio);
380+
}
381+
382+
if (!vlan_present || !prio_mask) {
383+
prio_val = UNKNOWN_MATCH_PRIO;
384+
} else if (prio_mask != 0x7) {
385+
netdev_warn(priv->netdev,
386+
"masked priority match not supported for hairpin\n");
387+
return -EOPNOTSUPP;
388+
}
389+
390+
*match_prio = prio_val;
391+
return 0;
392+
}
393+
350394
static int mlx5e_hairpin_flow_add(struct mlx5e_priv *priv,
351395
struct mlx5e_tc_flow *flow,
352396
struct mlx5e_tc_flow_parse_attr *parse_attr)
@@ -356,6 +400,7 @@ static int mlx5e_hairpin_flow_add(struct mlx5e_priv *priv,
356400
struct mlx5_core_dev *peer_mdev;
357401
struct mlx5e_hairpin_entry *hpe;
358402
struct mlx5e_hairpin *hp;
403+
u8 match_prio;
359404
u16 peer_id;
360405
int err;
361406

@@ -366,7 +411,10 @@ static int mlx5e_hairpin_flow_add(struct mlx5e_priv *priv,
366411
}
367412

368413
peer_id = MLX5_CAP_GEN(peer_mdev, vhca_id);
369-
hpe = mlx5e_hairpin_get(priv, peer_id);
414+
err = mlx5e_hairpin_get_prio(priv, &parse_attr->spec, &match_prio);
415+
if (err)
416+
return err;
417+
hpe = mlx5e_hairpin_get(priv, peer_id, match_prio);
370418
if (hpe)
371419
goto attach_flow;
372420

@@ -376,6 +424,7 @@ static int mlx5e_hairpin_flow_add(struct mlx5e_priv *priv,
376424

377425
INIT_LIST_HEAD(&hpe->flows);
378426
hpe->peer_vhca_id = peer_id;
427+
hpe->prio = match_prio;
379428

380429
params.log_data_size = 15;
381430
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,
390439
goto create_hairpin_err;
391440
}
392441

393-
netdev_dbg(priv->netdev, "add hairpin: tirn %x rqn %x peer %s sqn %x log data size %d\n",
442+
netdev_dbg(priv->netdev, "add hairpin: tirn %x rqn %x peer %s sqn %x prio %d log data size %d\n",
394443
hp->tirn, hp->pair->rqn, hp->pair->peer_mdev->priv.name,
395-
hp->pair->sqn, params.log_data_size);
444+
hp->pair->sqn, match_prio, params.log_data_size);
396445

397446
hpe->hp = hp;
398-
hash_add(priv->fs.tc.hairpin_tbl, &hpe->hairpin_hlist, peer_id);
447+
hash_add(priv->fs.tc.hairpin_tbl, &hpe->hairpin_hlist,
448+
hash_hairpin_info(peer_id, match_prio));
399449

400450
attach_flow:
401451
flow->nic_attr->hairpin_tirn = hpe->hp->tirn;

0 commit comments

Comments
 (0)