Skip to content

Commit f96b48c

Browse files
committed
Merge tag 'mlx5-updates-2021-08-19' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux
Saeed Mahameed says: ==================== mlx5-updates-2021-08-19 This series introduces the support for two new mlx5 features: 1) Sample offload for tunneled traffic 2) devlink rate objects support 1) From Chris Mi: Sample offload for tunneled traffic ===================================================== Background and solution ----------------------- Currently the sample offload actions send the encapsulated packet to software. This series de-capsulates the packet before performing the sampling and set the tunnel properties on the skb metadata fields to make the behavior consistent with OVS sFlow. If de-capsulating first, we can't use the same match like before in default table. So instantiate a post action instance to continue processing the action list. If HW can preserve reg_c, also use the post action instance. Post action infrastructure -------------------------- Some tc actions are modeled in hardware using multiple tables causing a tc action list split. For example, CT action is modeled by jumping to a ct table which is controlled by nf flow table. sFlow jumps in hardware to a sample table, which continues to a "default table" where it should continue processing the action list. Multi table actions are modeled in hardware using a unique fte_id. The fte_id is set before jumping to a table. Split actions continue to a post-action table where the matched fte_id value continues the execution the tc action list. This series also introduces post action infrastructure. Both ct and sample use it. Sample for tunnel in TC SW -------------------------- tc filter add dev vxlan1 protocol ip parent ffff: prio 3 \ flower src_mac 24:25:d0:e1:00:00 dst_mac 02:25:d0:13:01:02 \ enc_src_ip 192.168.1.14 enc_dst_ip 192.168.1.13 \ enc_dst_port 4789 enc_key_id 4 \ action sample rate 1 group 6 \ action tunnel_key unset \ action mirred egress redirect dev enp4s0f0_1 MLX5 sample HW offload ---------------------- For the following typical flow table: +-------------------------------+ + original flow table + +-------------------------------+ + original match + +-------------------------------+ + sample action + other actions + +-------------------------------+ We translate the tc filter with sample action to the following HW model: +---------------------+ + original flow table + +---------------------+ + original match + +---------------------+ | set fte_id (if reg_c preserve cap) | do decap v +------------------------------------------------+ + Flow Sampler Object + +------------------------------------------------+ + sample ratio + +------------------------------------------------+ + sample table id | default table id + +------------------------------------------------+ | | v v +-----------------------------+ +-------------------+ + sample table + + default table + +-----------------------------+ +-------------------+ + forward to management vport + | +-----------------------------+ | +-------+------+ | |reg_c preserve cap | |or decap action v v +-----------------+ +-------------+ + per vport table + + post action + +-----------------+ +-------------+ + original match + +-----------------+ + other actions + +-----------------+ 2) From Dmytro Linkin: devlink rate object support for mlx5_core driver ======================================================================= HIGH-LEVEL OVERVIEW Devlink leaf rate objects created per vport (VF/SF, and PF on BlueField) in switchdev mode on devlink port registration. Implement devlink ops callbacks to create/destroy rate groups, set TX rate values of the vport/group, assign vport to the group. Driver accepts TX rate values as fraction of 1Mbps. Refactor existing eswitch QoS infrastructure to be accessible by legacy NDO rate API and new devlink rate API. NDO rate API is not removed/disabled in switchdev mode to not break existing users. Rate values configured with NDO rate API are not visible for devlink infrastructure, therefore APIs should not be used simultaneously. IMPLEMENTATION DETAILS Driver provide two level rate hierarchy to manage bandwidth - group level and vport level. Initially each vport added to internal unlimited group created by default. Each rate element (vport or group) receive bandwidth relative to its parent element (for groups the parent is a physical link itself) in a Round Robin manner, where element get bandwidth value according to its weight. Example: Created four rate groups with tx_share limits: $ devlink port function rate add \ pci/0000:06:00.0/group_1 tx_share 30gbit $ devlink port function rate add \ pci/0000:06:00.0/group_2 tx_share 20gbit $ devlink port function rate add \ pci/0000:06:00.0/group_3 tx_share 20gbit $ devlink port function rate add \ pci/0000:06:00.0/group_4 tx_share 10gbit Weights created in HW for each group are relative to the bigest tx_share value, which is 30gbit: <group_1> 1.0 <group_2> 0.67 <group_3> 0.67 <group_4> 0.33 Assuming link speed is 50 Gbit/sec and each group can sustain such amount of traffic, maximum bandwidth is 50 / (1.0 + 0.67 + 0.67 + 0.33) = ~18.75 Gbit/sec. Normilized bandwidth values for groups: <group_1> 18.75 * 1.0 = 18.75 Gbit/sec <group_2> 18.75 * 0.67 = 12.5 Gbit/sec <group_3> 18.75 * 0.67 = 12.5 Gbit/sec <group_4> 18.75 * 0.33 = 6.25 Gbit/sec If in example above group_1 doesn't produce any traffic, then maximum bandwidth becomes 50 / (0.67 + 0.67 + 0.33) = ~30.0 Gbit/sec. Normalized values: <group_2> 30.0 * 0.67 = 20.0 Gbit/sec <group_3> 30.0 * 0.67 = 20.0 Gbit/sec <group_4> 30.0 * 0.33 = 10.0 Gbit/sec Same normalization applied to each vport in the group. Normalized values are internal, therefore driver provides QoS tracepoints for next events: * vport rate element creation/deletion: * vport rate element configuration; * group rate element creation/deletion; * group rate element configuration. PATCHES OVERVIEW 1 - Moving and isolation of eswitch QoS logic in separate file; 2 - Implement devlink leaf rate object support for vports; 3 - Implement rate groups creation/deletion; 4 - Implement TX rate management for the groups; 5 - Implement parent set for vports; 6 - Eswitch QoS tracepoints. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents e61fbee + 3202ea6 commit f96b48c

