From mboxrd@z Thu Jan 1 00:00:00 1970 From: Hemant Agrawal Subject: [PATCH 4/4] net/dpaa2: add support for flow table flush Date: Tue, 26 Mar 2019 12:01:48 +0000 Message-ID: <20190326115952.26278-4-hemant.agrawal@nxp.com> References: <20190326115952.26278-1-hemant.agrawal@nxp.com> Mime-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Cc: "ferruh.yigit@intel.com" , Shreyansh Jain To: "dev@dpdk.org" Return-path: Received: from EUR02-VE1-obe.outbound.protection.outlook.com (mail-eopbgr20059.outbound.protection.outlook.com [40.107.2.59]) by dpdk.org (Postfix) with ESMTP id 438953256 for ; Tue, 26 Mar 2019 13:01:49 +0100 (CET) In-Reply-To: <20190326115952.26278-1-hemant.agrawal@nxp.com> Content-Language: en-US List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Signed-off-by: Hemant Agrawal --- drivers/net/dpaa2/dpaa2_ethdev.c | 2 + drivers/net/dpaa2/dpaa2_ethdev.h | 2 + drivers/net/dpaa2/dpaa2_flow.c | 118 +++++++++++++++++++++---------- 3 files changed, 85 insertions(+), 37 deletions(-) diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_eth= dev.c index c92edecf3..3fbc82977 100644 --- a/drivers/net/dpaa2/dpaa2_ethdev.c +++ b/drivers/net/dpaa2/dpaa2_ethdev.c @@ -971,6 +971,8 @@ dpaa2_dev_close(struct rte_eth_dev *dev) =20 PMD_INIT_FUNC_TRACE(); =20 + dpaa2_flow_clean(dev); + /* Clean the device first */ ret =3D dpni_reset(dpni, CMD_PRI_LOW, priv->token); if (ret) { diff --git a/drivers/net/dpaa2/dpaa2_ethdev.h b/drivers/net/dpaa2/dpaa2_eth= dev.h index 0ef1bf368..33b1506aa 100644 --- a/drivers/net/dpaa2/dpaa2_ethdev.h +++ b/drivers/net/dpaa2/dpaa2_ethdev.h @@ -126,6 +126,7 @@ struct dpaa2_dev_priv { uint64_t qos_extract_param; uint64_t fs_extract_param[MAX_TCS]; } extract; + LIST_HEAD(, rte_flow) flows; /**< Configured flow rule handles. */ }; =20 int dpaa2_distset_to_dpkg_profile_cfg(uint64_t req_dist_set, @@ -172,5 +173,6 @@ uint16_t dpaa2_dev_tx_ordered(void *queue, struct rte_m= buf **bufs, uint16_t nb_pkts); uint16_t dummy_dev_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkt= s); void dpaa2_dev_free_eqresp_buf(uint16_t eqresp_ci); +void dpaa2_flow_clean(struct rte_eth_dev *dev); =20 #endif /* _DPAA2_ETHDEV_H */ diff --git a/drivers/net/dpaa2/dpaa2_flow.c b/drivers/net/dpaa2/dpaa2_flow.= c index 20de3da53..c94c7ef6b 100644 --- a/drivers/net/dpaa2/dpaa2_flow.c +++ b/drivers/net/dpaa2/dpaa2_flow.c @@ -24,6 +24,7 @@ #include =20 struct rte_flow { + LIST_ENTRY(rte_flow) next; /**< Pointer to the next flow structure. */ struct dpni_rule_cfg rule; uint8_t key_size; uint8_t tc_id; @@ -1347,6 +1348,7 @@ dpaa2_generic_flow_set(struct rte_flow *flow, struct dpaa2_dev_priv *priv =3D dev->data->dev_private; struct fsl_mc_io *dpni =3D (struct fsl_mc_io *)priv->hw; size_t param; + struct rte_flow *curr =3D LIST_FIRST(&priv->flows); =20 /* Parse pattern list to get the matching parameters */ while (!end_of_list) { @@ -1625,6 +1627,16 @@ dpaa2_generic_flow_set(struct rte_flow *flow, j++; } =20 + if (!ret) { + /* New rules are inserted. */ + if (!curr) { + LIST_INSERT_HEAD(&priv->flows, flow, next); + } else { + while (LIST_NEXT(curr, next)) + curr =3D LIST_NEXT(curr, next); + LIST_INSERT_AFTER(curr, flow, next); + } + } return ret; } =20 @@ -1764,7 +1776,7 @@ int dpaa2_flow_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *flow_attr, const struct rte_flow_item pattern[], const struct rte_flow_action actions[], - struct rte_flow_error *error __rte_unused) + struct rte_flow_error *error) { struct dpaa2_dev_priv *priv =3D dev->data->dev_private; struct dpni_attr dpni_attr; @@ -1778,6 +1790,9 @@ int dpaa2_flow_validate(struct rte_eth_dev *dev, DPAA2_PMD_ERR( "Failure to get dpni@%p attribute, err code %d\n", dpni, ret); + rte_flow_error_set(error, EPERM, + RTE_FLOW_ERROR_TYPE_ATTR, + flow_attr, "invalid"); return ret; } =20 @@ -1786,6 +1801,9 @@ int dpaa2_flow_validate(struct rte_eth_dev *dev, if (ret < 0) { DPAA2_PMD_ERR( "Invalid attributes are given\n"); + rte_flow_error_set(error, EPERM, + RTE_FLOW_ERROR_TYPE_ATTR, + flow_attr, "invalid"); goto not_valid_params; } /* Verify input pattern list */ @@ -1793,6 +1811,9 @@ int dpaa2_flow_validate(struct rte_eth_dev *dev, if (ret < 0) { DPAA2_PMD_ERR( "Invalid pattern list is given\n"); + rte_flow_error_set(error, EPERM, + RTE_FLOW_ERROR_TYPE_ITEM, + pattern, "invalid"); goto not_valid_params; } /* Verify input action list */ @@ -1800,6 +1821,9 @@ int dpaa2_flow_validate(struct rte_eth_dev *dev, if (ret < 0) { DPAA2_PMD_ERR( "Invalid action list is given\n"); + rte_flow_error_set(error, EPERM, + RTE_FLOW_ERROR_TYPE_ACTION, + actions, "invalid"); goto not_valid_params; } not_valid_params: @@ -1820,20 +1844,20 @@ struct rte_flow *dpaa2_flow_create(struct rte_eth_d= ev *dev, flow =3D rte_malloc(NULL, sizeof(struct rte_flow), RTE_CACHE_LINE_SIZE); if (!flow) { DPAA2_PMD_ERR("Failure to allocate memory for flow"); - return NULL; + goto mem_failure; } /* Allocate DMA'ble memory to write the rules */ key_iova =3D (size_t)rte_malloc(NULL, 256, 64); if (!key_iova) { DPAA2_PMD_ERR( "Memory allocation failure for rule configration\n"); - goto creation_error; + goto mem_failure; } mask_iova =3D (size_t)rte_malloc(NULL, 256, 64); if (!mask_iova) { DPAA2_PMD_ERR( "Memory allocation failure for rule configration\n"); - goto creation_error; + goto mem_failure; } =20 flow->rule.key_iova =3D key_iova; @@ -1845,6 +1869,10 @@ struct rte_flow *dpaa2_flow_create(struct rte_eth_de= v *dev, ret =3D dpaa2_generic_flow_set(flow, dev, attr, pattern, actions, error); if (ret < 0) { + if (error->type > RTE_FLOW_ERROR_TYPE_ACTION) + rte_flow_error_set(error, EPERM, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + attr, "unknown"); DPAA2_PMD_ERR( "Failure to create flow, return code (%d)", ret); goto creation_error; @@ -1857,21 +1885,22 @@ struct rte_flow *dpaa2_flow_create(struct rte_eth_d= ev *dev, } =20 return flow; - +mem_failure: + rte_flow_error_set(error, EPERM, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, "memory alloc"); creation_error: - if (flow) - rte_free((void *)flow); - if (key_iova) - rte_free((void *)key_iova); - if (mask_iova) - rte_free((void *)mask_iova); + rte_free((void *)flow); + rte_free((void *)key_iova); + rte_free((void *)mask_iova); + return NULL; } =20 static int dpaa2_flow_destroy(struct rte_eth_dev *dev, struct rte_flow *flow, - struct rte_flow_error *error __rte_unused) + struct rte_flow_error *error) { int ret =3D 0; struct dpaa2_dev_priv *priv =3D dev->data->dev_private; @@ -1913,44 +1942,40 @@ int dpaa2_flow_destroy(struct rte_eth_dev *dev, break; } =20 + LIST_REMOVE(flow, next); /* Now free the flow */ rte_free(flow); =20 error: + if (ret) + rte_flow_error_set(error, EPERM, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, "unknown"); return ret; } =20 +/** + * Destroy user-configured flow rules. + * + * This function skips internal flows rules. + * + * @see rte_flow_flush() + * @see rte_flow_ops + */ static int dpaa2_flow_flush(struct rte_eth_dev *dev, - struct rte_flow_error *error __rte_unused) + struct rte_flow_error *error) { - int ret =3D 0, tc_id; - struct dpni_rx_tc_dist_cfg tc_cfg; - struct dpni_qos_tbl_cfg qos_cfg; struct dpaa2_dev_priv *priv =3D dev->data->dev_private; - struct fsl_mc_io *dpni =3D (struct fsl_mc_io *)priv->hw; + struct rte_flow *flow =3D LIST_FIRST(&priv->flows); =20 - /* Reset QoS table */ - qos_cfg.default_tc =3D 0; - qos_cfg.discard_on_miss =3D false; - qos_cfg.keep_entries =3D false; - qos_cfg.key_cfg_iova =3D priv->extract.qos_extract_param; - ret =3D dpni_set_qos_table(dpni, CMD_PRI_LOW, priv->token, &qos_cfg); - if (ret < 0) - DPAA2_PMD_ERR( - "QoS table is not reset to default: %d\n", ret); - - for (tc_id =3D 0; tc_id < priv->num_rx_tc; tc_id++) { - /* Reset FS table */ - memset(&tc_cfg, 0, sizeof(struct dpni_rx_tc_dist_cfg)); - ret =3D dpni_set_rx_tc_dist(dpni, CMD_PRI_LOW, priv->token, - tc_id, &tc_cfg); - if (ret < 0) - DPAA2_PMD_ERR( - "Error (%d) in flushing entries for TC (%d)", - ret, tc_id); + while (flow) { + struct rte_flow *next =3D LIST_NEXT(flow, next); + + dpaa2_flow_destroy(dev, flow, error); + flow =3D next; } - return ret; + return 0; } =20 static int @@ -1963,6 +1988,25 @@ dpaa2_flow_query(struct rte_eth_dev *dev __rte_unuse= d, return 0; } =20 +/** + * Clean up all flow rules. + * + * Unlike dpaa2_flow_flush(), this function takes care of all remaining fl= ow + * rules regardless of whether they are internal or user-configured. + * + * @param priv + * Pointer to private structure. + */ +void +dpaa2_flow_clean(struct rte_eth_dev *dev) +{ + struct rte_flow *flow; + struct dpaa2_dev_priv *priv =3D dev->data->dev_private; + + while ((flow =3D LIST_FIRST(&priv->flows))) + dpaa2_flow_destroy(dev, flow, NULL); +} + const struct rte_flow_ops dpaa2_flow_ops =3D { .create =3D dpaa2_flow_create, .validate =3D dpaa2_flow_validate, --=20 2.17.1