From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 749A64302D; Thu, 10 Aug 2023 20:07:04 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 37C164326B; Thu, 10 Aug 2023 20:07:00 +0200 (CEST) Received: from agw.arknetworks.am (agw.arknetworks.am [79.141.165.80]) by mails.dpdk.org (Postfix) with ESMTP id EEC0E406BC for ; Thu, 10 Aug 2023 20:06:57 +0200 (CEST) Received: from localhost.localdomain (unknown [78.109.70.111]) (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 77EBDE1192; Thu, 10 Aug 2023 22:06:57 +0400 (+04) From: Ivan Malov To: dev@dpdk.org Cc: Andrew Rybchenko , Ferruh Yigit , Andy Moreton Subject: [PATCH 2/2] net/sfc: support updating indirect VXLAN encap action Date: Thu, 10 Aug 2023 22:06:56 +0400 Message-Id: <20230810180656.6046-2-ivan.malov@arknetworks.am> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230810180656.6046-1-ivan.malov@arknetworks.am> References: <20230810180656.6046-1-ivan.malov@arknetworks.am> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 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 Such updates are helpful as they let applications avoid costly flow re-insertions when the header data changes. Signed-off-by: Ivan Malov Reviewed-by: Andy Moreton --- drivers/common/sfc_efx/base/efx.h | 9 +++ drivers/common/sfc_efx/base/efx_mae.c | 80 ++++++++++++++++++++++++ drivers/common/sfc_efx/version.map | 1 + drivers/net/sfc/sfc_flow.c | 35 +++++++++++ drivers/net/sfc/sfc_mae.c | 88 +++++++++++++++++++++++++++ drivers/net/sfc/sfc_mae.h | 5 ++ 6 files changed, 218 insertions(+) diff --git a/drivers/common/sfc_efx/base/efx.h b/drivers/common/sfc_efx/base/efx.h index efefea717f..b4d8cfe9d8 100644 --- a/drivers/common/sfc_efx/base/efx.h +++ b/drivers/common/sfc_efx/base/efx.h @@ -4811,6 +4811,15 @@ efx_mae_encap_header_alloc( __in size_t header_size, __out efx_mae_eh_id_t *eh_idp); +LIBEFX_API +extern __checkReturn efx_rc_t +efx_mae_encap_header_update( + __in efx_nic_t *enp, + __in efx_mae_eh_id_t *eh_idp, + __in efx_tunnel_protocol_t encap_type, + __in_bcount(header_size) const uint8_t *header_data, + __in size_t header_size); + LIBEFX_API extern __checkReturn efx_rc_t efx_mae_encap_header_free( diff --git a/drivers/common/sfc_efx/base/efx_mae.c b/drivers/common/sfc_efx/base/efx_mae.c index d36cdc71be..0d7b24d351 100644 --- a/drivers/common/sfc_efx/base/efx_mae.c +++ b/drivers/common/sfc_efx/base/efx_mae.c @@ -2937,6 +2937,86 @@ efx_mae_encap_header_alloc( EFSYS_PROBE(fail6); fail5: EFSYS_PROBE(fail5); +fail4: + EFSYS_PROBE(fail4); +fail3: + EFSYS_PROBE(fail3); +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + return (rc); +} + + __checkReturn efx_rc_t +efx_mae_encap_header_update( + __in efx_nic_t *enp, + __in efx_mae_eh_id_t *eh_idp, + __in efx_tunnel_protocol_t encap_type, + __in_bcount(header_size) const uint8_t *header_data, + __in size_t header_size) +{ + const efx_nic_cfg_t *encp = efx_nic_cfg_get(enp); + efx_mcdi_req_t req; + EFX_MCDI_DECLARE_BUF(payload, + MC_CMD_MAE_ENCAP_HEADER_UPDATE_IN_LENMAX_MCDI2, + MC_CMD_MAE_ENCAP_HEADER_UPDATE_OUT_LEN); + uint32_t encap_type_mcdi; + efx_rc_t rc; + + if (encp->enc_mae_supported == B_FALSE) { + rc = ENOTSUP; + goto fail1; + } + + switch (encap_type) { + case EFX_TUNNEL_PROTOCOL_NONE: + encap_type_mcdi = MAE_MCDI_ENCAP_TYPE_NONE; + break; + case EFX_TUNNEL_PROTOCOL_VXLAN: + encap_type_mcdi = MAE_MCDI_ENCAP_TYPE_VXLAN; + break; + case EFX_TUNNEL_PROTOCOL_GENEVE: + encap_type_mcdi = MAE_MCDI_ENCAP_TYPE_GENEVE; + break; + case EFX_TUNNEL_PROTOCOL_NVGRE: + encap_type_mcdi = MAE_MCDI_ENCAP_TYPE_NVGRE; + break; + default: + rc = ENOTSUP; + goto fail2; + } + + if (header_size > + MC_CMD_MAE_ENCAP_HEADER_UPDATE_IN_HDR_DATA_MAXNUM_MCDI2) { + rc = EINVAL; + goto fail3; + } + + req.emr_cmd = MC_CMD_MAE_ENCAP_HEADER_UPDATE; + req.emr_in_buf = payload; + req.emr_in_length = MC_CMD_MAE_ENCAP_HEADER_UPDATE_IN_LEN(header_size); + req.emr_out_buf = payload; + req.emr_out_length = MC_CMD_MAE_ENCAP_HEADER_UPDATE_OUT_LEN; + + MCDI_IN_SET_DWORD(req, + MAE_ENCAP_HEADER_UPDATE_IN_EH_ID, eh_idp->id); + + MCDI_IN_SET_DWORD(req, + MAE_ENCAP_HEADER_UPDATE_IN_ENCAP_TYPE, encap_type_mcdi); + + memcpy(MCDI_IN2(req, uint8_t, MAE_ENCAP_HEADER_UPDATE_IN_HDR_DATA), + header_data, header_size); + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail4; + } + + return (0); + fail4: EFSYS_PROBE(fail4); fail3: diff --git a/drivers/common/sfc_efx/version.map b/drivers/common/sfc_efx/version.map index 40c97ad2b4..43e8e52ab9 100644 --- a/drivers/common/sfc_efx/version.map +++ b/drivers/common/sfc_efx/version.map @@ -123,6 +123,7 @@ INTERNAL { efx_mae_counters_stream_stop; efx_mae_encap_header_alloc; efx_mae_encap_header_free; + efx_mae_encap_header_update; efx_mae_fini; efx_mae_get_limits; efx_mae_init; diff --git a/drivers/net/sfc/sfc_flow.c b/drivers/net/sfc/sfc_flow.c index a35f20770d..1b50aefe5c 100644 --- a/drivers/net/sfc/sfc_flow.c +++ b/drivers/net/sfc/sfc_flow.c @@ -2864,6 +2864,40 @@ sfc_flow_action_handle_destroy(struct rte_eth_dev *dev, return rc; } +static int +sfc_flow_action_handle_update(struct rte_eth_dev *dev, + struct rte_flow_action_handle *handle, + const void *update, struct rte_flow_error *error) +{ + struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev); + struct rte_flow_action_handle *entry; + int rc = EINVAL; + + sfc_adapter_lock(sa); + + TAILQ_FOREACH(entry, &sa->flow_indir_actions, entries) { + if (entry != handle) + continue; + + if (entry->transfer) { + rc = sfc_mae_indir_action_update(sa, handle, + update, error); + } else { + SFC_ASSERT(B_FALSE); + } + + goto exit; + } + + rc = rte_flow_error_set(error, ENOENT, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, + "indirect action handle not found"); + +exit: + sfc_adapter_unlock(sa); + return rc; +} + static int sfc_flow_action_handle_query(struct rte_eth_dev *dev, const struct rte_flow_action_handle *handle, @@ -2907,6 +2941,7 @@ const struct rte_flow_ops sfc_flow_ops = { .isolate = sfc_flow_isolate, .action_handle_create = sfc_flow_action_handle_create, .action_handle_destroy = sfc_flow_action_handle_destroy, + .action_handle_update = sfc_flow_action_handle_update, .action_handle_query = sfc_flow_action_handle_query, .tunnel_decap_set = sfc_ft_decap_set, .tunnel_match = sfc_ft_match, diff --git a/drivers/net/sfc/sfc_mae.c b/drivers/net/sfc/sfc_mae.c index 45a66307d2..2bfb918275 100644 --- a/drivers/net/sfc/sfc_mae.c +++ b/drivers/net/sfc/sfc_mae.c @@ -749,6 +749,50 @@ sfc_mae_encap_header_del(struct sfc_adapter *sa, sfc_dbg(sa, "deleted encap_header=%p", encap_header); } +static int +sfc_mae_encap_header_update(struct sfc_adapter *sa, + struct sfc_mae_encap_header *encap_header) +{ + const struct sfc_mae_bounce_eh *bounce_eh = &sa->mae.bounce_eh; + struct sfc_mae_fw_rsrc *fw_rsrc; + uint8_t *buf; + int ret; + + if (bounce_eh->type != encap_header->type || + bounce_eh->size == 0) + return EINVAL; + + buf = rte_malloc("sfc_mae_encap_header_buf", bounce_eh->size, 0); + if (buf == NULL) + return ENOMEM; + + rte_memcpy(buf, bounce_eh->buf, bounce_eh->size); + + fw_rsrc = &encap_header->fw_rsrc; + + if (fw_rsrc->refcnt > 0) { + SFC_ASSERT(fw_rsrc->eh_id.id != EFX_MAE_RSRC_ID_INVALID); + + ret = efx_mae_encap_header_update(sa->nic, &fw_rsrc->eh_id, + encap_header->type, buf, + bounce_eh->size); + if (ret != 0) { + sfc_err(sa, "failed to update encap_header=%p: %s", + encap_header, strerror(ret)); + rte_free(buf); + return ret; + } + } + + encap_header->size = bounce_eh->size; + rte_free(encap_header->buf); + encap_header->buf = buf; + + sfc_dbg(sa, "updated encap_header=%p", encap_header); + + return 0; +} + static int sfc_mae_encap_header_enable(struct sfc_adapter *sa, struct sfc_mae_encap_header *encap_header, @@ -5288,6 +5332,50 @@ sfc_mae_indir_action_destroy(struct sfc_adapter *sa, NULL, "indirect action is still in use"); } +int +sfc_mae_indir_action_update(struct sfc_adapter *sa, + struct rte_flow_action_handle *handle, + const void *update, struct rte_flow_error *error) +{ + const struct rte_flow_action *action = update; + struct sfc_mae *mae = &sa->mae; + bool custom_error = false; + int ret; + + SFC_ASSERT(sfc_adapter_is_locked(sa)); + SFC_ASSERT(action != NULL); + SFC_ASSERT(handle != NULL); + + switch (handle->type) { + case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP: + /* Cleanup after previous encap. header bounce buffer usage. */ + sfc_mae_bounce_eh_invalidate(&mae->bounce_eh); + + ret = sfc_mae_rule_parse_action_vxlan_encap(mae, action->conf, + NULL, error); + if (ret != 0) { + custom_error = true; + break; + } + + ret = sfc_mae_encap_header_update(sa, handle->encap_header); + break; + default: + ret = ENOTSUP; + } + + if (custom_error) + return ret; + + if (ret != 0) { + return rte_flow_error_set(error, ret, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, + "failed to parse indirect action to mae object"); + } + + return 0; +} + int sfc_mae_indir_action_query(struct sfc_adapter *sa, const struct rte_flow_action_handle *handle, diff --git a/drivers/net/sfc/sfc_mae.h b/drivers/net/sfc/sfc_mae.h index 4b928f876b..7f4c3324bd 100644 --- a/drivers/net/sfc/sfc_mae.h +++ b/drivers/net/sfc/sfc_mae.h @@ -422,6 +422,11 @@ int sfc_mae_indir_action_destroy(struct sfc_adapter *sa, const struct rte_flow_action_handle *handle, struct rte_flow_error *error); +int sfc_mae_indir_action_update(struct sfc_adapter *sa, + struct rte_flow_action_handle *handle, + const void *update, + struct rte_flow_error *error); + int sfc_mae_indir_action_query(struct sfc_adapter *sa, const struct rte_flow_action_handle *handle, void *data, struct rte_flow_error *error); -- 2.31.1