File tree

24 files changed

+1815
-703
lines changed

24 files changed

+1815
-703
lines changed

Documentation/networking/device_drivers/ethernet/mellanox/mlx5.rst

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -656,3 +656,47 @@ Bridge offloads tracepoints:
656656
$ cat /sys/kernel/debug/tracing/trace
657657
...
658658
ip-5387 [000] ...1 573713: mlx5_esw_bridge_vport_cleanup: vport_num=1
659+
660+
Eswitch QoS tracepoints:
661+
662+
- mlx5_esw_vport_qos_create: trace creation of transmit scheduler arbiter for vport::
663+
664+
$ echo mlx5:mlx5_esw_vport_qos_create >> /sys/kernel/debug/tracing/set_event
665+
$ cat /sys/kernel/debug/tracing/trace
666+
...
667+
<...>-23496 [018] .... 73136.838831: mlx5_esw_vport_qos_create: (0000:82:00.0) vport=2 tsar_ix=4 bw_share=0, max_rate=0 group=000000007b576bb3
668+
669+
- mlx5_esw_vport_qos_config: trace configuration of transmit scheduler arbiter for vport::
670+
671+
$ echo mlx5:mlx5_esw_vport_qos_config >> /sys/kernel/debug/tracing/set_event
672+
$ cat /sys/kernel/debug/tracing/trace
673+
...
674+
<...>-26548 [023] .... 75754.223823: mlx5_esw_vport_qos_config: (0000:82:00.0) vport=1 tsar_ix=3 bw_share=34, max_rate=10000 group=000000007b576bb3
675+
676+
- mlx5_esw_vport_qos_destroy: trace deletion of transmit scheduler arbiter for vport::
677+
678+
$ echo mlx5:mlx5_esw_vport_qos_destroy >> /sys/kernel/debug/tracing/set_event
679+
$ cat /sys/kernel/debug/tracing/trace
680+
...
681+
<...>-27418 [004] .... 76546.680901: mlx5_esw_vport_qos_destroy: (0000:82:00.0) vport=1 tsar_ix=3
682+
683+
- mlx5_esw_group_qos_create: trace creation of transmit scheduler arbiter for rate group::
684+
685+
$ echo mlx5:mlx5_esw_group_qos_create >> /sys/kernel/debug/tracing/set_event
686+
$ cat /sys/kernel/debug/tracing/trace
687+
...
688+
<...>-26578 [008] .... 75776.022112: mlx5_esw_group_qos_create: (0000:82:00.0) group=000000008dac63ea tsar_ix=5
689+
690+
- mlx5_esw_group_qos_config: trace configuration of transmit scheduler arbiter for rate group::
691+
692+
$ echo mlx5:mlx5_esw_group_qos_config >> /sys/kernel/debug/tracing/set_event
693+
$ cat /sys/kernel/debug/tracing/trace
694+
...
695+
<...>-27303 [020] .... 76461.455356: mlx5_esw_group_qos_config: (0000:82:00.0) group=000000008dac63ea tsar_ix=5 bw_share=100 max_rate=20000
696+
697+
- mlx5_esw_group_qos_destroy: trace deletion of transmit scheduler arbiter for group::
698+
699+
$ echo mlx5:mlx5_esw_group_qos_destroy >> /sys/kernel/debug/tracing/set_event
700+
$ cat /sys/kernel/debug/tracing/trace
701+
...
702+
<...>-27418 [006] .... 76547.187258: mlx5_esw_group_qos_destroy: (0000:82:00.0) group=000000007b576bb3 tsar_ix=1

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

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,19 +44,22 @@ mlx5_core-$(CONFIG_MLX5_CLS_ACT) += en_tc.o en/rep/tc.o en/rep/neigh.o \
4444
lib/fs_chains.o en/tc_tun.o \
4545
esw/indir_table.o en/tc_tun_encap.o \
4646
en/tc_tun_vxlan.o en/tc_tun_gre.o en/tc_tun_geneve.o \
47-
en/tc_tun_mplsoudp.o diag/en_tc_tracepoint.o
47+
en/tc_tun_mplsoudp.o diag/en_tc_tracepoint.o \
48+
en/tc/post_act.o
4849
mlx5_core-$(CONFIG_MLX5_TC_CT) += en/tc_ct.o
50+
mlx5_core-$(CONFIG_MLX5_TC_SAMPLE) += en/tc/sample.o
4951

