Skip to content

Commit bd5251d

Browse files
amirvdavem330
authored andcommitted
net/mlx5_core: Introduce flow steering destination of type counter
When adding a flow steering rule with a counter, need to supply a destination of type MLX5_FLOW_DESTINATION_TYPE_COUNTER, with a pointer to a struct mlx5_fc. Also, MLX5_FLOW_CONTEXT_ACTION_COUNT bit should be set in the action. Signed-off-by: Amir Vadai <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 9dc0b28 commit bd5251d

File tree

6 files changed

+106
-10
lines changed

6 files changed

+106
-10
lines changed

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

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -241,17 +241,20 @@ static int mlx5_cmd_set_fte(struct mlx5_core_dev *dev,
241241
MLX5_SET(flow_context, in_flow_context, group_id, group_id);
242242
MLX5_SET(flow_context, in_flow_context, flow_tag, fte->flow_tag);
243243
MLX5_SET(flow_context, in_flow_context, action, fte->action);
244-
MLX5_SET(flow_context, in_flow_context, destination_list_size,
245-
fte->dests_size);
246244
in_match_value = MLX5_ADDR_OF(flow_context, in_flow_context,
247245
match_value);
248246
memcpy(in_match_value, &fte->val, MLX5_ST_SZ_BYTES(fte_match_param));
249247

248+
in_dests = MLX5_ADDR_OF(flow_context, in_flow_context, destination);
250249
if (fte->action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST) {
251-
in_dests = MLX5_ADDR_OF(flow_context, in_flow_context, destination);
250+
int list_size = 0;
251+
252252
list_for_each_entry(dst, &fte->node.children, node.list) {
253253
unsigned int id;
254254

255+
if (dst->dest_attr.type == MLX5_FLOW_DESTINATION_TYPE_COUNTER)
256+
continue;
257+
255258
MLX5_SET(dest_format_struct, in_dests, destination_type,
256259
dst->dest_attr.type);
257260
if (dst->dest_attr.type ==
@@ -262,8 +265,31 @@ static int mlx5_cmd_set_fte(struct mlx5_core_dev *dev,
262265
}
263266
MLX5_SET(dest_format_struct, in_dests, destination_id, id);
264267
in_dests += MLX5_ST_SZ_BYTES(dest_format_struct);
268+
list_size++;
269+
}
270+
271+
MLX5_SET(flow_context, in_flow_context, destination_list_size,
272+
list_size);
273+
}
274+
275+
if (fte->action & MLX5_FLOW_CONTEXT_ACTION_COUNT) {
276+
int list_size = 0;
277+
278+
list_for_each_entry(dst, &fte->node.children, node.list) {
279+
if (dst->dest_attr.type !=
280+
MLX5_FLOW_DESTINATION_TYPE_COUNTER)
281+
continue;
282+
283+
MLX5_SET(flow_counter_list, in_dests, flow_counter_id,
284+
dst->dest_attr.counter->id);
285+
in_dests += MLX5_ST_SZ_BYTES(dest_format_struct);
286+
list_size++;
265287
}
288+
289+
MLX5_SET(flow_context, in_flow_context, flow_counter_list_size,
290+
list_size);
266291
}
292+
267293
memset(out, 0, sizeof(out));
268294
err = mlx5_cmd_exec_check_status(dev, in, inlen, out,
269295
sizeof(out));
@@ -283,18 +309,16 @@ int mlx5_cmd_create_fte(struct mlx5_core_dev *dev,
283309
int mlx5_cmd_update_fte(struct mlx5_core_dev *dev,
284310
struct mlx5_flow_table *ft,
285311
unsigned group_id,
312+
int modify_mask,
286313
struct fs_fte *fte)
287314
{
288315
int opmod;
289-
int modify_mask;
290316
int atomic_mod_cap = MLX5_CAP_FLOWTABLE(dev,
291317
flow_table_properties_nic_receive.
292318
flow_modify_en);
293319
if (!atomic_mod_cap)
294320
return -ENOTSUPP;
295321
opmod = 1;
296-
modify_mask = 1 <<
297-
MLX5_SET_FTE_MODIFY_ENABLE_MASK_DESTINATION_LIST;
298322

299323
return mlx5_cmd_set_fte(dev, opmod, modify_mask, ft, group_id, fte);
300324
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ int mlx5_cmd_create_fte(struct mlx5_core_dev *dev,
6262
int mlx5_cmd_update_fte(struct mlx5_core_dev *dev,
6363
struct mlx5_flow_table *ft,
6464
unsigned group_id,
65+
int modify_mask,
6566
struct fs_fte *fte);
6667

6768
int mlx5_cmd_delete_fte(struct mlx5_core_dev *dev,

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

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,7 @@ static void del_rule(struct fs_node *node)
344344
struct mlx5_flow_group *fg;
345345
struct fs_fte *fte;
346346
u32 *match_value;
347+
int modify_mask;
347348
struct mlx5_core_dev *dev = get_dev(node);
348349
int match_len = MLX5_ST_SZ_BYTES(fte_match_param);
349350
int err;
@@ -367,8 +368,11 @@ static void del_rule(struct fs_node *node)
367368
}
368369
if ((fte->action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST) &&
369370
--fte->dests_size) {
371+
modify_mask = BIT(MLX5_SET_FTE_MODIFY_ENABLE_MASK_DESTINATION_LIST),
370372
err = mlx5_cmd_update_fte(dev, ft,
371-
fg->id, fte);
373+
fg->id,
374+
modify_mask,
375+
fte);
372376
if (err)
373377
pr_warn("%s can't del rule fg id=%d fte_index=%d\n",
374378
__func__, fg->id, fte->index);
@@ -615,6 +619,7 @@ int mlx5_modify_rule_destination(struct mlx5_flow_rule *rule,
615619
struct mlx5_flow_table *ft;
616620
struct mlx5_flow_group *fg;
617621
struct fs_fte *fte;
622+
int modify_mask = BIT(MLX5_SET_FTE_MODIFY_ENABLE_MASK_DESTINATION_LIST);
618623
int err = 0;
619624

620625
fs_get_obj(fte, rule->node.parent);
@@ -626,7 +631,9 @@ int mlx5_modify_rule_destination(struct mlx5_flow_rule *rule,
626631

627632
memcpy(&rule->dest_attr, dest, sizeof(*dest));
628633
err = mlx5_cmd_update_fte(get_dev(&ft->node),
629-
ft, fg->id, fte);
634+
ft, fg->id,
635+
modify_mask,
636+
fte);
630637
unlock_ref_node(&fte->node);
631638

632639
return err;
@@ -877,6 +884,7 @@ static struct mlx5_flow_rule *add_rule_fte(struct fs_fte *fte,
877884
{
878885
struct mlx5_flow_table *ft;
879886
struct mlx5_flow_rule *rule;
887+
int modify_mask = 0;
880888
int err;
881889

882890
rule = alloc_rule(dest);
@@ -892,14 +900,20 @@ static struct mlx5_flow_rule *add_rule_fte(struct fs_fte *fte,
892900
list_add(&rule->node.list, &fte->node.children);
893901
else
894902
list_add_tail(&rule->node.list, &fte->node.children);
895-
if (dest)
903+
if (dest) {
896904
fte->dests_size++;
905+
906+
modify_mask |= dest->type == MLX5_FLOW_DESTINATION_TYPE_COUNTER ?
907+
BIT(MLX5_SET_FTE_MODIFY_ENABLE_MASK_FLOW_COUNTERS) :
908+
BIT(MLX5_SET_FTE_MODIFY_ENABLE_MASK_DESTINATION_LIST);
909+
}
910+
897911
if (fte->dests_size == 1 || !dest)
898912
err = mlx5_cmd_create_fte(get_dev(&ft->node),
899913
ft, fg->id, fte);
900914
else
901915
err = mlx5_cmd_update_fte(get_dev(&ft->node),
902-
ft, fg->id, fte);
916+
ft, fg->id, modify_mask, fte);
903917
if (err)
904918
goto free_rule;
905919

@@ -1092,10 +1106,40 @@ static struct mlx5_flow_rule *add_rule_fg(struct mlx5_flow_group *fg,
10921106
return rule;
10931107
}
10941108

1109+
struct mlx5_fc *mlx5_flow_rule_counter(struct mlx5_flow_rule *rule)
1110+
{
1111+
struct mlx5_flow_rule *dst;
1112+
struct fs_fte *fte;
1113+
1114+
fs_get_obj(fte, rule->node.parent);
1115+
1116+
fs_for_each_dst(dst, fte) {
1117+
if (dst->dest_attr.type == MLX5_FLOW_DESTINATION_TYPE_COUNTER)
1118+
return dst->dest_attr.counter;
1119+
}
1120+
1121+
return NULL;
1122+
}
1123+
1124+
static bool counter_is_valid(struct mlx5_fc *counter, u32 action)
1125+
{
1126+
if (!(action & MLX5_FLOW_CONTEXT_ACTION_COUNT))
1127+
return !counter;
1128+
1129+
if (!counter)
1130+
return false;
1131+
1132+
/* Hardware support counter for a drop action only */
1133+
return action == (MLX5_FLOW_CONTEXT_ACTION_DROP | MLX5_FLOW_CONTEXT_ACTION_COUNT);
1134+
}
1135+
10951136
static bool dest_is_valid(struct mlx5_flow_destination *dest,
10961137
u32 action,
10971138
struct mlx5_flow_table *ft)
10981139
{
1140+
if (dest && (dest->type == MLX5_FLOW_DESTINATION_TYPE_COUNTER))
1141+
return counter_is_valid(dest->counter, action);
1142+
10991143
if (!(action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST))
11001144
return true;
11011145

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,28 @@ struct mlx5_flow_table {
9696
struct list_head fwd_rules;
9797
};
9898

99+
struct mlx5_fc_cache {
100+
u64 packets;
101+
u64 bytes;
102+
u64 lastuse;
103+
};
104+
105+
struct mlx5_fc {
106+
struct list_head list;
107+
108+
/* last{packets,bytes} members are used when calculating the delta since
109+
* last reading
110+
*/
111+
u64 lastpackets;
112+
u64 lastbytes;
113+
114+
u16 id;
115+
bool deleted;
116+
bool aging;
117+
118+
struct mlx5_fc_cache cache ____cacheline_aligned_in_smp;
119+
};
120+
99121
/* Type of children is mlx5_flow_rule */
100122
struct fs_fte {
101123
struct fs_node node;
@@ -105,6 +127,7 @@ struct fs_fte {
105127
u32 index;
106128
u32 action;
107129
enum fs_fte_status status;
130+
struct mlx5_fc *counter;
108131
};
109132

110133
/* Type of children is mlx5_flow_table/namespace */

include/linux/mlx5/fs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ struct mlx5_flow_destination {
7373
u32 tir_num;
7474
struct mlx5_flow_table *ft;
7575
u32 vport_num;
76+
struct mlx5_fc *counter;
7677
};
7778
};
7879

@@ -125,4 +126,5 @@ void mlx5_del_flow_rule(struct mlx5_flow_rule *fr);
125126
int mlx5_modify_rule_destination(struct mlx5_flow_rule *rule,
126127
struct mlx5_flow_destination *dest);
127128

129+
struct mlx5_fc *mlx5_flow_rule_counter(struct mlx5_flow_rule *rule);
128130
#endif

include/linux/mlx5/mlx5_ifc.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -936,6 +936,8 @@ enum mlx5_flow_destination_type {
936936
MLX5_FLOW_DESTINATION_TYPE_VPORT = 0x0,
937937
MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE = 0x1,
938938
MLX5_FLOW_DESTINATION_TYPE_TIR = 0x2,
939+
940+
MLX5_FLOW_DESTINATION_TYPE_COUNTER = 0x100,
939941
};
940942

941943
struct mlx5_ifc_dest_format_struct_bits {

0 commit comments

Comments
 (0)