Re: [PATCH/RFC net-next] tc: allow drivers to accept gact with PIPE when offloading
From: Marcelo Leitner <hidden>
Date: 2022-11-28 13:12:40
On Mon, Nov 28, 2022 at 07:11:05AM +0000, Tianyu Yuan wrote:
On Fri, Nov 25, 2022 at 10:20 PM Marcelo Leitner [off-list ref]quoted
On Fri, Nov 25, 2022 at 03:10:37AM +0000, Tianyu Yuan wrote:quoted
On Fri, Nov 25, 2022 at 10:21 AM Jamal Hadi Salim [off-list ref]wrote:quoted
quoted
I am not sure if the mlx5 changes will work since they both seem to be calling mlx5e_tc_act_get() which expects the act->id to exist in tc_acts_xxx tables, meaning mlx5e_tc_act_get() will always return you NULL and that check is hit before you check for ACT_PIPE. Something not obvious to me: Would all these drivers now be able to handle ACT_PIPE transparently as if no action is specified? Cant see the obvious connection to POLICE by just staring at the patch - is there and ACT_PIPE first then aPOLICE?quoted
quoted
Another question: If the ACT_PIPE count is not being updated in s/w - is there a h/w equivalent stat being updated? cheers, jamalThanks Jamal for your review. About mlx5e_tc_act_get(), I'll later add PIPE action in tc_acts_nic so that mlx5e_tc_act_get() will return the right act_id. In driver we choose just ignore this gact with ACT_PIPE, so after parsing the filter(rule) from kernel, the remaining actions are just like whatthey used to be without changes in this patch. So the flow could be processed as before.quoted
The connection between POLICE and ACT_PIPE may exist in userspace (e.g. ovs), we could put a gact (PIPE) at the beginning place in each tc filter.We will also have an OVS patch for this propose.quoted
I'm not very clear with your last case, but in expectation, the once the traffic is offloaded in h/w tc datapath, the stats will be updated by the flower stats from hardware. And when the traffic is using s/w tcdatapath, the stats are from software. I'm still confused here. Take, for example cxgb4 driver below. It will simply ignore this action AFAICT. This is good because it will still offload whatever vswitchd would be offloading but then, I don't see how the stats will be right in the end. I think the hw stats will be zeroed, no? (this is already considering the per action stats change that Oz is working on, see [ RFC net-next v2 0/2] net: flow_offload: add support for per action hw stats) I think the drivers have to reject the action if they don't support it, and vswitchd will have to probe for proper support when starting. Other than this, patch seems good. Thanks, MarceloThanks Marcelo for your reply
Likewise :)
As far as I've seen, in kernel tc (fl_hw_update_stats()), the flower stats from hw datapath is updated as following: 1) get the flower stats from each driver directly using the registered offload api and store it in cls_flower 2) using the dumped stats in cls_flower to update stats for each action in this filter (tcf_exts_hw_stats_update()) So the stats of gact with PIPE will still be updated using the stats above even though this action is ignored and actually not processed by hw.
Right, but...
Furthermore, I think the current stats for each action mentioned in 2) cannot represent the real hw stats and this is why [ RFC net-next v2 0/2] (net: flow_offload: add support for per action hw stats) will come up.
Exactly. Then, when this patchset (or similar) come up, it won't update all actions with the same stats anymore. It will require a set of stats from hw for the gact with PIPE action here. But if drivers are ignoring this action, they can't have specific stats for it. Or am I missing something? So it is better for the drivers to reject the whole flow instead of simply ignoring it, and let vswitchd probe if it should or should not use this action. Cheers, Marcelo
Cheers, Tianyuquoted
quoted
B.R. Tianyuquoted
On Tue, Nov 22, 2022 at 6:21 AM Simon Horman [off-list ref] wrote:quoted
From: Tianyu Yuan <redacted> Support gact with PIPE action when setting up gact in TC. This PIPE gact could come first in each tc filter to update the filter(flow) stats. The stats for each actons in a filter are updated by the flower stats from HW(via netdev drivers) in kernel TC rather than drivers. In each netdev driver, we don't have to process this gact, but only to ignore it to make sure the whole rule can be offloaded. Background: This is a proposed solution to a problem with a miss-match between TC police action instances - which may be shared between flows - and OpenFlow meter actions - the action is per flow, while the underlying meter may be shared. The key problem being that the police action statistics are shared between flows, and this does not match the requirement of OpenFlow for per-flow statistics. Ref: [ovs-dev] [PATCH] tests: fix reference output for meter offload stats https://mail.openvswitch.org/pipermail/ovs-dev/2022-October/398363.htmquoted
l Signed-off-by: Tianyu Yuan <redacted> Signed-off-by: Simon Horman <redacted> --- drivers/net/dsa/ocelot/felix_vsc9959.c | 5 +++++ drivers/net/dsa/sja1105/sja1105_flower.c | 5 +++++ drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c | 5 +++++ drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-flower.c | 6++++++quoted
quoted
quoted
drivers/net/ethernet/intel/ice/ice_tc_lib.c | 5 +++++ drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c | 5 +++++ drivers/net/ethernet/marvell/prestera/prestera_flower.c | 5 +++++ drivers/net/ethernet/mediatek/mtk_ppe_offload.c | 5 +++++ drivers/net/ethernet/mellanox/mlx5/core/en/rep/tc.c | 6 ++++++ drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 5 +++++ drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c | 5+++++quoted
quoted
quoted
drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c | 4 ++++ drivers/net/ethernet/mscc/ocelot_flower.c | 5 +++++ drivers/net/ethernet/netronome/nfp/flower/action.c | 5 +++++ drivers/net/ethernet/qlogic/qede/qede_filter.c | 5 +++++| 5 +++++quoted
drivers/net/ethernet/ti/cpsw_priv.c | 5 +++++ net/sched/act_gact.c | 7 ++++--- 18 files changed, 90 insertions(+), 3 deletions(-)diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.cb/drivers/net/dsa/ocelot/felix_vsc9959.c index b0ae8d6156f6..e54eb8e28386 100644--- a/drivers/net/dsa/ocelot/felix_vsc9959.c +++ b/drivers/net/dsa/ocelot/felix_vsc9959.c@@ -2217,6 +2217,11 @@ static int vsc9959_psfp_filter_add(structocelot*ocelot, int port,quoted
sfi.fmid = index; sfi.maxsdu = a->police.mtu; break; + /* Just ignore GACT with pipe action to let this + action count thepackets.quoted
+ * The NIC doesn't have to process this action + */ + case FLOW_ACTION_PIPE: + break; default: mutex_unlock(&psfp->lock); return -EOPNOTSUPP; diff --git a/drivers/net/dsa/sja1105/sja1105_flower.c b/drivers/net/dsa/sja1105/sja1105_flower.c index fad5afe3819c..d3eeeeea152a 100644--- a/drivers/net/dsa/sja1105/sja1105_flower.c +++ b/drivers/net/dsa/sja1105/sja1105_flower.c@@ -426,6 +426,11 @@ int sja1105_cls_flower_add(struct dsa_switch*ds,int port,quoted
if (rc) goto out; break; + /* Just ignore GACT with pipe action to let this + action count thepackets.quoted
+ * The NIC doesn't have to process this action + */ + case FLOW_ACTION_PIPE: + break; default: NL_SET_ERR_MSG_MOD(extack, "Action not supported"); diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c index dd9be229819a..443f405c0ed4 100644--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c@@ -770,6 +770,11 @@ int cxgb4_validate_flow_actions(structnet_device*dev,quoted
case FLOW_ACTION_QUEUE: /* Do nothing. cxgb4_set_filter will validate */ break; + /* Just ignore GACT with pipe action to let this + action count thepackets.quoted
+ * The NIC doesn't have to process this action + */ + case FLOW_ACTION_PIPE: + break; default: netdev_err(dev, "%s: Unsupported action\n", __func__); return -EOPNOTSUPP; diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-flower.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-flower.c index cacd454ac696..cfbf2f76e83a 100644--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-flower.c +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-flower.c@@ -378,6 +378,11 @@ static intdpaa2_switch_tc_parse_action_acl(structethsw_core *ethsw,quoted
case FLOW_ACTION_DROP: dpsw_act->action = DPSW_ACL_ACTION_DROP; break; + /* Just ignore GACT with pipe action to let this action + count thepackets.quoted
+ * The NIC doesn't have to process this action + */ + case FLOW_ACTION_PIPE: + break; default: NL_SET_ERR_MSG_MOD(extack, "Action not supported"); @@ -651,6 +656,7 @@ int dpaa2_switch_cls_flower_replace(structdpaa2_switch_filter_block *block,quoted
case FLOW_ACTION_REDIRECT: case FLOW_ACTION_TRAP: case FLOW_ACTION_DROP: + case FLOW_ACTION_PIPE: return dpaa2_switch_cls_flower_replace_acl(block, cls); case FLOW_ACTION_MIRRED: return dpaa2_switch_cls_flower_replace_mirror(block, cls); diff --git a/drivers/net/ethernet/intel/ice/ice_tc_lib.c b/drivers/net/ethernet/intel/ice/ice_tc_lib.c index faba0f857cd9..5908ad4d0170 100644--- a/drivers/net/ethernet/intel/ice/ice_tc_lib.c +++ b/drivers/net/ethernet/intel/ice/ice_tc_lib.c@@ -642,6 +642,11 @@ ice_eswitch_tc_parse_action(structice_tc_flower_fltr *fltr, break; + /* Just ignore GACT with pipe action to let this action + count thepackets.quoted
+ * The NIC doesn't have to process this action + */ + case FLOW_ACTION_PIPE: + break; default: NL_SET_ERR_MSG_MOD(fltr->extack, "Unsupported action inswitchdev mode");quoted
return -EINVAL;diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.cb/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c index e64318c110fd..fc05897adb70 100644--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c@@ -450,6 +450,11 @@ static int otx2_tc_parse_actions(structotx2_nic*nic,quoted
case FLOW_ACTION_MARK: mark = act->mark; break; + /* Just ignore GACT with pipe action to let this + action count thepackets.quoted
+ * The NIC doesn't have to process this action + */ + case FLOW_ACTION_PIPE: + break; default: return -EOPNOTSUPP; } diff --git a/drivers/net/ethernet/marvell/prestera/prestera_flower.c b/drivers/net/ethernet/marvell/prestera/prestera_flower.c index 91a478b75cbf..9686ed086e35 100644--- a/drivers/net/ethernet/marvell/prestera/prestera_flower.c +++ b/drivers/net/ethernet/marvell/prestera/prestera_flower.c@@ -126,6 +126,11 @@ static intprestera_flower_parse_actions(structprestera_flow_block *block,quoted
if (err) return err; break; + /* Just ignore GACT with pipe action to let this + action count thepackets.quoted
+ * The NIC doesn't have to process this action + */ + case FLOW_ACTION_PIPE: + break; default: NL_SET_ERR_MSG_MOD(extack, "Unsupported action"); pr_err("Unsupported action\n"); diff --git a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c index 81afd5ee3fbf..91e4d3fcc756 100644--- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c +++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c@@ -344,6 +344,11 @@ mtk_flow_offload_replace(struct mtk_eth*eth,quoted
quoted
struct flow_cls_offload *f)quoted
data.pppoe.sid = act->pppoe.sid; data.pppoe.num++; break; + /* Just ignore GACT with pipe action to let this + action count thepackets.quoted
+ * The NIC doesn't have to process this action + */ + case FLOW_ACTION_PIPE: + break; default: return -EOPNOTSUPP; }diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/rep/tc.cb/drivers/net/ethernet/mellanox/mlx5/core/en/rep/tc.c index b08339d986d5..231660cb1daf 100644--- a/drivers/net/ethernet/mellanox/mlx5/core/en/rep/tc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/rep/tc.c@@ -544,6 +544,12 @@ mlx5e_rep_indr_replace_act(structmlx5e_rep_priv *rpriv,quoted
if (!act->offload_action) continue; + /* Just ignore GACT with pipe action to let this + action count thepackets.quoted
+ * The NIC doesn't have to process this action + */ + if (action->id == FLOW_ACTION_PIPE) + continue; + if (!act->offload_action(priv, fl_act, action)) add = true; }diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.cb/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c index 3782f0097292..adac2ce9b24f 100644--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c@@ -3853,6 +3853,11 @@ parse_tc_actions(structmlx5e_tc_act_parse_state *parse_state, flow_action_for_each(i, _act, &flow_action_reorder) { act = *_act; + /* Just ignore GACT with pipe action to let this + action count thepackets.quoted
+ * The NIC doesn't have to process this action + */ + if (act->id == FLOW_ACTION_PIPE) + continue; tc_act = mlx5e_tc_act_get(act->id, ns_type); if (!tc_act) { NL_SET_ERR_MSG_MOD(extack, "Not implemented offload action"); diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c index e91fb205e0b4..9270bf9581c7 100644--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c@@ -266,6 +266,11 @@ static intmlxsw_sp_flower_parse_actions(structmlxsw_sp *mlxsw_sp,quoted
return err; break; } + /* Just ignore GACT with pipe action to let this + action count thepackets.quoted
+ * The NIC doesn't have to process this action + */ + case FLOW_ACTION_PIPE: + break; default: NL_SET_ERR_MSG_MOD(extack, "Unsupported action"); dev_err(mlxsw_sp->bus_info->dev, "Unsupported action\n"); diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c b/drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c index bd6bd380ba34..e32f5b5d1e95 100644--- a/drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c@@ -692,6 +692,10 @@ static int sparx5_tc_flower_replace(structnet_device *ndev,quoted
break; case FLOW_ACTION_GOTO: /* Links between VCAPs will be added later */ + /* Just ignore GACT with pipe action to let this + action count thepackets.quoted
+ * The NIC doesn't have to process this action + */ + case FLOW_ACTION_PIPE: break; default: NL_SET_ERR_MSG_MOD(fco->common.extack,diff --git a/drivers/net/ethernet/mscc/ocelot_flower.cb/drivers/net/ethernet/mscc/ocelot_flower.c index 7c0897e779dc..b8e01af0fb48 100644--- a/drivers/net/ethernet/mscc/ocelot_flower.c +++ b/drivers/net/ethernet/mscc/ocelot_flower.c@@ -492,6 +492,11 @@ static int ocelot_flower_parse_action(structocelot*ocelot, int port,quoted
} filter->type = OCELOT_PSFP_FILTER_OFFLOAD; break; + /* Just ignore GACT with pipe action to let this + action count thepackets.quoted
+ * The NIC doesn't have to process this action + */ + case FLOW_ACTION_PIPE: + break; default: NL_SET_ERR_MSG_MOD(extack, "Cannot offload action"); return -EOPNOTSUPP; diff --git a/drivers/net/ethernet/netronome/nfp/flower/action.c b/drivers/net/ethernet/netronome/nfp/flower/action.c index 2b383d92d7f5..57fd83b8e54a 100644--- a/drivers/net/ethernet/netronome/nfp/flower/action.c +++ b/drivers/net/ethernet/netronome/nfp/flower/action.c@@ -1209,6 +1209,11 @@ nfp_flower_loop_action(struct nfp_app*app,quoted
quoted
const struct flow_action_entry *act,quoted
if (err) return err; break; + /* Just ignore GACT with pipe action to let this action + count thepackets.quoted
+ * The NIC doesn't have to process this action + */ + case FLOW_ACTION_PIPE: + break; default: /* Currently we do not handle any other actions. */ NL_SET_ERR_MSG_MOD(extack, "unsupported offload: unsupported action in action list"); diff --git a/drivers/net/ethernet/qlogic/qede/qede_filter.c b/drivers/net/ethernet/qlogic/qede/qede_filter.c index 3010833ddde3..69110d5978d8 100644--- a/drivers/net/ethernet/qlogic/qede/qede_filter.c +++ b/drivers/net/ethernet/qlogic/qede/qede_filter.c@@ -1691,6 +1691,11 @@ static int qede_parse_actions(structqede_dev*edev,quoted
return -EINVAL; } break; + /* Just ignore GACT with pipe action to let this + action count thepackets.quoted
+ * The NIC doesn't have to process this action + */ + case FLOW_ACTION_PIPE: + break; default: return -EINVAL; }diff --git a/drivers/net/ethernet/sfc/tc.cb/drivers/net/ethernet/sfc/tc.c index deeaab9ee761..7256bbcdcc59 100644--- a/drivers/net/ethernet/sfc/tc.c +++ b/drivers/net/ethernet/sfc/tc.c@@ -494,6 +494,11 @@ static int efx_tc_flower_replace(structefx_nic*efx,quoted
} *act = save; break; + /* Just ignore GACT with pipe action to let this + action count thepackets.quoted
+ * The NIC doesn't have to process this action + */ + case FLOW_ACTION_PIPE: + break; default: NL_SET_ERR_MSG_FMT_MOD(extack, "Unhandledaction %u",quoted
quoted
quoted
fa->id); diff --git a/drivers/net/ethernet/ti/cpsw_priv.c b/drivers/net/ethernet/ti/cpsw_priv.c index 758295c898ac..c0ac58db64d4 100644--- a/drivers/net/ethernet/ti/cpsw_priv.c +++ b/drivers/net/ethernet/ti/cpsw_priv.c@@ -1492,6 +1492,11 @@ static intcpsw_qos_configure_clsflower(struct cpsw_priv *priv, struct flow_cls_ return cpsw_qos_clsflower_add_policer(priv, extack, cls, act->police.rate_pkt_ps); + /* Just ignore GACT with pipe action to let this + action count thepackets.quoted
+ * The NIC doesn't have to process this action + */ + case FLOW_ACTION_PIPE: + break; default: NL_SET_ERR_MSG_MOD(extack, "Action not supported"); return -EOPNOTSUPP; diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c index 62d682b96b88..82d1371e251e 100644--- a/net/sched/act_gact.c +++ b/net/sched/act_gact.c@@ -250,15 +250,14 @@ static int tcf_gact_offload_act_setup(structtc_action *act, void *entry_data,quoted
} else if (is_tcf_gact_goto_chain(act)) { entry->id = FLOW_ACTION_GOTO; entry->chain_index = tcf_gact_goto_chain_index(act); + } else if (is_tcf_gact_pipe(act)) { + entry->id = FLOW_ACTION_PIPE; } else if (is_tcf_gact_continue(act)) { NL_SET_ERR_MSG_MOD(extack, "Offload of \"continue\"action is not supported");quoted
return -EOPNOTSUPP; } else if (is_tcf_gact_reclassify(act)) { NL_SET_ERR_MSG_MOD(extack, "Offload of \"reclassify\"action is not supported");quoted
return -EOPNOTSUPP; - } else if (is_tcf_gact_pipe(act)) { - NL_SET_ERR_MSG_MOD(extack, "Offload of \"pipe\"action isquoted
quoted
not supported");quoted
- return -EOPNOTSUPP; } else { NL_SET_ERR_MSG_MOD(extack, "Unsupported generic actionoffload");quoted
return -EOPNOTSUPP; @@ -275,6 +274,8 @@ static int tcf_gact_offload_act_setup(struct tc_action *act, void*entry_data,quoted
quoted
quoted
fl_action->id = FLOW_ACTION_TRAP; else if (is_tcf_gact_goto_chain(act)) fl_action->id = FLOW_ACTION_GOTO; + else if (is_tcf_gact_pipe(act)) + fl_action->id = FLOW_ACTION_PIPE; else return -EOPNOTSUPP; } -- 2.30.2