Skip to content

Commit 248d3b4

Browse files
Tariq ToukanSaeed Mahameed
authored andcommitted
net/mlx5e: Support flow classification into RSS contexts
Extend the existing flow classification support, to steer flows not only directly to a receive ring, but also into the new RSS contexts. Create needed TIR objects on demand, and hold reference on the RSS context. Signed-off-by: Tariq Toukan <[email protected]> Reviewed-by: Maxim Mikityanskiy <[email protected]> Signed-off-by: Saeed Mahameed <[email protected]>
1 parent f01cc58 commit 248d3b4

File tree

5 files changed

+131
-21
lines changed

5 files changed

+131
-21
lines changed

drivers/net/ethernet/mellanox/mlx5/core/en/rss.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,30 @@ u32 mlx5e_rss_get_tirn(struct mlx5e_rss *rss, enum mlx5_traffic_types tt,
367367
return mlx5e_tir_get_tirn(tir);
368368
}
369369

370+
/* Fill the "tirn" output parameter.
371+
* Create the requested TIR if it's its first usage.
372+
*/
373+
int mlx5e_rss_obtain_tirn(struct mlx5e_rss *rss,
374+
enum mlx5_traffic_types tt,
375+
const struct mlx5e_lro_param *init_lro_param,
376+
bool inner, u32 *tirn)
377+
{
378+
struct mlx5e_tir *tir;
379+
380+
tir = rss_get_tir(rss, tt, inner);
381+
if (!tir) { /* TIR doesn't exist, create one */
382+
int err;
383+
384+
err = mlx5e_rss_create_tir(rss, tt, init_lro_param, inner);
385+
if (err)
386+
return err;
387+
tir = rss_get_tir(rss, tt, inner);
388+
}
389+
390+
*tirn = mlx5e_tir_get_tirn(tir);
391+
return 0;
392+
}
393+
370394
static void mlx5e_rss_apply(struct mlx5e_rss *rss, u32 *rqns, unsigned int num_rqns)
371395
{
372396
int err;

drivers/net/ethernet/mellanox/mlx5/core/en/rss.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ unsigned int mlx5e_rss_refcnt_read(struct mlx5e_rss *rss);
2828

2929
u32 mlx5e_rss_get_tirn(struct mlx5e_rss *rss, enum mlx5_traffic_types tt,
3030
bool inner);
31+
int mlx5e_rss_obtain_tirn(struct mlx5e_rss *rss,
32+
enum mlx5_traffic_types tt,
33+
const struct mlx5e_lro_param *init_lro_param,
34+
bool inner, u32 *tirn);
35+
3136
void mlx5e_rss_enable(struct mlx5e_rss *rss, u32 *rqns, unsigned int num_rqns);
3237
void mlx5e_rss_disable(struct mlx5e_rss *rss);
3338

drivers/net/ethernet/mellanox/mlx5/core/en/rx_res.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,28 @@ int mlx5e_rx_res_rss_cnt(struct mlx5e_rx_res *res)
245245
return cnt;
246246
}
247247

248+
int mlx5e_rx_res_rss_index(struct mlx5e_rx_res *res, struct mlx5e_rss *rss)
249+
{
250+
int i;
251+
252+
if (!rss)
253+
return -EINVAL;
254+
255+
for (i = 0; i < MLX5E_MAX_NUM_RSS; i++)
256+
if (rss == res->rss[i])
257+
return i;
258+
259+
return -ENOENT;
260+
}
261+
262+
struct mlx5e_rss *mlx5e_rx_res_rss_get(struct mlx5e_rx_res *res, u32 rss_idx)
263+
{
264+
if (rss_idx >= MLX5E_MAX_NUM_RSS)
265+
return NULL;
266+
267+
return res->rss[rss_idx];
268+
}
269+
248270
/* End of API rx_res_rss_* */
249271

250272
struct mlx5e_rx_res *mlx5e_rx_res_alloc(void)