5052
#
5153
# Core extra
5254
#
5355
mlx5_core-$(CONFIG_MLX5_ESWITCH) += eswitch.o eswitch_offloads.o eswitch_offloads_termtbl.o \
54-
ecpf.o rdma.o esw/legacy.o
56+
ecpf.o rdma.o esw/legacy.o \
57+
esw/devlink_port.o esw/vporttbl.o esw/qos.o
58+
5559
mlx5_core-$(CONFIG_MLX5_ESWITCH) += esw/acl/helper.o \
5660
esw/acl/egress_lgcy.o esw/acl/egress_ofld.o \
57-
esw/acl/ingress_lgcy.o esw/acl/ingress_ofld.o \
58-
esw/devlink_port.o esw/vporttbl.o
59-
mlx5_core-$(CONFIG_MLX5_TC_SAMPLE) += esw/sample.o
61+
esw/acl/ingress_lgcy.o esw/acl/ingress_ofld.o
62+
6063
mlx5_core-$(CONFIG_MLX5_BRIDGE) += esw/bridge.o en/rep/bridge.o
6164

6265
mlx5_core-$(CONFIG_MLX5_MPFS) += lib/mpfs.o

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "fw_reset.h"
88
#include "fs_core.h"
99
#include "eswitch.h"
10+
#include "esw/qos.h"
1011
#include "sf/dev/dev.h"
1112
#include "sf/sf.h"
1213

