Skip to content

Commit 40e6ad9

Browse files
Tariq ToukanSaeed Mahameed
authored andcommitted
net/mlx5e: Support cross-vhca RSS
Implement driver support for the HW feature that allows RX steering of one device to target other device's RQs. In SD multi-pf netdev mode, we set the secondaries into silent mode, disconnecting them from the network. This feature is then used to steer traffic from the primary to the secondaries. Signed-off-by: Tariq Toukan <[email protected]> Reviewed-by: Gal Pressman <[email protected]> Signed-off-by: Saeed Mahameed <[email protected]>
1 parent 67936e1 commit 40e6ad9

File tree

10 files changed

+179
-57
lines changed

10 files changed

+179
-57
lines changed

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,20 +23,26 @@ bool mlx5e_channels_is_xsk(struct mlx5e_channels *chs, unsigned int ix)
2323
return test_bit(MLX5E_CHANNEL_STATE_XSK, c->state);
2424
}
2525

26-
void mlx5e_channels_get_regular_rqn(struct mlx5e_channels *chs, unsigned int ix, u32 *rqn)
26+
void mlx5e_channels_get_regular_rqn(struct mlx5e_channels *chs, unsigned int ix, u32 *rqn,
27+
u32 *vhca_id)
2728
{
2829
struct mlx5e_channel *c = mlx5e_channels_get(chs, ix);
2930

3031
*rqn = c->rq.rqn;
32+
if (vhca_id)
33+
*vhca_id = MLX5_CAP_GEN(c->mdev, vhca_id);
3134
}
3235

33-
void mlx5e_channels_get_xsk_rqn(struct mlx5e_channels *chs, unsigned int ix, u32 *rqn)
36+
void mlx5e_channels_get_xsk_rqn(struct mlx5e_channels *chs, unsigned int ix, u32 *rqn,
37+
u32 *vhca_id)
3438
{
3539
struct mlx5e_channel *c = mlx5e_channels_get(chs, ix);
3640

3741
WARN_ON_ONCE(!test_bit(MLX5E_CHANNEL_STATE_XSK, c->state));
3842

3943
*rqn = c->xskrq.rqn;
44+
if (vhca_id)
45+
*vhca_id = MLX5_CAP_GEN(c->mdev, vhca_id);
4046
}
4147

4248
bool mlx5e_channels_get_ptp_rqn(struct mlx5e_channels *chs, u32 *rqn)

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@ struct mlx5e_channels;
1010

1111
unsigned int mlx5e_channels_get_num(struct mlx5e_channels *chs);
1212
bool mlx5e_channels_is_xsk(struct mlx5e_channels *chs, unsigned int ix);
13-
void mlx5e_channels_get_regular_rqn(struct mlx5e_channels *chs, unsigned int ix, u32 *rqn);
14-
void mlx5e_channels_get_xsk_rqn(struct mlx5e_channels *chs, unsigned int ix, u32 *rqn);
13+
void mlx5e_channels_get_regular_rqn(struct mlx5e_channels *chs, unsigned int ix, u32 *rqn,
14+
u32 *vhca_id);
15+
void mlx5e_channels_get_xsk_rqn(struct mlx5e_channels *chs, unsigned int ix, u32 *rqn,
16+
u32 *vhca_id);
1517
bool mlx5e_channels_get_ptp_rqn(struct mlx5e_channels *chs, u32 *rqn);
1618

1719
#endif /* __MLX5_EN_CHANNELS_H__ */

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

Lines changed: 100 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,33 @@
44
#include "rqt.h"
55
#include <linux/mlx5/transobj.h>
66