drivers/net/ethernet/mellanox/mlx5/core/en/rx_res.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ int mlx5e_rx_res_lro_set_param(struct mlx5e_rx_res *res, struct mlx5e_lro_param
6262
int mlx5e_rx_res_rss_init(struct mlx5e_rx_res *res, u32 *rss_idx, unsigned int init_nch);
6363
int mlx5e_rx_res_rss_destroy(struct mlx5e_rx_res *res, u32 rss_idx);
6464
int mlx5e_rx_res_rss_cnt(struct mlx5e_rx_res *res);
65+
int mlx5e_rx_res_rss_index(struct mlx5e_rx_res *res, struct mlx5e_rss *rss);
66+
struct mlx5e_rss *mlx5e_rx_res_rss_get(struct mlx5e_rx_res *res, u32 rss_idx);
6567

6668
/* Workaround for hairpin */
6769
struct mlx5e_rss_params_hash mlx5e_rx_res_get_current_hash(struct mlx5e_rx_res *res);

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

Lines changed: 78 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,19 @@
3535
#include "en/params.h"
3636
#include "en/xsk/pool.h"
3737

38+
static int flow_type_to_traffic_type(u32 flow_type);
39+
40+
static u32 flow_type_mask(u32 flow_type)
41+
{
42+
return flow_type & ~(FLOW_EXT | FLOW_MAC_EXT | FLOW_RSS);
43+
}
44+
3845
struct mlx5e_ethtool_rule {
3946
struct list_head list;
4047
struct ethtool_rx_flow_spec flow_spec;
4148
struct mlx5_flow_handle *rule;
4249
struct mlx5e_ethtool_table *eth_ft;
50+
struct mlx5e_rss *rss;
4351
};
4452

4553
static void put_flow_table(struct mlx5e_ethtool_table *eth_ft)
@@ -66,7 +74,7 @@ static struct mlx5e_ethtool_table *get_flow_table(struct mlx5e_priv *priv,
6674
int table_size;
6775
int prio;
6876

69-
switch (fs->flow_type & ~(FLOW_EXT | FLOW_MAC_EXT)) {
77+
switch (flow_type_mask(fs->flow_type)) {
7078
case TCP_V4_FLOW:
7179
case UDP_V4_FLOW:
7280
case TCP_V6_FLOW:
@@ -329,7 +337,7 @@ static int set_flow_attrs(u32 *match_c, u32 *match_v,
329337
outer_headers);
330338
void *outer_headers_v = MLX5_ADDR_OF(fte_match_param, match_v,
331339
outer_headers);
332-
u32 flow_type = fs->flow_type & ~(FLOW_EXT | FLOW_MAC_EXT);
340+
u32 flow_type = flow_type_mask(fs->flow_type);
333341

334342
switch (flow_type) {
335343
case TCP_V4_FLOW:
@@ -397,10 +405,53 @@ static bool outer_header_zero(u32 *match_criteria)
397405
size - 1);
398406
}
399407

408+
static int flow_get_tirn(struct mlx5e_priv *priv,
409+
struct mlx5e_ethtool_rule *eth_rule,
410+
struct ethtool_rx_flow_spec *fs,
411+
u32 rss_context, u32 *tirn)
412+
{
413+
if (fs->flow_type & FLOW_RSS) {
414+
struct mlx5e_lro_param lro_param;
415+
struct mlx5e_rss *rss;
416+
u32 flow_type;
417+
int err;
418+
int tt;
419+
420+
rss = mlx5e_rx_res_rss_get(priv->rx_res, rss_context);
421+
if (!rss)
422+
return -ENOENT;
423+
424+
flow_type = flow_type_mask(fs->flow_type);
425+
tt = flow_type_to_traffic_type(flow_type);
426+
if (tt < 0)
427+
return -EINVAL;
428+
429+
lro_param = mlx5e_get_lro_param(&priv->channels.params);
430+
err = mlx5e_rss_obtain_tirn(rss, tt, &lro_param, false, tirn);
431+
if (err)
432+
return err;
433+
eth_rule->rss = rss;
434+
mlx5e_rss_refcnt_inc(eth_rule->rss);
435+
} else {
436+
struct mlx5e_params *params = &priv->channels.params;
437+
enum mlx5e_rq_group group;
438+
u16 ix;
439+
440+
mlx5e_qid_get_ch_and_group(params, fs->ring_cookie, &ix, &group);
441+
442+
*tirn = group == MLX5E_RQ_GROUP_XSK ?
443+
mlx5e_rx_res_get_tirn_xsk(priv->rx_res, ix) :
444+
mlx5e_rx_res_get_tirn_direct(priv->rx_res, ix);
445+
}
446+
447+
return 0;
448+
}
449+
400450
static struct mlx5_flow_handle *
401451
add_ethtool_flow_rule(struct mlx5e_priv *priv,
452+
struct mlx5e_ethtool_rule *eth_rule,
402453
struct mlx5_flow_table *ft,
403-
struct ethtool_rx_flow_spec *fs)
454+
struct ethtool_rx_flow_spec *fs, u32 rss_context)
404455
{
405456
struct mlx5_flow_act flow_act = { .flags = FLOW_ACT_NO_APPEND };
406457
struct mlx5_flow_destination *dst = NULL;
@@ -419,23 +470,17 @@ add_ethtool_flow_rule(struct mlx5e_priv *priv,
419470
if (fs->ring_cookie == RX_CLS_FLOW_DISC) {
420471
flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP;
421472
} else {
422-
struct mlx5e_params *params = &priv->channels.params;
423-
enum mlx5e_rq_group group;
424-
u16 ix;
425-
426-
mlx5e_qid_get_ch_and_group(params, fs->ring_cookie, &ix, &group);
427-
428473
dst = kzalloc(sizeof(*dst), GFP_KERNEL);
429474
if (!dst) {
430475
err = -ENOMEM;
431476
goto free;
432477
}
433478

479+
err = flow_get_tirn(priv, eth_rule, fs, rss_context, &dst->tir_num);
480+
if (err)
481+
goto free;
482+
434483
dst->type = MLX5_FLOW_DESTINATION_TYPE_TIR;
435-
if (group == MLX5E_RQ_GROUP_XSK)
436-
dst->tir_num = mlx5e_rx_res_get_tirn_xsk(priv->rx_res, ix);
437-
else
438-
dst->tir_num = mlx5e_rx_res_get_tirn_direct(priv->rx_res, ix);
439484
flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
440485
}
441486

@@ -459,6 +504,8 @@ static void del_ethtool_rule(struct mlx5e_priv *priv,
459504
{
460505
if (eth_rule->rule)
461506
mlx5_del_flow_rules(eth_rule->rule);
507+
if (eth_rule->rss)
508+
mlx5e_rss_refcnt_dec(eth_rule->rss);
462509
list_del(&eth_rule->list);
463510
priv->fs.ethtool.tot_num_rules--;
464511
put_flow_table(eth_rule->eth_ft);
@@ -619,7 +666,7 @@ static int validate_flow(struct mlx5e_priv *priv,
619666
fs->ring_cookie))
620667
return -EINVAL;
621668

622-
switch (fs->flow_type & ~(FLOW_EXT | FLOW_MAC_EXT)) {
669+
switch (flow_type_mask(fs->flow_type)) {
623670
case ETHER_FLOW:
624671
num_tuples += validate_ethter(fs);
625672
break;
@@ -668,7 +715,7 @@ static int validate_flow(struct mlx5e_priv *priv,
668715

669716
static int
670717
mlx5e_ethtool_flow_replace(struct mlx5e_priv *priv,
671-
struct ethtool_rx_flow_spec *fs)
718+
struct ethtool_rx_flow_spec *fs, u32 rss_context)
672719
{
673720
struct mlx5e_ethtool_table *eth_ft;
674721
struct mlx5e_ethtool_rule *eth_rule;
@@ -699,7 +746,7 @@ mlx5e_ethtool_flow_replace(struct mlx5e_priv *priv,
699746
err = -EINVAL;
700747
goto del_ethtool_rule;
701748
}
702-
rule = add_ethtool_flow_rule(priv, eth_ft->ft, fs);
749+
rule = add_ethtool_flow_rule(priv, eth_rule, eth_ft->ft, fs, rss_context);
703750
if (IS_ERR(rule)) {
704751
err = PTR_ERR(rule);
705752
goto del_ethtool_rule;
@@ -745,10 +792,20 @@ mlx5e_ethtool_get_flow(struct mlx5e_priv *priv,
745792
return -EINVAL;
746793

747794
list_for_each_entry(eth_rule, &priv->fs.ethtool.rules, list) {
748-
if (eth_rule->flow_spec.location == location) {
749-
info->fs = eth_rule->flow_spec;
795+
int index;
796+
797+
if (eth_rule->flow_spec.location != location)
798+
continue;
799+
if (!info)
750800
return 0;
751-
}
801+
info->fs = eth_rule->flow_spec;
802+
if (!eth_rule->rss)
803+
return 0;
804+
index = mlx5e_rx_res_rss_index(priv->rx_res, eth_rule->rss);
805+
if (index < 0)
806+
return index;
807+
info->rss_context = index;
808+
return 0;
752809
}
753810

754811
return -ENOENT;
@@ -764,7 +821,7 @@ mlx5e_ethtool_get_all_flows(struct mlx5e_priv *priv,
764821

765822
info->data = MAX_NUM_OF_ETHTOOL_RULES;
766823
while ((!err || err == -ENOENT) && idx < info->rule_cnt) {
767-
err = mlx5e_ethtool_get_flow(priv, info, location);
824+
err = mlx5e_ethtool_get_flow(priv, NULL, location);
768825
if (!err)
769826
rule_locs[idx++] = location;
770827
location++;
@@ -887,7 +944,7 @@ int mlx5e_ethtool_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
887944

888945
switch (cmd->cmd) {
889946
case ETHTOOL_SRXCLSRLINS:
890-
err = mlx5e_ethtool_flow_replace(priv, &cmd->fs);
947+
err = mlx5e_ethtool_flow_replace(priv, &cmd->fs, cmd->rss_context);
891948
break;
892949
case ETHTOOL_SRXCLSRLDEL:
893950
err = mlx5e_ethtool_flow_remove(priv, cmd->fs.location);

0 commit comments

Comments
 (0)