@@ -292,6 +293,13 @@ static const struct devlink_ops mlx5_devlink_ops = {
292293
.eswitch_encap_mode_get = mlx5_devlink_eswitch_encap_mode_get,
293294
.port_function_hw_addr_get = mlx5_devlink_port_function_hw_addr_get,
294295
.port_function_hw_addr_set = mlx5_devlink_port_function_hw_addr_set,
296+
.rate_leaf_tx_share_set = mlx5_esw_devlink_rate_leaf_tx_share_set,
297+
.rate_leaf_tx_max_set = mlx5_esw_devlink_rate_leaf_tx_max_set,
298+
.rate_node_tx_share_set = mlx5_esw_devlink_rate_node_tx_share_set,
299+
.rate_node_tx_max_set = mlx5_esw_devlink_rate_node_tx_max_set,
300+
.rate_node_new = mlx5_esw_devlink_rate_node_new,
301+
.rate_node_del = mlx5_esw_devlink_rate_node_del,
302+
.rate_leaf_parent_set = mlx5_esw_devlink_rate_parent_set,
295303
#endif
296304
#ifdef CONFIG_MLX5_SF_MANAGER
297305
.port_new = mlx5_devlink_sf_port_new,

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
#include "mod_hdr.h"
88
#include "lib/fs_ttc.h"
99

10+
struct mlx5e_post_act;
11+
1012
enum {
1113
MLX5E_TC_FT_LEVEL = 0,
1214
MLX5E_TC_TTC_FT_LEVEL,
@@ -19,6 +21,7 @@ struct mlx5e_tc_table {
1921
struct mutex t_lock;
2022
struct mlx5_flow_table *t;
2123
struct mlx5_fs_chains *chains;
24+
struct mlx5e_post_act *post_act;
2225

2326
struct rhashtable ht;
2427

drivers/net/ethernet/mellanox/mlx5/core/en/rep/tc.c

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
#include "en/mapping.h"
1818
#include "en/tc_tun.h"
1919
#include "lib/port_tun.h"
20-
#include "esw/sample.h"
20+
#include "en/tc/sample.h"
2121

2222
struct mlx5e_rep_indr_block_priv {
2323
struct net_device *netdev;
@@ -516,7 +516,6 @@ void mlx5e_rep_tc_netdevice_event_unregister(struct mlx5e_rep_priv *rpriv)
516516
mlx5e_rep_indr_block_unbind);
517517
}
518518

519-
#if IS_ENABLED(CONFIG_NET_TC_SKB_EXT)
520519
static bool mlx5e_restore_tunnel(struct mlx5e_priv *priv, struct sk_buff *skb,
521520
struct mlx5e_tc_update_priv *tc_priv,
522521
u32 tunnel_id)
@@ -609,12 +608,13 @@ static bool mlx5e_restore_tunnel(struct mlx5e_priv *priv, struct sk_buff *skb,
609608
return true;
610609
}
611610

612-
static bool mlx5e_restore_skb(struct sk_buff *skb, u32 chain, u32 reg_c1,
613-
struct mlx5e_tc_update_priv *tc_priv)
611+
static bool mlx5e_restore_skb_chain(struct sk_buff *skb, u32 chain, u32 reg_c1,
612+
struct mlx5e_tc_update_priv *tc_priv)
614613
{
615614
struct mlx5e_priv *priv = netdev_priv(skb->dev);
616615
u32 tunnel_id = (reg_c1 >> ESW_TUN_OFFSET) & TUNNEL_ID_MASK;
617616

617+
#if IS_ENABLED(CONFIG_NET_TC_SKB_EXT)
618618
if (chain) {
619619
struct mlx5_rep_uplink_priv *uplink_priv;
620620
struct mlx5e_rep_priv *uplink_rpriv;
@@ -636,9 +636,25 @@ static bool mlx5e_restore_skb(struct sk_buff *skb, u32 chain, u32 reg_c1,
636636
zone_restore_id))
637637
return false;
638638
}
639+
#endif /* CONFIG_NET_TC_SKB_EXT */
640+
639641
return mlx5e_restore_tunnel(priv, skb, tc_priv, tunnel_id);
640642
}
641-
#endif /* CONFIG_NET_TC_SKB_EXT */
643+
644+
static void mlx5e_restore_skb_sample(struct mlx5e_priv *priv, struct sk_buff *skb,
645+
struct mlx5_mapped_obj *mapped_obj,
646+
struct mlx5e_tc_update_priv *tc_priv)
647+
{
648+
if (!mlx5e_restore_tunnel(priv, skb, tc_priv, mapped_obj->sample.tunnel_id)) {
649+
netdev_dbg(priv->netdev,
650+
"Failed to restore tunnel info for sampled packet\n");
651+
return;
652+
}
653+
#if IS_ENABLED(CONFIG_MLX5_TC_SAMPLE)
654+
mlx5e_tc_sample_skb(skb, mapped_obj);
655+
#endif /* CONFIG_MLX5_TC_SAMPLE */
656+
mlx5_rep_tc_post_napi_receive(tc_priv);
657+
}
642658

643659
bool mlx5e_rep_tc_update_skb(struct mlx5_cqe64 *cqe,
644660
struct sk_buff *skb,
@@ -647,7 +663,7 @@ bool mlx5e_rep_tc_update_skb(struct mlx5_cqe64 *cqe,
647663
struct mlx5_mapped_obj mapped_obj;
648664
struct mlx5_eswitch *esw;
649665
struct mlx5e_priv *priv;
650-
u32 reg_c0, reg_c1;
666+
u32 reg_c0;
651667
int err;
652668

653669
reg_c0 = (be32_to_cpu(cqe->sop_drop_qpn) & MLX5E_TC_FLOW_ID_MASK);
@@ -659,8 +675,6 @@ bool mlx5e_rep_tc_update_skb(struct mlx5_cqe64 *cqe,
659675
*/
660676
skb->mark = 0;
661677

662-
reg_c1 = be32_to_cpu(cqe->ft_metadata);
663-
664678
priv = netdev_priv(skb->dev);
665679
esw = priv->mdev->priv.eswitch;
666680
err = mapping_find(esw->offloads.reg_c0_obj_pool, reg_c0, &mapped_obj);
@@ -671,18 +685,14 @@ bool mlx5e_rep_tc_update_skb(struct mlx5_cqe64 *cqe,
671685
return false;
672686
}
673687

674-
#if IS_ENABLED(CONFIG_NET_TC_SKB_EXT)
675-
if (mapped_obj.type == MLX5_MAPPED_OBJ_CHAIN)
676-
return mlx5e_restore_skb(skb, mapped_obj.chain, reg_c1, tc_priv);
677-
#endif /* CONFIG_NET_TC_SKB_EXT */
678-
#if IS_ENABLED(CONFIG_MLX5_TC_SAMPLE)
679-
if (mapped_obj.type == MLX5_MAPPED_OBJ_SAMPLE) {
680-
mlx5_esw_sample_skb(skb, &mapped_obj);
688+
if (mapped_obj.type == MLX5_MAPPED_OBJ_CHAIN) {
689+
u32 reg_c1 = be32_to_cpu(cqe->ft_metadata);
690+
691+
return mlx5e_restore_skb_chain(skb, mapped_obj.chain, reg_c1, tc_priv);
692+
} else if (mapped_obj.type == MLX5_MAPPED_OBJ_SAMPLE) {
693+
mlx5e_restore_skb_sample(priv, skb, &mapped_obj, tc_priv);
681694
return false;
682-
}
683-
#endif /* CONFIG_MLX5_TC_SAMPLE */
684-
if (mapped_obj.type != MLX5_MAPPED_OBJ_SAMPLE &&
685-
mapped_obj.type != MLX5_MAPPED_OBJ_CHAIN) {
695+
} else {
686696
netdev_dbg(priv->netdev, "Invalid mapped object type: %d\n", mapped_obj.type);
687697
return false;
688698
}
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
2+
// Copyright (c) 2021, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3+
4+
#include "en_tc.h"
5+
#include "post_act.h"
6+
#include "mlx5_core.h"
7+
8+
struct mlx5e_post_act {
9+
enum mlx5_flow_namespace_type ns_type;
10+
struct mlx5_fs_chains *chains;
11+
struct mlx5_flow_table *ft;
12+
struct mlx5e_priv *priv;
13+
struct xarray ids;
14+
};
15+
16+
struct mlx5e_post_act_handle {
17+
enum mlx5_flow_namespace_type ns_type;
18+
struct mlx5_flow_attr *attr;
19+
struct mlx5_flow_handle *rule;
20+
u32 id;
21+
};
22+
23+
#define MLX5_POST_ACTION_BITS (mlx5e_tc_attr_to_reg_mappings[FTEID_TO_REG].mlen)
24+
#define MLX5_POST_ACTION_MAX GENMASK(MLX5_POST_ACTION_BITS - 1, 0)
25+
#define MLX5_POST_ACTION_MASK MLX5_POST_ACTION_MAX
26+
27+
struct mlx5e_post_act *
28+
mlx5e_tc_post_act_init(struct mlx5e_priv *priv, struct mlx5_fs_chains *chains,
29+
enum mlx5_flow_namespace_type ns_type)
30+
{
31+
struct mlx5e_post_act *post_act;
32+
int err;
33+
34+
if (ns_type == MLX5_FLOW_NAMESPACE_FDB &&
35+
!MLX5_CAP_ESW_FLOWTABLE_FDB(priv->mdev, ignore_flow_level)) {
36+
mlx5_core_warn(priv->mdev, "firmware level support is missing\n");
37+
err = -EOPNOTSUPP;
38+
goto err_check;
39+
} else if (!MLX5_CAP_FLOWTABLE_NIC_RX(priv->mdev, ignore_flow_level)) {
40+
mlx5_core_warn(priv->mdev, "firmware level support is missing\n");
41+
err = -EOPNOTSUPP;
42+
goto err_check;
43+
}
44+
45+
post_act = kzalloc(sizeof(*post_act), GFP_KERNEL);
46+
if (!post_act) {
47+
err = -ENOMEM;
48+
goto err_check;
49+
}
50+
post_act->ft = mlx5_chains_create_global_table(chains);
51+
if (IS_ERR(post_act->ft)) {
52+
err = PTR_ERR(post_act->ft);
53+
mlx5_core_warn(priv->mdev, "failed to create post action table, err: %d\n", err);
54+
goto err_ft;
55+
}
56+
post_act->chains = chains;
57+
post_act->ns_type = ns_type;
58+
post_act->priv = priv;
59+
xa_init_flags(&post_act->ids, XA_FLAGS_ALLOC1);
60+
return post_act;
61+
62+
err_ft:
63+
kfree(post_act);
64+
err_check:
65+
return ERR_PTR(err);
66+
}
67+
68+
void
69+
mlx5e_tc_post_act_destroy(struct mlx5e_post_act *post_act)
70+
{
71+
if (IS_ERR_OR_NULL(post_act))
72+
return;
73+
74+
xa_destroy(&post_act->ids);
75+
mlx5_chains_destroy_global_table(post_act->chains, post_act->ft);
76+
kfree(post_act);
77+
}
78+
79+
struct mlx5e_post_act_handle *
80+
mlx5e_tc_post_act_add(struct mlx5e_post_act *post_act, struct mlx5_flow_attr *attr)
81+
{
82+
u32 attr_sz = ns_to_attr_sz(post_act->ns_type);
83+
struct mlx5e_post_act_handle *handle = NULL;
84+
struct mlx5_flow_attr *post_attr = NULL;
85+
struct mlx5_flow_spec *spec = NULL;
86+
int err;
87+
88+
handle = kzalloc(sizeof(*handle), GFP_KERNEL);
89+
spec = kvzalloc(sizeof(*spec), GFP_KERNEL);
90+
post_attr = mlx5_alloc_flow_attr(post_act->ns_type);
91+
if (!handle || !spec || !post_attr) {
92+
kfree(post_attr);
93+
kvfree(spec);
94+
kfree(handle);
95+
return ERR_PTR(-ENOMEM);
96+
}
97+
98+
memcpy(post_attr, attr, attr_sz);
99+
post_attr->chain = 0;
100+
post_attr->prio = 0;
101+
post_attr->ft = post_act->ft;
102+
post_attr->inner_match_level = MLX5_MATCH_NONE;
103+
post_attr->outer_match_level = MLX5_MATCH_NONE;
104+
post_attr->action &= ~(MLX5_FLOW_CONTEXT_ACTION_DECAP);
105+
106+
handle->ns_type = post_act->ns_type;
107+
/* Splits were handled before post action */
108+
if (handle->ns_type == MLX5_FLOW_NAMESPACE_FDB)
109+
post_attr->esw_attr->split_count = 0;
110+
111+
err = xa_alloc(&post_act->ids, &handle->id, post_attr,
112+
XA_LIMIT(1, MLX5_POST_ACTION_MAX), GFP_KERNEL);
113+
if (err)
114+
goto err_xarray;
115+
116+
/* Post action rule matches on fte_id and executes original rule's
117+
* tc rule action
118+
*/
119+
mlx5e_tc_match_to_reg_match(spec, FTEID_TO_REG,
120+
handle->id, MLX5_POST_ACTION_MASK);
121+
122+
handle->rule = mlx5_tc_rule_insert(post_act->priv, spec, post_attr);
123+
if (IS_ERR(handle->rule)) {
124+
err = PTR_ERR(handle->rule);
125+
netdev_warn(post_act->priv->netdev, "Failed to add post action rule");
126+
goto err_rule;
127+
}
128+
handle->attr = post_attr;
129+
130+
kvfree(spec);
131+
return handle;
132+
133+
err_rule:
134+
xa_erase(&post_act->ids, handle->id);
135+
err_xarray:
136+
kfree(post_attr);
137+
kvfree(spec);
138+
kfree(handle);
139+
return ERR_PTR(err);
140+
}
141+
142+
void
143+
mlx5e_tc_post_act_del(struct mlx5e_post_act *post_act, struct mlx5e_post_act_handle *handle)
144+
{
145+
mlx5_tc_rule_delete(post_act->priv, handle->rule, handle->attr);
146+
xa_erase(&post_act->ids, handle->id);
147+
kfree(handle->attr);
148+
kfree(handle);
149+
}
150+
151+
struct mlx5_flow_table *
152+
mlx5e_tc_post_act_get_ft(struct mlx5e_post_act *post_act)
153+
{
154+
return post_act->ft;
155+
}
156+
157+
/* Allocate a header modify action to write the post action handle fte id to a register. */
158+
int
159+
mlx5e_tc_post_act_set_handle(struct mlx5_core_dev *dev,
160+
struct mlx5e_post_act_handle *handle,
161+
struct mlx5e_tc_mod_hdr_acts *acts)
162+
{
163+
return mlx5e_tc_match_to_reg_set(dev, acts, handle->ns_type, FTEID_TO_REG, handle->id);
164+
}

0 commit comments

Comments
 (0)