Skip to content

Commit a833fb8

Browse files
committed
Merge branch 'mlx5-hw-managed-flow-steering-in-fs-core-level'
Tariq Toukan says: ==================== mlx5 HW-Managed Flow Steering in FS core level This patchset by Moshe follows Yevgeny's patchsets [1][2] on subject "HW-Managed Flow Steering in mlx5 driver". As introduced there in HW managed Flow Steering mode (HWS) the driver is configuring steering rules directly to the HW using WQs with a special new type of WQE (Work Queue Element). This way we can reach higher rule insertion/deletion rate with much lower CPU utilization compared to SW Managed Flow Steering (SWS). This patchset adds API to manage namespace, flow tables, flow groups and prepare FTE (Flow Table Entry) rules. It also adds caching and pool mechanisms for HWS actions to allow sharing of steering actions among different rules. The implementation of this API in FS layer, allows FS core to use HW Managed Flow Steering in addition to the existing FW or SW Managed Flow Steering. Patch 13 of this series adds support for configuring HW Managed Flow Steering mode through devlink param, similar to configuring SW Managed Flow Steering mode: # devlink dev param set pci/0000:08:00.0 name flow_steering_mode \ cmode runtime value hmfs In addition, the series contains 2 HWS patches from Yevgeny that implement flow update support. [1] https://lore.kernel.org/netdev/[email protected]/ [2] https://lore.kernel.org/all/[email protected]/ ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents afc6649 + 3fc44ca commit a833fb8

File tree

19 files changed

+2245
-284
lines changed

19 files changed

+2245
-284
lines changed

Documentation/networking/devlink/mlx5.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ parameters.
5353
* ``smfs`` Software managed flow steering. In SMFS mode, the HW
5454
steering entities are created and manage through the driver without
5555
firmware intervention.
56+
* ``hmfs`` Hardware managed flow steering. In HMFS mode, the driver
57+
is configuring steering rules directly to the HW using Work Queues with
58+
a special new type of WQE (Work Queue Element).
5659

5760
SMFS mode is faster and provides better rule insertion rate compared to
5861
default DMFS mode.

drivers/net/ethernet/mellanox/mlx5/core/Makefile

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,9 @@ mlx5_core-$(CONFIG_MLX5_HW_STEERING) += steering/hws/cmd.o \
151151
steering/hws/bwc.o \
152152
steering/hws/debug.o \
153153
steering/hws/vport.o \
154-
steering/hws/bwc_complex.o
155-
154+
steering/hws/bwc_complex.o \
155+
steering/hws/fs_hws_pools.o \
156+
steering/hws/fs_hws.o
156157

