From patchwork Wed Jun 7 13:02:25 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ivan Malov X-Patchwork-Id: 128303 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id CB32942C4D; Wed, 7 Jun 2023 15:04:58 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 7129B42D8D; Wed, 7 Jun 2023 15:03:04 +0200 (CEST) Received: from agw.arknetworks.am (agw.arknetworks.am [79.141.165.80]) by mails.dpdk.org (Postfix) with ESMTP id DBA0642D43 for ; Wed, 7 Jun 2023 15:02:54 +0200 (CEST) Received: from localhost.localdomain (unknown [78.109.69.83]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by agw.arknetworks.am (Postfix) with ESMTPSA id 67914E1253; Wed, 7 Jun 2023 17:02:54 +0400 (+04) From: Ivan Malov To: dev@dpdk.org Cc: Andrew Rybchenko , Ferruh Yigit , Andy Moreton Subject: [PATCH v4 14/34] net/sfc: let driver-internal flows use VF representor action Date: Wed, 7 Jun 2023 17:02:25 +0400 Message-Id: <20230607130245.8048-15-ivan.malov@arknetworks.am> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20230607130245.8048-1-ivan.malov@arknetworks.am> References: <20230601195538.8265-1-ivan.malov@arknetworks.am> <20230607130245.8048-1-ivan.malov@arknetworks.am> MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org In the case of VF <--> VF representor pairs, these flows can only collect VF traffic, so let them use generic flow action PORT_REPRESENTOR, as part of re-using generic flow mechanism. Currently, it does not allow to access VF representors since they have no unique HW logical ports (m-ports). They all sit on the same (representor proxy) m-port, while demultiplexing of traffic uses ingress (VF) m-port value in packet metadata. Traffic from arbitrary sources cannot be identified this way. But, for VF traffic, it should be right to make an exception. Signed-off-by: Ivan Malov Reviewed-by: Andy Moreton --- drivers/net/sfc/sfc_mae.c | 25 +++++++++++++++++++------ drivers/net/sfc/sfc_repr.c | 20 ++++++++++++++++---- drivers/net/sfc/sfc_repr_proxy.c | 15 +++++++++++++++ drivers/net/sfc/sfc_repr_proxy_api.h | 3 +++ drivers/net/sfc/sfc_switch.c | 7 ++----- drivers/net/sfc/sfc_switch.h | 10 ++++++++++ 6 files changed, 65 insertions(+), 15 deletions(-) diff --git a/drivers/net/sfc/sfc_mae.c b/drivers/net/sfc/sfc_mae.c index 1928d58779..89fa75281f 100644 --- a/drivers/net/sfc/sfc_mae.c +++ b/drivers/net/sfc/sfc_mae.c @@ -1525,6 +1525,7 @@ sfc_mae_rule_parse_item_port_id(const struct rte_flow_item *item, const struct rte_flow_item_port_id *spec = NULL; const struct rte_flow_item_port_id *mask = NULL; efx_mport_sel_t mport_sel; + unsigned int type_mask; int rc; if (ctx_mae->match_mport_set) { @@ -1556,8 +1557,10 @@ sfc_mae_rule_parse_item_port_id(const struct rte_flow_item *item, "The port ID is too large"); } + type_mask = 1U << SFC_MAE_SWITCH_PORT_INDEPENDENT; + rc = sfc_mae_switch_get_ethdev_mport(ctx_mae->sa->mae.switch_domain_id, - spec->id, &mport_sel); + spec->id, type_mask, &mport_sel); if (rc != 0) { return rte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_ITEM, item, @@ -1590,6 +1593,7 @@ sfc_mae_rule_parse_item_ethdev_based(const struct rte_flow_item *item, const struct rte_flow_item_ethdev *spec = NULL; const struct rte_flow_item_ethdev *mask = NULL; efx_mport_sel_t mport_sel; + unsigned int type_mask; int rc; if (ctx_mae->match_mport_set) { @@ -1617,9 +1621,11 @@ sfc_mae_rule_parse_item_ethdev_based(const struct rte_flow_item *item, switch (item->type) { case RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR: + type_mask = 1U << SFC_MAE_SWITCH_PORT_INDEPENDENT; + rc = sfc_mae_switch_get_ethdev_mport( ctx_mae->sa->mae.switch_domain_id, - spec->port_id, &mport_sel); + spec->port_id, type_mask, &mport_sel); if (rc != 0) { return rte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_ITEM, item, @@ -3529,6 +3535,7 @@ sfc_mae_rule_parse_action_port_id(struct sfc_adapter *sa, { struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); struct sfc_mae *mae = &sa->mae; + unsigned int type_mask; efx_mport_sel_t mport; uint16_t port_id; int rc; @@ -3538,8 +3545,10 @@ sfc_mae_rule_parse_action_port_id(struct sfc_adapter *sa, port_id = (conf->original != 0) ? sas->port_id : conf->id; + type_mask = 1U << SFC_MAE_SWITCH_PORT_INDEPENDENT; + rc = sfc_mae_switch_get_ethdev_mport(mae->switch_domain_id, - port_id, &mport); + port_id, type_mask, &mport); if (rc != 0) { sfc_err(sa, "failed to get m-port for the given ethdev (port_id=%u): %s", port_id, strerror(rc)); @@ -3558,14 +3567,14 @@ sfc_mae_rule_parse_action_port_id(struct sfc_adapter *sa, static int sfc_mae_rule_parse_action_port_representor(struct sfc_adapter *sa, const struct rte_flow_action_ethdev *conf, - efx_mae_actions_t *spec) + unsigned int type_mask, efx_mae_actions_t *spec) { struct sfc_mae *mae = &sa->mae; efx_mport_sel_t mport; int rc; rc = sfc_mae_switch_get_ethdev_mport(mae->switch_domain_id, - conf->port_id, &mport); + conf->port_id, type_mask, &mport); if (rc != 0) { sfc_err(sa, "failed to get m-port for the given ethdev (port_id=%u): %s", conf->port_id, strerror(rc)); @@ -3641,6 +3650,7 @@ sfc_mae_rule_parse_action(struct sfc_adapter *sa, const struct sfc_mae_outer_rule *outer_rule = spec_mae->outer_rule; const uint64_t rx_metadata = sa->negotiated_rx_metadata; efx_mae_actions_t *spec = ctx->spec; + unsigned int switch_port_type_mask; bool custom_error = B_FALSE; int rc = 0; @@ -3757,8 +3767,11 @@ sfc_mae_rule_parse_action(struct sfc_adapter *sa, case RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR: SFC_BUILD_SET_OVERFLOW(RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR, bundle->actions_mask); + + switch_port_type_mask = 1U << SFC_MAE_SWITCH_PORT_INDEPENDENT; + rc = sfc_mae_rule_parse_action_port_representor(sa, - action->conf, spec); + action->conf, switch_port_type_mask, spec); break; case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT: SFC_BUILD_SET_OVERFLOW(RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT, diff --git a/drivers/net/sfc/sfc_repr.c b/drivers/net/sfc/sfc_repr.c index d4134ec91b..6c7727d569 100644 --- a/drivers/net/sfc/sfc_repr.c +++ b/drivers/net/sfc/sfc_repr.c @@ -933,15 +933,26 @@ sfc_repr_eth_dev_init(struct rte_eth_dev *dev, void *init_params) struct sfc_repr_shared *srs = sfc_repr_shared_by_eth_dev(dev); struct sfc_mae_switch_port_request switch_port_request; efx_mport_sel_t ethdev_mport_sel; + efx_mport_id_t proxy_mport_id; struct sfc_repr *sr; int ret; /* - * Currently there is no mport we can use for representor's - * ethdev. Use an invalid one for now. This way representors - * can be instantiated. + * For each representor, a driver-internal flow has to be installed + * in order to direct traffic coming from the represented entity to + * the "representor proxy". Such internal flows need to find ethdev + * mport by ethdev ID of the representors in question to specify in + * delivery action. So set the representor ethdev's mport to that + * of the "representor proxy" in below switch port request. */ - efx_mae_mport_invalid(ðdev_mport_sel); + sfc_repr_proxy_mport_alias_get(repr_data->pf_port_id, &proxy_mport_id); + + ret = efx_mae_mport_by_id(&proxy_mport_id, ðdev_mport_sel); + if (ret != 0) { + SFC_GENERIC_LOG(ERR, + "%s() failed to get repr proxy mport by ID", __func__); + goto fail_get_selector; + } memset(&switch_port_request, 0, sizeof(switch_port_request)); switch_port_request.type = SFC_MAE_SWITCH_PORT_REPRESENTOR; @@ -1033,6 +1044,7 @@ sfc_repr_eth_dev_init(struct rte_eth_dev *dev, void *init_params) fail_create_port: fail_mae_assign_switch_port: +fail_get_selector: SFC_GENERIC_LOG(ERR, "%s() failed: %s", __func__, rte_strerror(-ret)); return ret; } diff --git a/drivers/net/sfc/sfc_repr_proxy.c b/drivers/net/sfc/sfc_repr_proxy.c index 4ba7683370..74c3494c35 100644 --- a/drivers/net/sfc/sfc_repr_proxy.c +++ b/drivers/net/sfc/sfc_repr_proxy.c @@ -1708,3 +1708,18 @@ sfc_repr_proxy_repr_entity_mac_addr_set(uint16_t pf_port_id, uint16_t repr_id, return rc; } + +void +sfc_repr_proxy_mport_alias_get(uint16_t pf_port_id, efx_mport_id_t *mport_alias) +{ + const struct sfc_repr_proxy *rp; + struct sfc_adapter *sa; + + sa = sfc_get_adapter_by_pf_port_id(pf_port_id); + sfc_adapter_lock(sa); + rp = sfc_repr_proxy_by_adapter(sa); + + memcpy(mport_alias, &rp->mport_alias, sizeof(*mport_alias)); + + sfc_adapter_unlock(sa); +} diff --git a/drivers/net/sfc/sfc_repr_proxy_api.h b/drivers/net/sfc/sfc_repr_proxy_api.h index 1d38ab2451..07d79a50cb 100644 --- a/drivers/net/sfc/sfc_repr_proxy_api.h +++ b/drivers/net/sfc/sfc_repr_proxy_api.h @@ -46,6 +46,9 @@ int sfc_repr_proxy_stop_repr(uint16_t pf_port_id, uint16_t repr_id); int sfc_repr_proxy_repr_entity_mac_addr_set(uint16_t pf_port_id, uint16_t repr_id, const struct rte_ether_addr *mac_addr); +void sfc_repr_proxy_mport_alias_get(uint16_t pf_port_id, + efx_mport_id_t *mport_alias); + #ifdef __cplusplus } #endif diff --git a/drivers/net/sfc/sfc_switch.c b/drivers/net/sfc/sfc_switch.c index 8f1ee97fa8..f80de4e889 100644 --- a/drivers/net/sfc/sfc_switch.c +++ b/drivers/net/sfc/sfc_switch.c @@ -551,6 +551,7 @@ sfc_mae_find_switch_port_by_ethdev(uint16_t switch_domain_id, int sfc_mae_switch_get_ethdev_mport(uint16_t switch_domain_id, uint16_t ethdev_port_id, + unsigned int allowed_mae_switch_port_types, efx_mport_sel_t *mport_sel) { struct sfc_mae_switch_port *port; @@ -562,11 +563,7 @@ sfc_mae_switch_get_ethdev_mport(uint16_t switch_domain_id, if (rc != 0) goto unlock; - if (port->type != SFC_MAE_SWITCH_PORT_INDEPENDENT) { - /* - * The ethdev is a "VF representor". It does not own - * a dedicated m-port suitable for use in flow rules. - */ + if (((1U << port->type) & allowed_mae_switch_port_types) == 0) { rc = ENOTSUP; goto unlock; } diff --git a/drivers/net/sfc/sfc_switch.h b/drivers/net/sfc/sfc_switch.h index 62aea9b785..6a85ce4dcf 100644 --- a/drivers/net/sfc/sfc_switch.h +++ b/drivers/net/sfc/sfc_switch.h @@ -102,8 +102,18 @@ int sfc_mae_assign_switch_port(uint16_t switch_domain_id, int sfc_mae_clear_switch_port(uint16_t switch_domain_id, uint16_t switch_port_id); +/* + * For user flows, allowed_mae_switch_port_types can only contain bit + * SFC_MAE_SWITCH_PORT_INDEPENDENT, meaning that only those ethdevs + * that have their own MAE m-ports can be accessed by a port-based + * action. For driver-internal flows, this mask can also contain + * bit SFC_MAE_SWITCH_PORT_REPRESENTOR to allow VF traffic to be + * sent to the common MAE m-port of all such REPRESENTOR ports + * via a port-based action, for default switch interconnection. + */ int sfc_mae_switch_get_ethdev_mport(uint16_t switch_domain_id, uint16_t ethdev_port_id, + unsigned int allowed_mae_switch_port_types, efx_mport_sel_t *mport_sel); int sfc_mae_switch_get_entity_mport(uint16_t switch_domain_id,