7+
static bool verify_num_vhca_ids(struct mlx5_core_dev *mdev, u32 *vhca_ids,
8+
unsigned int size)
9+
{
10+
unsigned int max_num_vhca_id = MLX5_CAP_GEN_2(mdev, max_rqt_vhca_id);
11+
int i;
12+
13+
/* Verify that all vhca_ids are in range [0, max_num_vhca_ids - 1] */
14+
for (i = 0; i < size; i++)
15+
if (vhca_ids[i] >= max_num_vhca_id)
16+
return false;
17+
return true;
18+
}
19+
20+
static bool rqt_verify_vhca_ids(struct mlx5_core_dev *mdev, u32 *vhca_ids,
21+
unsigned int size)
22+
{
23+
if (!vhca_ids)
24+
return true;
25+
26+
if (!MLX5_CAP_GEN(mdev, cross_vhca_rqt))
27+
return false;
28+
if (!verify_num_vhca_ids(mdev, vhca_ids, size))
29+
return false;
30+
31+
return true;
32+
}
33+
734
void mlx5e_rss_params_indir_init_uniform(struct mlx5e_rss_params_indir *indir,
835
unsigned int num_channels)
936
{
@@ -13,30 +40,48 @@ void mlx5e_rss_params_indir_init_uniform(struct mlx5e_rss_params_indir *indir,
1340
indir->table[i] = i % num_channels;
1441
}
1542

43+
static void fill_rqn_list(void *rqtc, u32 *rqns, u32 *vhca_ids, unsigned int size)
44+
{
45+
unsigned int i;
46+
47+
if (vhca_ids) {
48+
MLX5_SET(rqtc, rqtc, rq_vhca_id_format, 1);
49+
for (i = 0; i < size; i++) {
50+
MLX5_SET(rqtc, rqtc, rq_vhca[i].rq_num, rqns[i]);
51+
MLX5_SET(rqtc, rqtc, rq_vhca[i].rq_vhca_id, vhca_ids[i]);
52+
}
53+
} else {
54+
for (i = 0; i < size; i++)
55+
MLX5_SET(rqtc, rqtc, rq_num[i], rqns[i]);
56+
}
57+
}
1658
static int mlx5e_rqt_init(struct mlx5e_rqt *rqt, struct mlx5_core_dev *mdev,
17-
u16 max_size, u32 *init_rqns, u16 init_size)
59+
u16 max_size, u32 *init_rqns, u32 *init_vhca_ids, u16 init_size)
1860
{
61+
int entry_sz;
1962
void *rqtc;
2063
int inlen;
2164
int err;
2265
u32 *in;
23-
int i;
66+
67+
if (!rqt_verify_vhca_ids(mdev, init_vhca_ids, init_size))
68+
return -EOPNOTSUPP;
2469

2570
rqt->mdev = mdev;
2671
rqt->size = max_size;
2772

28-
inlen = MLX5_ST_SZ_BYTES(create_rqt_in) + sizeof(u32) * init_size;
73+
entry_sz = init_vhca_ids ? MLX5_ST_SZ_BYTES(rq_vhca) : MLX5_ST_SZ_BYTES(rq_num);
74+
inlen = MLX5_ST_SZ_BYTES(create_rqt_in) + entry_sz * init_size;
2975
in = kvzalloc(inlen, GFP_KERNEL);
3076
if (!in)
3177
return -ENOMEM;
3278

3379
rqtc = MLX5_ADDR_OF(create_rqt_in, in, rqt_context);
3480

3581
MLX5_SET(rqtc, rqtc, rqt_max_size, rqt->size);
36-
3782
MLX5_SET(rqtc, rqtc, rqt_actual_size, init_size);
38-
for (i = 0; i < init_size; i++)
39-
MLX5_SET(rqtc, rqtc, rq_num[i], init_rqns[i]);
83+
84+
fill_rqn_list(rqtc, init_rqns, init_vhca_ids, init_size);
4085

4186
err = mlx5_core_create_rqt(rqt->mdev, in, inlen, &rqt->rqtn);
4287

@@ -49,7 +94,7 @@ int mlx5e_rqt_init_direct(struct mlx5e_rqt *rqt, struct mlx5_core_dev *mdev,
4994
{
5095
u16 max_size = indir_enabled ? indir_table_size : 1;
5196

52-
return mlx5e_rqt_init(rqt, mdev, max_size, &init_rqn, 1);
97+
return mlx5e_rqt_init(rqt, mdev, max_size, &init_rqn, NULL, 1);
5398
}
5499

55100
static int mlx5e_bits_invert(unsigned long a, int size)
@@ -63,7 +108,8 @@ static int mlx5e_bits_invert(unsigned long a, int size)
63108
return inv;
64109
}
65110

66-
static int mlx5e_calc_indir_rqns(u32 *rss_rqns, u32 *rqns, unsigned int num_rqns,
111+
static int mlx5e_calc_indir_rqns(u32 *rss_rqns, u32 *rqns, u32 *rss_vhca_ids, u32 *vhca_ids,
112+
unsigned int num_rqns,
67113
u8 hfunc, struct mlx5e_rss_params_indir *indir)
68114
{
69115
unsigned int i;
@@ -82,30 +128,42 @@ static int mlx5e_calc_indir_rqns(u32 *rss_rqns, u32 *rqns, unsigned int num_rqns
82128
*/
83129
return -EINVAL;
84130
rss_rqns[i] = rqns[ix];
131+
if (vhca_ids)
132+
rss_vhca_ids[i] = vhca_ids[ix];
85133
}
86134

87135
return 0;
88136
}
89137

90138
int mlx5e_rqt_init_indir(struct mlx5e_rqt *rqt, struct mlx5_core_dev *mdev,
91-
u32 *rqns, unsigned int num_rqns,
139+
u32 *rqns, u32 *vhca_ids, unsigned int num_rqns,
92140
u8 hfunc, struct mlx5e_rss_params_indir *indir)
93141
{
94-
u32 *rss_rqns;
142+
u32 *rss_rqns, *rss_vhca_ids = NULL;
95143
int err;
96144

97145
rss_rqns = kvmalloc_array(indir->actual_table_size, sizeof(*rss_rqns), GFP_KERNEL);
98146
if (!rss_rqns)
99147
return -ENOMEM;
100148

101-
err = mlx5e_calc_indir_rqns(rss_rqns, rqns, num_rqns, hfunc, indir);
149+
if (vhca_ids) {
150+
rss_vhca_ids = kvmalloc_array(indir->actual_table_size, sizeof(*rss_vhca_ids),
151+
GFP_KERNEL);
152+
if (!rss_vhca_ids) {
153+
kvfree(rss_rqns);
154+
return -ENOMEM;
155+
}
156+
}
157+
158+
err = mlx5e_calc_indir_rqns(rss_rqns, rqns, rss_vhca_ids, vhca_ids, num_rqns, hfunc, indir);
102159
if (err)
103160
goto out;
104161

105-
err = mlx5e_rqt_init(rqt, mdev, indir->max_table_size, rss_rqns,
162+
err = mlx5e_rqt_init(rqt, mdev, indir->max_table_size, rss_rqns, rss_vhca_ids,
106163
indir->actual_table_size);
107164

108165
out:
166+
kvfree(rss_vhca_ids);
109167
kvfree(rss_rqns);
110168
return err;
111169
}
@@ -126,15 +184,20 @@ void mlx5e_rqt_destroy(struct mlx5e_rqt *rqt)
126184
mlx5_core_destroy_rqt(rqt->mdev, rqt->rqtn);
127185
}
128186

129-
static int mlx5e_rqt_redirect(struct mlx5e_rqt *rqt, u32 *rqns, unsigned int size)
187+
static int mlx5e_rqt_redirect(struct mlx5e_rqt *rqt, u32 *rqns, u32 *vhca_ids,
188+
unsigned int size)
130189
{
131-
unsigned int i;
190+
int entry_sz;
132191
void *rqtc;
133192
int inlen;
134193
u32 *in;
135194
int err;
136195

137-
inlen = MLX5_ST_SZ_BYTES(modify_rqt_in) + sizeof(u32) * size;
196+
if (!rqt_verify_vhca_ids(rqt->mdev, vhca_ids, size))
197+
return -EINVAL;
198+
199+
entry_sz = vhca_ids ? MLX5_ST_SZ_BYTES(rq_vhca) : MLX5_ST_SZ_BYTES(rq_num);
200+
inlen = MLX5_ST_SZ_BYTES(modify_rqt_in) + entry_sz * size;
138201
in = kvzalloc(inlen, GFP_KERNEL);
139202
if (!in)
140203
return -ENOMEM;
@@ -143,40 +206,54 @@ static int mlx5e_rqt_redirect(struct mlx5e_rqt *rqt, u32 *rqns, unsigned int siz
143206

144207
MLX5_SET(modify_rqt_in, in, bitmask.rqn_list, 1);
145208
MLX5_SET(rqtc, rqtc, rqt_actual_size, size);
146-
for (i = 0; i < size; i++)
147-
MLX5_SET(rqtc, rqtc, rq_num[i], rqns[i]);
209+
210+
fill_rqn_list(rqtc, rqns, vhca_ids, size);
148211

149212
err = mlx5_core_modify_rqt(rqt->mdev, rqt->rqtn, in, inlen);
150213

151214
kvfree(in);
152215
return err;
153216
}
154217

155-
int mlx5e_rqt_redirect_direct(struct mlx5e_rqt *rqt, u32 rqn)
218+
int mlx5e_rqt_redirect_direct(struct mlx5e_rqt *rqt, u32 rqn, u32 *vhca_id)
156219
{
157-
return mlx5e_rqt_redirect(rqt, &rqn, 1);
220+
return mlx5e_rqt_redirect(rqt, &rqn, vhca_id, 1);
158221
}
159222

160-
int mlx5e_rqt_redirect_indir(struct mlx5e_rqt *rqt, u32 *rqns, unsigned int num_rqns,
223+
int mlx5e_rqt_redirect_indir(struct mlx5e_rqt *rqt, u32 *rqns, u32 *vhca_ids,
224+
unsigned int num_rqns,
161225
u8 hfunc, struct mlx5e_rss_params_indir *indir)
162226
{
163-
u32 *rss_rqns;
227+
u32 *rss_rqns, *rss_vhca_ids = NULL;
164228
int err;
165229

230+
if (!rqt_verify_vhca_ids(rqt->mdev, vhca_ids, num_rqns))
231+
return -EINVAL;
232+
166233
if (WARN_ON(rqt->size != indir->max_table_size))
167234
return -EINVAL;
168235

169236
rss_rqns = kvmalloc_array(indir->actual_table_size, sizeof(*rss_rqns), GFP_KERNEL);
170237
if (!rss_rqns)
171238
return -ENOMEM;
172239

173-
err = mlx5e_calc_indir_rqns(rss_rqns, rqns, num_rqns, hfunc, indir);
240+
if (vhca_ids) {
241+
rss_vhca_ids = kvmalloc_array(indir->actual_table_size, sizeof(*rss_vhca_ids),
242+
GFP_KERNEL);
243+
if (!rss_vhca_ids) {
244+
kvfree(rss_rqns);
245+
return -ENOMEM;
246+
}
247+
}
248+
249+
err = mlx5e_calc_indir_rqns(rss_rqns, rqns, rss_vhca_ids, vhca_ids, num_rqns, hfunc, indir);
174250
if (err)
175251
goto out;
176252

177-
err = mlx5e_rqt_redirect(rqt, rss_rqns, indir->actual_table_size);
253+
err = mlx5e_rqt_redirect(rqt, rss_rqns, rss_vhca_ids, indir->actual_table_size);
178254

179255
out:
256+
kvfree(rss_vhca_ids);
180257
kvfree(rss_rqns);
181258
return err;
182259
}

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,15 @@ void mlx5e_rss_params_indir_init_uniform(struct mlx5e_rss_params_indir *indir,
2020
unsigned int num_channels);
2121

2222
struct mlx5e_rqt {
23-
struct mlx5_core_dev *mdev;
23+
struct mlx5_core_dev *mdev; /* primary */
2424
u32 rqtn;
2525
u16 size;
2626
};
2727

2828
int mlx5e_rqt_init_direct(struct mlx5e_rqt *rqt, struct mlx5_core_dev *mdev,
2929
bool indir_enabled, u32 init_rqn, u32 indir_table_size);
3030
int mlx5e_rqt_init_indir(struct mlx5e_rqt *rqt, struct mlx5_core_dev *mdev,
31-
u32 *rqns, unsigned int num_rqns,
31+
u32 *rqns, u32 *vhca_ids, unsigned int num_rqns,
3232
u8 hfunc, struct mlx5e_rss_params_indir *indir);
3333
void mlx5e_rqt_destroy(struct mlx5e_rqt *rqt);
3434

@@ -38,8 +38,9 @@ static inline u32 mlx5e_rqt_get_rqtn(struct mlx5e_rqt *rqt)
3838
}
3939

4040
u32 mlx5e_rqt_size(struct mlx5_core_dev *mdev, unsigned int num_channels);
41-
int mlx5e_rqt_redirect_direct(struct mlx5e_rqt *rqt, u32 rqn);
42-
int mlx5e_rqt_redirect_indir(struct mlx5e_rqt *rqt, u32 *rqns, unsigned int num_rqns,
41+
int mlx5e_rqt_redirect_direct(struct mlx5e_rqt *rqt, u32 rqn, u32 *vhca_id);
42+
int mlx5e_rqt_redirect_indir(struct mlx5e_rqt *rqt, u32 *rqns, u32 *vhca_ids,
43+
unsigned int num_rqns,
4344
u8 hfunc, struct mlx5e_rss_params_indir *indir);
4445

4546
#endif /* __MLX5_EN_RQT_H__ */

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

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ struct mlx5e_rss {
7474
struct mlx5e_tir *tir[MLX5E_NUM_INDIR_TIRS];
7575
struct mlx5e_tir *inner_tir[MLX5E_NUM_INDIR_TIRS];
7676
struct mlx5e_rqt rqt;
77-
struct mlx5_core_dev *mdev;
77+
struct mlx5_core_dev *mdev; /* primary */
7878
u32 drop_rqn;
7979
bool inner_ft_support;
8080
bool enabled;
@@ -473,29 +473,30 @@ int mlx5e_rss_obtain_tirn(struct mlx5e_rss *rss,
473473
return 0;
474474
}
475475

476-
static int mlx5e_rss_apply(struct mlx5e_rss *rss, u32 *rqns, unsigned int num_rqns)
476+
static int mlx5e_rss_apply(struct mlx5e_rss *rss, u32 *rqns, u32 *vhca_ids, unsigned int num_rqns)
477477
{
478478
int err;
479479

480-
err = mlx5e_rqt_redirect_indir(&rss->rqt, rqns, num_rqns, rss->hash.hfunc, &rss->indir);
480+
err = mlx5e_rqt_redirect_indir(&rss->rqt, rqns, vhca_ids, num_rqns, rss->hash.hfunc,
481+
&rss->indir);
481482
if (err)
482483
mlx5e_rss_warn(rss->mdev, "Failed to redirect RQT %#x to channels: err = %d\n",
483484
mlx5e_rqt_get_rqtn(&rss->rqt), err);
484485
return err;
485486
}
486487

487-
void mlx5e_rss_enable(struct mlx5e_rss *rss, u32 *rqns, unsigned int num_rqns)
488+
void mlx5e_rss_enable(struct mlx5e_rss *rss, u32 *rqns, u32 *vhca_ids, unsigned int num_rqns)
488489
{
489490
rss->enabled = true;
490-
mlx5e_rss_apply(rss, rqns, num_rqns);
491+
mlx5e_rss_apply(rss, rqns, vhca_ids, num_rqns);
491492
}
492493

493494
void mlx5e_rss_disable(struct mlx5e_rss *rss)
494495
{
495496
int err;
496497

497498
rss->enabled = false;
498-
err = mlx5e_rqt_redirect_direct(&rss->rqt, rss->drop_rqn);
499+
err = mlx5e_rqt_redirect_direct(&rss->rqt, rss->drop_rqn, NULL);
499500
if (err)
500501
mlx5e_rss_warn(rss->mdev, "Failed to redirect RQT %#x to drop RQ %#x: err = %d\n",
501502
mlx5e_rqt_get_rqtn(&rss->rqt), rss->drop_rqn, err);
@@ -568,7 +569,7 @@ int mlx5e_rss_get_rxfh(struct mlx5e_rss *rss, u32 *indir, u8 *key, u8 *hfunc)
568569

569570
int mlx5e_rss_set_rxfh(struct mlx5e_rss *rss, const u32 *indir,
570571
const u8 *key, const u8 *hfunc,
571-
u32 *rqns, unsigned int num_rqns)
572+
u32 *rqns, u32 *vhca_ids, unsigned int num_rqns)
572573
{
573574
bool changed_indir = false;
574575
bool changed_hash = false;
@@ -608,7 +609,7 @@ int mlx5e_rss_set_rxfh(struct mlx5e_rss *rss, const u32 *indir,
608609
}
609610

610611
if (changed_indir && rss->enabled) {
611-
err = mlx5e_rss_apply(rss, rqns, num_rqns);
612+
err = mlx5e_rss_apply(rss, rqns, vhca_ids, num_rqns);
612613
if (err) {
613614
mlx5e_rss_copy(rss, old_rss);
614615
goto out;

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,15 @@ int mlx5e_rss_obtain_tirn(struct mlx5e_rss *rss,
3939
const struct mlx5e_packet_merge_param *init_pkt_merge_param,
4040
bool inner, u32 *tirn);
4141

42-
void mlx5e_rss_enable(struct mlx5e_rss *rss, u32 *rqns, unsigned int num_rqns);
42+
void mlx5e_rss_enable(struct mlx5e_rss *rss, u32 *rqns, u32 *vhca_ids, unsigned int num_rqns);
4343
void mlx5e_rss_disable(struct mlx5e_rss *rss);
4444

4545
int mlx5e_rss_packet_merge_set_param(struct mlx5e_rss *rss,
4646
struct mlx5e_packet_merge_param *pkt_merge_param);
4747
int mlx5e_rss_get_rxfh(struct mlx5e_rss *rss, u32 *indir, u8 *key, u8 *hfunc);
4848
int mlx5e_rss_set_rxfh(struct mlx5e_rss *rss, const u32 *indir,
4949
const u8 *key, const u8 *hfunc,
50-
u32 *rqns, unsigned int num_rqns);
50+
u32 *rqns, u32 *vhca_ids, unsigned int num_rqns);
5151
struct mlx5e_rss_params_hash mlx5e_rss_get_hash(struct mlx5e_rss *rss);
5252
u8 mlx5e_rss_get_hash_fields(struct mlx5e_rss *rss, enum mlx5_traffic_types tt);
5353
int mlx5e_rss_set_hash_fields(struct mlx5e_rss *rss, enum mlx5_traffic_types tt,

0 commit comments

Comments
 (0)