157158
#
158159
# SF device

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

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3535,35 +3535,42 @@ static int mlx5_fs_mode_validate(struct devlink *devlink, u32 id,
35353535
{
35363536
struct mlx5_core_dev *dev = devlink_priv(devlink);
35373537
char *value = val.vstr;
3538-
int err = 0;
3538+
u8 eswitch_mode;
35393539

3540-
if (!strcmp(value, "dmfs")) {
3540+
if (!strcmp(value, "dmfs"))
35413541
return 0;
3542-
} else if (!strcmp(value, "smfs")) {
3543-
u8 eswitch_mode;
3544-
bool smfs_cap;
35453542

3546-
eswitch_mode = mlx5_eswitch_mode(dev);
3547-
smfs_cap = mlx5_fs_dr_is_supported(dev);
3543+
if (!strcmp(value, "smfs")) {
3544+
bool smfs_cap = mlx5_fs_dr_is_supported(dev);
35483545

35493546
if (!smfs_cap) {
3550-
err = -EOPNOTSUPP;
35513547
NL_SET_ERR_MSG_MOD(extack,
35523548
"Software managed steering is not supported by current device");
3549+
return -EOPNOTSUPP;
35533550
}
3551+
} else if (!strcmp(value, "hmfs")) {
3552+
bool hmfs_cap = mlx5_fs_hws_is_supported(dev);
35543553

3555-
else if (eswitch_mode == MLX5_ESWITCH_OFFLOADS) {
3554+
if (!hmfs_cap) {
35563555
NL_SET_ERR_MSG_MOD(extack,
3557-
"Software managed steering is not supported when eswitch offloads enabled.");
3558-
err = -EOPNOTSUPP;
3556+
"Hardware steering is not supported by current device");
3557+
return -EOPNOTSUPP;
35593558
}
35603559
} else {
35613560
NL_SET_ERR_MSG_MOD(extack,
3562-
"Bad parameter: supported values are [\"dmfs\", \"smfs\"]");
3563-
err = -EINVAL;
3561+
"Bad parameter: supported values are [\"dmfs\", \"smfs\", \"hmfs\"]");
3562+
return -EINVAL;
35643563
}
35653564

3566-
return err;
3565+
eswitch_mode = mlx5_eswitch_mode(dev);
3566+
if (eswitch_mode == MLX5_ESWITCH_OFFLOADS) {
3567+
NL_SET_ERR_MSG_FMT_MOD(extack,
3568+
"Moving to %s is not supported when eswitch offloads enabled.",
3569+
value);
3570+
return -EOPNOTSUPP;
3571+
}
3572+
3573+
return 0;
35673574
}
35683575

35693576
static int mlx5_fs_mode_set(struct devlink *devlink, u32 id,
@@ -3575,6 +3582,8 @@ static int mlx5_fs_mode_set(struct devlink *devlink, u32 id,
35753582

35763583
if (!strcmp(ctx->val.vstr, "smfs"))
35773584
mode = MLX5_FLOW_STEERING_MODE_SMFS;
3585+
else if (!strcmp(ctx->val.vstr, "hmfs"))
3586+
mode = MLX5_FLOW_STEERING_MODE_HMFS;
35783587
else
35793588
mode = MLX5_FLOW_STEERING_MODE_DMFS;
35803589
dev->priv.steering->mode = mode;
@@ -3587,10 +3596,17 @@ static int mlx5_fs_mode_get(struct devlink *devlink, u32 id,
35873596
{
35883597
struct mlx5_core_dev *dev = devlink_priv(devlink);
35893598

3590-
if (dev->priv.steering->mode == MLX5_FLOW_STEERING_MODE_SMFS)
3599+
switch (dev->priv.steering->mode) {
3600+
case MLX5_FLOW_STEERING_MODE_SMFS:
35913601
strscpy(ctx->val.vstr, "smfs", sizeof(ctx->val.vstr));
3592-
else
3602+
break;
3603+
case MLX5_FLOW_STEERING_MODE_HMFS:
3604+
strscpy(ctx->val.vstr, "hmfs", sizeof(ctx->val.vstr));
3605+
break;
3606+
default:
35933607
strscpy(ctx->val.vstr, "dmfs", sizeof(ctx->val.vstr));
3608+
}
3609+
35943610
return 0;
35953611
}
35963612

@@ -4009,6 +4025,8 @@ int mlx5_flow_namespace_set_mode(struct mlx5_flow_namespace *ns,
40094025

40104026
if (mode == MLX5_FLOW_STEERING_MODE_SMFS)
40114027
cmds = mlx5_fs_cmd_get_dr_cmds();
4028+
else if (mode == MLX5_FLOW_STEERING_MODE_HMFS)
4029+
cmds = mlx5_fs_cmd_get_hws_cmds();
40124030
else
40134031
cmds = mlx5_fs_cmd_get_fw_cmds();
40144032
if (!cmds)

drivers/net/ethernet/mellanox/mlx5/core/fs_core.h

Lines changed: 57 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include <linux/rhashtable.h>
3939
#include <linux/llist.h>
4040
#include <steering/sws/fs_dr.h>
41+
#include <steering/hws/fs_hws.h>
4142

4243
#define FDB_TC_MAX_CHAIN 3
4344
#define FDB_FT_CHAIN (FDB_TC_MAX_CHAIN + 1)
@@ -64,6 +65,7 @@ struct mlx5_modify_hdr {
6465
enum mlx5_flow_resource_owner owner;
6566
union {
6667
struct mlx5_fs_dr_action fs_dr_action;
68+
struct mlx5_fs_hws_action fs_hws_action;
6769
u32 id;
6870
};
6971
};
@@ -74,6 +76,7 @@ struct mlx5_pkt_reformat {
7476
enum mlx5_flow_resource_owner owner;
7577
union {
7678
struct mlx5_fs_dr_action fs_dr_action;
79+
struct mlx5_fs_hws_action fs_hws_action;
7780
u32 id;
7881
};
7982
};
@@ -126,7 +129,8 @@ enum fs_fte_status {
126129

127130
enum mlx5_flow_steering_mode {
128131
MLX5_FLOW_STEERING_MODE_DMFS,
129-
MLX5_FLOW_STEERING_MODE_SMFS
132+
MLX5_FLOW_STEERING_MODE_SMFS,
133+
MLX5_FLOW_STEERING_MODE_HMFS,
130134
};
131135

132136
enum mlx5_flow_steering_capabilty {
@@ -190,7 +194,10 @@ struct mlx5_flow_handle {
190194
/* Type of children is mlx5_flow_group */
191195
struct mlx5_flow_table {
192196
struct fs_node node;
193-
struct mlx5_fs_dr_table fs_dr_table;
197+
union {
198+
struct mlx5_fs_dr_table fs_dr_table;
199+
struct mlx5_fs_hws_table fs_hws_table;
200+
};
194201
u32 id;
195202
u16 vport;
196203
unsigned int max_fte;
@@ -247,7 +254,10 @@ struct fs_fte_dup {
247254
/* Type of children is mlx5_flow_rule */
248255
struct fs_fte {
249256
struct fs_node node;
250-
struct mlx5_fs_dr_rule fs_dr_rule;
257+
union {
258+
struct mlx5_fs_dr_rule fs_dr_rule;
259+
struct mlx5_fs_hws_rule fs_hws_rule;
260+
};
251261
u32 val[MLX5_ST_SZ_DW_MATCH_PARAM];
252262
struct fs_fte_action act_dests;
253263
struct fs_fte_dup *dup;
@@ -280,7 +290,10 @@ struct mlx5_flow_group_mask {
280290
/* Type of children is fs_fte */
281291
struct mlx5_flow_group {
282292
struct fs_node node;
283-
struct mlx5_fs_dr_matcher fs_dr_matcher;
293+
union {
294+
struct mlx5_fs_dr_matcher fs_dr_matcher;
295+
struct mlx5_fs_hws_matcher fs_hws_matcher;
296+
};
284297
struct mlx5_flow_group_mask mask;
285298
u32 start_index;
286299
u32 max_ftes;
@@ -293,7 +306,10 @@ struct mlx5_flow_group {
293306
struct mlx5_flow_root_namespace {
294307
struct mlx5_flow_namespace ns;
295308
enum mlx5_flow_steering_mode mode;
296-
struct mlx5_fs_dr_domain fs_dr_domain;
309+
union {
310+
struct mlx5_fs_dr_domain fs_dr_domain;
311+
struct mlx5_fs_hws_context fs_hws_context;
312+
};
297313
enum fs_flow_table_type table_type;
298314
struct mlx5_core_dev *dev;
299315
struct mlx5_flow_table *root_ft;
@@ -303,6 +319,42 @@ struct mlx5_flow_root_namespace {
303319
const struct mlx5_flow_cmds *cmds;
304320
};
305321

322+
enum mlx5_fc_type {
323+
MLX5_FC_TYPE_ACQUIRED = 0,
324+
MLX5_FC_TYPE_LOCAL,
325+
};
326+
327+
struct mlx5_fc_cache {
328+
u64 packets;
329+
u64 bytes;
330+
u64 lastuse;
331+
};
332+
333+
struct mlx5_fc {
334+
u32 id;
335+
bool aging;
336+
enum mlx5_fc_type type;
337+
struct mlx5_fc_bulk *bulk;
338+
struct mlx5_fc_cache cache;
339+
/* last{packets,bytes} are used for calculating deltas since last reading. */
340+
u64 lastpackets;
341+
u64 lastbytes;
342+
};
343+
344+
struct mlx5_fc_bulk_hws_data {
345+
struct mlx5hws_action *hws_action;
346+
struct mutex lock; /* protects hws_action */
347+
refcount_t hws_action_refcount;
348+
};
349+
350+
struct mlx5_fc_bulk {
351+
struct mlx5_fs_bulk fs_bulk;
352+
u32 base_id;
353+
struct mlx5_fc_bulk_hws_data hws_data;
354+
struct mlx5_fc fcs[];
355+
};
356+
357+
u32 mlx5_fc_get_base_id(struct mlx5_fc *counter);
306358
int mlx5_init_fc_stats(struct mlx5_core_dev *dev);
307359
void mlx5_cleanup_fc_stats(struct mlx5_core_dev *dev);
308360
void mlx5_fc_queue_stats_work(struct mlx5_core_dev *dev,

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

Lines changed: 11 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -44,28 +44,6 @@
4444
#define MLX5_FC_POOL_MAX_THRESHOLD BIT(18)
4545
#define MLX5_FC_POOL_USED_BUFF_RATIO 10
4646

47-
enum mlx5_fc_type {
48-
MLX5_FC_TYPE_ACQUIRED = 0,
49-
MLX5_FC_TYPE_LOCAL,
50-
};
51-
52-
struct mlx5_fc_cache {
53-
u64 packets;
54-
u64 bytes;
55-
u64 lastuse;
56-
};
57-
58-
struct mlx5_fc {
59-
u32 id;
60-
bool aging;
61-
enum mlx5_fc_type type;
62-
struct mlx5_fc_bulk *bulk;
63-
struct mlx5_fc_cache cache;
64-
/* last{packets,bytes} are used for calculating deltas since last reading. */
65-
u64 lastpackets;
66-
u64 lastbytes;
67-
};
68-
6947
struct mlx5_fc_stats {
7048
struct xarray counters;
7149

@@ -434,13 +412,7 @@ void mlx5_fc_update_sampling_interval(struct mlx5_core_dev *dev,
434412
fc_stats->sampling_interval);
435413
}
436414

437-
/* Flow counter bluks */
438-
439-
struct mlx5_fc_bulk {
440-
struct mlx5_fs_bulk fs_bulk;
441-
u32 base_id;
442-
struct mlx5_fc fcs[];
443-
};
415+
/* Flow counter bulks */
444416

445417
static void mlx5_fc_init(struct mlx5_fc *counter, struct mlx5_fc_bulk *bulk,
446418
u32 id)
@@ -449,7 +421,13 @@ static void mlx5_fc_init(struct mlx5_fc *counter, struct mlx5_fc_bulk *bulk,
449421
counter->id = id;
450422
}
451423

452-
static struct mlx5_fs_bulk *mlx5_fc_bulk_create(struct mlx5_core_dev *dev)
424+
u32 mlx5_fc_get_base_id(struct mlx5_fc *counter)
425+
{
426+
return counter->bulk->base_id;
427+
}
428+
429+
static struct mlx5_fs_bulk *mlx5_fc_bulk_create(struct mlx5_core_dev *dev,
430+
void *pool_ctx)
453431
{
454432
enum mlx5_fc_bulk_alloc_bitmask alloc_bitmask;
455433
struct mlx5_fc_bulk *fc_bulk;
@@ -473,6 +451,8 @@ static struct mlx5_fs_bulk *mlx5_fc_bulk_create(struct mlx5_core_dev *dev)
473451
for (i = 0; i < bulk_len; i++)
474452
mlx5_fc_init(&fc_bulk->fcs[i], fc_bulk, base_id + i);
475453

454+
refcount_set(&fc_bulk->hws_data.hws_action_refcount, 0);
455+
mutex_init(&fc_bulk->hws_data.lock);
476456
return &fc_bulk->fs_bulk;
477457

478458
fs_bulk_cleanup:
@@ -518,7 +498,7 @@ static const struct mlx5_fs_pool_ops mlx5_fc_pool_ops = {
518498
static void
519499
mlx5_fc_pool_init(struct mlx5_fs_pool *fc_pool, struct mlx5_core_dev *dev)
520500
{
521-
mlx5_fs_pool_init(fc_pool, dev, &mlx5_fc_pool_ops);
501+
mlx5_fs_pool_init(fc_pool, dev, &mlx5_fc_pool_ops, NULL);
522502
}
523503

524504
static void mlx5_fc_pool_cleanup(struct mlx5_fs_pool *fc_pool)

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,12 @@ static int mlx5_fs_bulk_release_index(struct mlx5_fs_bulk *fs_bulk, int index)
5656
}
5757

5858
void mlx5_fs_pool_init(struct mlx5_fs_pool *pool, struct mlx5_core_dev *dev,
59-
const struct mlx5_fs_pool_ops *ops)
59+
const struct mlx5_fs_pool_ops *ops, void *pool_ctx)
6060
{
6161
WARN_ON_ONCE(!ops || !ops->bulk_destroy || !ops->bulk_create ||
6262
!ops->update_threshold);
6363
pool->dev = dev;
64+
pool->pool_ctx = pool_ctx;
6465
mutex_init(&pool->pool_lock);
6566
INIT_LIST_HEAD(&pool->fully_used);
6667
INIT_LIST_HEAD(&pool->partially_used);
@@ -91,7 +92,7 @@ mlx5_fs_pool_alloc_new_bulk(struct mlx5_fs_pool *fs_pool)
9192
struct mlx5_core_dev *dev = fs_pool->dev;
9293
struct mlx5_fs_bulk *new_bulk;
9394

94-
new_bulk = fs_pool->ops->bulk_create(dev);
95+
new_bulk = fs_pool->ops->bulk_create(dev, fs_pool->pool_ctx);
9596
if (new_bulk)
9697
fs_pool->available_units += new_bulk->bulk_len;
9798
fs_pool->ops->update_threshold(fs_pool);

drivers/net/ethernet/mellanox/mlx5/core/fs_pool.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ struct mlx5_fs_pool;
2121

2222
struct mlx5_fs_pool_ops {
2323
int (*bulk_destroy)(struct mlx5_core_dev *dev, struct mlx5_fs_bulk *bulk);
24-
struct mlx5_fs_bulk * (*bulk_create)(struct mlx5_core_dev *dev);
24+
struct mlx5_fs_bulk * (*bulk_create)(struct mlx5_core_dev *dev,
25+
void *pool_ctx);
2526
void (*update_threshold)(struct mlx5_fs_pool *pool);
2627
};
2728

@@ -44,7 +45,7 @@ void mlx5_fs_bulk_cleanup(struct mlx5_fs_bulk *fs_bulk);
4445
int mlx5_fs_bulk_get_free_amount(struct mlx5_fs_bulk *bulk);
4546

4647
void mlx5_fs_pool_init(struct mlx5_fs_pool *pool, struct mlx5_core_dev *dev,
47-
const struct mlx5_fs_pool_ops *ops);
48+
const struct mlx5_fs_pool_ops *ops, void *pool_ctx);
4849
void mlx5_fs_pool_cleanup(struct mlx5_fs_pool *pool);
4950
int mlx5_fs_pool_acquire_index(struct mlx5_fs_pool *fs_pool,
5051
struct mlx5_fs_pool_index *pool_index);

drivers/net/ethernet/mellanox/mlx5/core/steering/hws/debug.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,8 @@ static int hws_debug_dump_matcher(struct seq_file *f, struct mlx5hws_matcher *ma
148148
matcher->match_ste.rtc_1_id,
149149
(int)ste_1_id);
150150

151-
ste = &matcher->action_ste[0].ste;
152-
ste_pool = matcher->action_ste[0].pool;
151+
ste = &matcher->action_ste.ste;
152+
ste_pool = matcher->action_ste.pool;
153153
if (ste_pool) {
154154
ste_0_id = mlx5hws_pool_chunk_get_base_id(ste_pool, ste);
155155
if (tbl_type == MLX5HWS_TABLE_TYPE_FDB)
@@ -171,10 +171,8 @@ static int hws_debug_dump_matcher(struct seq_file *f, struct mlx5hws_matcher *ma
171171
return ret;
172172

173173
seq_printf(f, ",%d,%d,%d,%d,%d,0x%llx,0x%llx\n",
174-
matcher->action_ste[0].rtc_0_id,
175-
(int)ste_0_id,
176-
matcher->action_ste[0].rtc_1_id,
177-
(int)ste_1_id,
174+
matcher->action_ste.rtc_0_id, (int)ste_0_id,
175+
matcher->action_ste.rtc_1_id, (int)ste_1_id,
178176
0,
179177
mlx5hws_debug_icm_to_idx(icm_addr_0),
180178
mlx5hws_debug_icm_to_idx(icm_addr_1));

0 commit comments

Comments
 (0)