From 8cd7725169aa51517c7358afde89bfae1ee08348 Mon Sep 17 00:00:00 2001 From: Ivan Malov Date: Wed, 13 Oct 2021 16:15:11 +0300 Subject: [PATCH] net/sfc: use action rules in tunnel offload jump rules By design, JUMP flows should be represented solely by the outer rules. But the HW/FW hasn't got support for setting Rx mark from RECIRC_ID on outer rule lookup yet. Neither does it support outer rule counters. As a workaround, an action rule of lower priority is used to do the job. Signed-off-by: Ivan Malov Reviewed-by: Andrew Rybchenko --- drivers/net/sfc/sfc_flow.c | 11 +++++--- drivers/net/sfc/sfc_mae.c | 56 ++++++++++++++++++++++++++++++++------ 2 files changed, 55 insertions(+), 12 deletions(-) diff --git a/drivers/net/sfc/sfc_flow.c b/drivers/net/sfc/sfc_flow.c index 51bf0992d6..82733b817a 100644 --- a/drivers/net/sfc/sfc_flow.c +++ b/drivers/net/sfc/sfc_flow.c @@ -2563,17 +2563,20 @@ sfc_flow_parse_rte_to_mae(struct rte_eth_dev *dev, if (spec_mae->ft_rule_type == SFC_FT_RULE_JUMP) { /* - * This flow is represented solely by the outer rule. - * It is supposed to mark and count matching packets. + * By design, this flow should be represented solely by the + * outer rule. But the HW/FW hasn't got support for setting + * Rx mark from RECIRC_ID on outer rule lookup yet. Neither + * does it support outer rule counters. As a workaround, an + * action rule of lower priority is used to do the job. + * + * So don't skip sfc_mae_rule_parse_actions() below. */ - goto skip_action_rule; } rc = sfc_mae_rule_parse_actions(sa, actions, spec_mae, error); if (rc != 0) goto fail; -skip_action_rule: if (spec_mae->ft != NULL) { if (spec_mae->ft_rule_type == SFC_FT_RULE_JUMP) spec_mae->ft->jump_rule_is_set = B_TRUE; diff --git a/drivers/net/sfc/sfc_mae.c b/drivers/net/sfc/sfc_mae.c index c972c2e3f2..72ffbfd3d1 100644 --- a/drivers/net/sfc/sfc_mae.c +++ b/drivers/net/sfc/sfc_mae.c @@ -2597,6 +2597,7 @@ sfc_mae_rule_parse_pattern(struct sfc_adapter *sa, struct rte_flow_error *error) { struct sfc_mae_parse_ctx ctx_mae; + unsigned int priority_shift = 0; struct sfc_flow_parse_ctx ctx; int rc; @@ -2608,13 +2609,32 @@ sfc_mae_rule_parse_pattern(struct sfc_adapter *sa, switch (ctx_mae.ft_rule_type) { case SFC_FT_RULE_JUMP: - /* No action rule */ - break; + /* + * By design, this flow should be represented solely by the + * outer rule. But the HW/FW hasn't got support for setting + * Rx mark from RECIRC_ID on outer rule lookup yet. Neither + * does it support outer rule counters. As a workaround, an + * action rule of lower priority is used to do the job. + */ + priority_shift = 1; + + /* FALLTHROUGH */ case SFC_FT_RULE_GROUP: + if (ctx_mae.priority != 0) { + /* + * Because of the above workaround, deny the + * use of priorities to JUMP and GROUP rules. + */ + rc = rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY, NULL, + "tunnel offload: priorities are not supported"); + goto fail_priority_check; + } + /* FALLTHROUGH */ case SFC_FT_RULE_NONE: rc = efx_mae_match_spec_init(sa->nic, EFX_MAE_RULE_ACTION, - spec->priority, + spec->priority + priority_shift, &ctx_mae.match_spec_action); if (rc != 0) { rc = rte_flow_error_set(error, rc, @@ -2689,6 +2709,7 @@ fail_encap_parse_init: efx_mae_match_spec_fini(sa->nic, ctx_mae.match_spec_action); fail_init_match_spec_action: +fail_priority_check: return rc; } @@ -3138,11 +3159,14 @@ sfc_mae_rule_parse_action_vxlan_encap( static int sfc_mae_rule_parse_action_mark(struct sfc_adapter *sa, const struct rte_flow_action_mark *conf, + const struct sfc_flow_spec_mae *spec_mae, efx_mae_actions_t *spec) { int rc; - if (conf->id > SFC_FT_USER_MARK_MASK) { + if (spec_mae->ft_rule_type == SFC_FT_RULE_JUMP) { + /* Workaround. See sfc_flow_parse_rte_to_mae() */ + } else if (conf->id > SFC_FT_USER_MARK_MASK) { sfc_err(sa, "the mark value is too large"); return EINVAL; } @@ -3302,16 +3326,18 @@ static const char * const action_names[] = { [RTE_FLOW_ACTION_TYPE_VF] = "VF", [RTE_FLOW_ACTION_TYPE_PORT_ID] = "PORT_ID", [RTE_FLOW_ACTION_TYPE_DROP] = "DROP", + [RTE_FLOW_ACTION_TYPE_JUMP] = "JUMP", }; static int sfc_mae_rule_parse_action(struct sfc_adapter *sa, const struct rte_flow_action *action, - const struct sfc_mae_outer_rule *outer_rule, + const struct sfc_flow_spec_mae *spec_mae, struct sfc_mae_actions_bundle *bundle, efx_mae_actions_t *spec, struct rte_flow_error *error) { + const struct sfc_mae_outer_rule *outer_rule = spec_mae->outer_rule; const uint64_t rx_metadata = sa->negotiated_rx_metadata; bool custom_error = B_FALSE; int rc = 0; @@ -3375,9 +3401,10 @@ sfc_mae_rule_parse_action(struct sfc_adapter *sa, case RTE_FLOW_ACTION_TYPE_MARK: SFC_BUILD_SET_OVERFLOW(RTE_FLOW_ACTION_TYPE_MARK, bundle->actions_mask); - if ((rx_metadata & RTE_ETH_RX_METADATA_USER_MARK) != 0) { + if ((rx_metadata & RTE_ETH_RX_METADATA_USER_MARK) != 0 || + spec_mae->ft_rule_type == SFC_FT_RULE_JUMP) { rc = sfc_mae_rule_parse_action_mark(sa, action->conf, - spec); + spec_mae, spec); } else { rc = rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, @@ -3411,6 +3438,12 @@ sfc_mae_rule_parse_action(struct sfc_adapter *sa, bundle->actions_mask); rc = efx_mae_action_set_populate_drop(spec); break; + case RTE_FLOW_ACTION_TYPE_JUMP: + if (spec_mae->ft_rule_type == SFC_FT_RULE_JUMP) { + /* Workaround. See sfc_flow_parse_rte_to_mae() */ + break; + } + /* FALLTHROUGH */ default: return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, NULL, @@ -3500,7 +3533,7 @@ sfc_mae_rule_parse_actions(struct sfc_adapter *sa, if (rc != 0) goto fail_rule_parse_action; - rc = sfc_mae_rule_parse_action(sa, action, spec_mae->outer_rule, + rc = sfc_mae_rule_parse_action(sa, action, spec_mae, &bundle, spec, error); if (rc != 0) goto fail_rule_parse_action; @@ -3524,6 +3557,12 @@ sfc_mae_rule_parse_actions(struct sfc_adapter *sa, switch (spec_mae->ft_rule_type) { case SFC_FT_RULE_NONE: break; + case SFC_FT_RULE_JUMP: + /* Workaround. See sfc_flow_parse_rte_to_mae() */ + rc = sfc_mae_rule_parse_action_pf_vf(sa, NULL, spec); + if (rc != 0) + goto fail_workaround_jump_delivery; + break; case SFC_FT_RULE_GROUP: /* * Packets that go to the rule's AR have FT mark set (from the @@ -3553,6 +3592,7 @@ sfc_mae_rule_parse_actions(struct sfc_adapter *sa, return 0; fail_action_set_add: +fail_workaround_jump_delivery: fail_nb_count: sfc_mae_encap_header_del(sa, encap_header); -- 2.20.1