[dpdk-dev] [PATCH 12/62] common/sfc_efx/base: add a match specs class comparison API

Andrew Rybchenko arybchenko at solarflare.com
Tue Oct 20 10:47:39 CEST 2020


From: Ivan Malov <ivan.malov at oktetlabs.ru>

>From MAE standpoint, a flow rule belongs to some class. Field capabilities
advertised by the FW provide a hint on whether changing a particular match
field value or its mask will affect the class of the rule. A client driver
can make use of the concept of a class by comparing a rule being validated
with already inserted ones so that if an existing rule with the same class
is encountered, it will become possible to skip making an explicit request
to the FW because the class of an already inserted rule is wittingly valid.

Implement an API for client drivers to carry out the said class comparison.

Signed-off-by: Ivan Malov <ivan.malov at oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko at solarflare.com>
Reviewed-by: Andy Moreton <amoreton at xilinx.com>
---
 drivers/common/sfc_efx/base/efx.h             | 13 +++
 drivers/common/sfc_efx/base/efx_mae.c         | 96 +++++++++++++++++++
 .../sfc_efx/rte_common_sfc_efx_version.map    |  1 +
 3 files changed, 110 insertions(+)

diff --git a/drivers/common/sfc_efx/base/efx.h b/drivers/common/sfc_efx/base/efx.h
index 094fad6367..c91f7948a0 100644
--- a/drivers/common/sfc_efx/base/efx.h
+++ b/drivers/common/sfc_efx/base/efx.h
@@ -4098,6 +4098,19 @@ efx_mae_match_spec_is_valid(
 	__in				efx_nic_t *enp,
 	__in				const efx_mae_match_spec_t *spec);
 
+/*
+ * Conduct a comparison to check whether two match specifications
+ * of equal rule type (action / outer) and priority would map to
+ * the very same rule class from the firmware's standpoint.
+ */
+LIBEFX_API
+extern	__checkReturn			efx_rc_t
+efx_mae_match_specs_class_cmp(
+	__in				efx_nic_t *enp,
+	__in				const efx_mae_match_spec_t *left,
+	__in				const efx_mae_match_spec_t *right,
+	__out				boolean_t *have_same_classp);
+
 #endif /* EFSYS_OPT_MAE */
 
 #ifdef	__cplusplus
diff --git a/drivers/common/sfc_efx/base/efx_mae.c b/drivers/common/sfc_efx/base/efx_mae.c
index 9e22c3d507..a126cba37f 100644
--- a/drivers/common/sfc_efx/base/efx_mae.c
+++ b/drivers/common/sfc_efx/base/efx_mae.c
@@ -434,4 +434,100 @@ efx_mae_match_spec_is_valid(
 	return (is_valid);
 }
 
+	__checkReturn			efx_rc_t
+efx_mae_match_specs_class_cmp(
+	__in				efx_nic_t *enp,
+	__in				const efx_mae_match_spec_t *left,
+	__in				const efx_mae_match_spec_t *right,
+	__out				boolean_t *have_same_classp)
+{
+	efx_mae_t *maep = enp->en_maep;
+	unsigned int field_ncaps = maep->em_max_nfields;
+	const efx_mae_field_cap_t *field_caps;
+	const efx_mae_mv_desc_t *desc_setp;
+	unsigned int desc_set_nentries;
+	boolean_t have_same_class = B_TRUE;
+	efx_mae_field_id_t field_id;
+	const uint8_t *mvpl;
+	const uint8_t *mvpr;
+	efx_rc_t rc;
+
+	switch (left->emms_type) {
+	case EFX_MAE_RULE_ACTION:
+		field_caps = maep->em_action_rule_field_caps;
+		desc_setp = __efx_mae_action_rule_mv_desc_set;
+		desc_set_nentries =
+		    EFX_ARRAY_SIZE(__efx_mae_action_rule_mv_desc_set);
+		mvpl = left->emms_mask_value_pairs.action;
+		mvpr = right->emms_mask_value_pairs.action;
+		break;
+	default:
+		rc = ENOTSUP;
+		goto fail1;
+	}
+
+	if (field_caps == NULL) {
+		rc = EAGAIN;
+		goto fail2;
+	}
+
+	if (left->emms_type != right->emms_type ||
+	    left->emms_prio != right->emms_prio) {
+		/*
+		 * Rules of different types can never map to the same class.
+		 *
+		 * The FW can support some set of match criteria for one
+		 * priority and not support the very same set for
+		 * another priority. Thus, two rules which have
+		 * different priorities can never map to
+		 * the same class.
+		 */
+		*have_same_classp = B_FALSE;
+		return (0);
+	}
+
+	for (field_id = 0; field_id < desc_set_nentries; ++field_id) {
+		const efx_mae_mv_desc_t *descp = &desc_setp[field_id];
+		efx_mae_field_cap_id_t field_cap_id = descp->emmd_field_cap_id;
+
+		if (descp->emmd_mask_size == 0)
+			continue; /* Skip array gap */
+
+		if (field_cap_id >= field_ncaps)
+			break;
+
+		if (field_caps[field_cap_id].emfc_mask_affects_class) {
+			const uint8_t *lmaskp = mvpl + descp->emmd_mask_offset;
+			const uint8_t *rmaskp = mvpr + descp->emmd_mask_offset;
+			size_t mask_size = descp->emmd_mask_size;
+
+			if (memcmp(lmaskp, rmaskp, mask_size) != 0) {
+				have_same_class = B_FALSE;
+				break;
+			}
+		}
+
+		if (field_caps[field_cap_id].emfc_match_affects_class) {
+			const uint8_t *lvalp = mvpl + descp->emmd_value_offset;
+			const uint8_t *rvalp = mvpr + descp->emmd_value_offset;
+			size_t value_size = descp->emmd_value_size;
+
+			if (memcmp(lvalp, rvalp, value_size) != 0) {
+				have_same_class = B_FALSE;
+				break;
+			}
+		}
+	}
+
+	*have_same_classp = have_same_class;
+
+	return (0);
+
+fail2:
+	EFSYS_PROBE(fail2);
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+	return (rc);
+}
+
 #endif /* EFSYS_OPT_MAE */
diff --git a/drivers/common/sfc_efx/rte_common_sfc_efx_version.map b/drivers/common/sfc_efx/rte_common_sfc_efx_version.map
index 0e6d44b6dc..aeb6f4d134 100644
--- a/drivers/common/sfc_efx/rte_common_sfc_efx_version.map
+++ b/drivers/common/sfc_efx/rte_common_sfc_efx_version.map
@@ -91,6 +91,7 @@ INTERNAL {
 	efx_mae_match_spec_fini;
 	efx_mae_match_spec_init;
 	efx_mae_match_spec_is_valid;
+	efx_mae_match_specs_class_cmp;
 
 	efx_mcdi_fini;
 	efx_mcdi_get_proxy_handle;
-- 
2.17.1



More information about the dev mailing list