From patchwork Tue Apr 13 00:14:27 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Li Zhang X-Patchwork-Id: 91142 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 BA13CA0524; Tue, 13 Apr 2021 02:14:47 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 4BA0E160923; Tue, 13 Apr 2021 02:14:40 +0200 (CEST) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by mails.dpdk.org (Postfix) with ESMTP id 08A2C160915 for ; Tue, 13 Apr 2021 02:14:36 +0200 (CEST) Received: from Internal Mail-Server by MTLPINE1 (envelope-from lizh@nvidia.com) with SMTP; 13 Apr 2021 03:14:32 +0300 Received: from nvidia.com (c-235-17-1-009.mtl.labs.mlnx [10.235.17.9]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 13D0EVH8024378; Tue, 13 Apr 2021 03:14:32 +0300 From: Li Zhang To: dekelp@nvidia.com, orika@nvidia.com, viacheslavo@nvidia.com, matan@nvidia.com, shahafs@nvidia.com, cristian.dumitrescu@intel.com, lironh@marvell.com, Wisam Jaddo , Xiaoyun Li , Jasvinder Singh , Thomas Monjalon , Ferruh Yigit , Andrew Rybchenko , Ray Kinsella , Neil Horman Cc: dev@dpdk.org, rasland@nvidia.com, roniba@nvidia.com, Haifei Luo , Jiawei Wang Date: Tue, 13 Apr 2021 03:14:27 +0300 Message-Id: <20210413001428.1999959-2-lizh@nvidia.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20210413001428.1999959-1-lizh@nvidia.com> References: <20210318085815.804896-1-lizh@nvidia.com> <20210413001428.1999959-1-lizh@nvidia.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH v3 1/2] ethdev: add pre-defined meter policy API 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 Sender: "dev" Currently, the flow meter policy does not support multiple actions per color; also the allowed action types per color are very limited. In addition, the policy cannot be pre-defined. Due to the growing in flow actions offload abilities there is a potential for the user to use variety of actions per color differently. This new meter policy API comes to allow this potential in the most ethdev common way using rte_flow action definition. A list of rte_flow actions will be provided by the user per color in order to create a meter policy. In addition, the API forces to pre-define the policy before the meters creation in order to allow sharing of single policy with multiple meters efficiently. meter_policy_id is added into struct rte_mtr_params. So that it can get the policy during the meters creation. Allow coloring the packet using a new rte_flow_action_color as could be done by the old policy API. The next API function were added: - rte_mtr_meter_policy_create - rte_mtr_meter_policy_delete - rte_mtr_meter_policy_update - rte_mtr_meter_policy_validate The next struct was changed: - rte_mtr_params - rte_mtr_capabilities The next API was deleted: - rte_mtr_policer_actions_update To support this API the following app were changed: app/test-flow-perf: clean meter policer app/testpmd: clean meter policer To support this API the following drivers were changed: net/softnic: support meter policy API 1. cleans meter rte_mtr_policer_action. 2. Support policy API to get color action as policer action did. The color action will be mapped into rte_table_action_policer. net/mlx5: clean meter creation management Cleans and breaks part of the current meter management in order to allow better design with policy API. Signed-off-by: Li Zhang Signed-off-by: Haifei Luo Signed-off-by: Jiawei Wang Acked-by: Matan Azrad Acked-by: Ray Kinsella --- app/test-flow-perf/main.c | 7 - app/test-pmd/cmdline.c | 1 - app/test-pmd/cmdline_mtr.c | 172 ------- app/test-pmd/cmdline_mtr.h | 1 - doc/guides/prog_guide/rte_flow.rst | 21 + .../traffic_metering_and_policing.rst | 16 +- doc/guides/rel_notes/release_21_05.rst | 22 +- doc/guides/testpmd_app_ug/testpmd_funcs.rst | 18 - drivers/net/mlx5/mlx5.h | 24 +- drivers/net/mlx5/mlx5_flow.c | 46 -- drivers/net/mlx5/mlx5_flow.h | 18 +- drivers/net/mlx5/mlx5_flow_aso.c | 8 +- drivers/net/mlx5/mlx5_flow_dv.c | 461 +----------------- drivers/net/mlx5/mlx5_flow_meter.c | 369 +------------- drivers/net/softnic/rte_eth_softnic_flow.c | 19 +- .../net/softnic/rte_eth_softnic_internals.h | 18 +- drivers/net/softnic/rte_eth_softnic_meter.c | 264 +++++++--- lib/librte_ethdev/rte_flow.h | 22 + lib/librte_ethdev/rte_mtr.c | 55 ++- lib/librte_ethdev/rte_mtr.h | 215 ++++++-- lib/librte_ethdev/rte_mtr_driver.h | 44 +- lib/librte_ethdev/version.map | 5 +- 22 files changed, 568 insertions(+), 1258 deletions(-) diff --git a/app/test-flow-perf/main.c b/app/test-flow-perf/main.c index 0aef767350..c1f38cbec5 100644 --- a/app/test-flow-perf/main.c +++ b/app/test-flow-perf/main.c @@ -921,13 +921,6 @@ create_meter_rule(int port_id, uint32_t counter) /*create meter*/ params.meter_profile_id = default_prof_id; - params.action[RTE_COLOR_GREEN] = - MTR_POLICER_ACTION_COLOR_GREEN; - params.action[RTE_COLOR_YELLOW] = - MTR_POLICER_ACTION_COLOR_YELLOW; - params.action[RTE_COLOR_RED] = - MTR_POLICER_ACTION_DROP; - ret = rte_mtr_create(port_id, counter, ¶ms, 1, &error); if (ret != 0) { printf("Port %u create meter idx(%d) error(%d) message: %s\n", diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index f44116b087..fae79d4c85 100644 --- a/app/test-pmd/cmdline.c +++ b/app/test-pmd/cmdline.c @@ -17071,7 +17071,6 @@ cmdline_parse_ctx_t main_ctx[] = { (cmdline_parse_inst_t *)&cmd_del_port_meter, (cmdline_parse_inst_t *)&cmd_set_port_meter_profile, (cmdline_parse_inst_t *)&cmd_set_port_meter_dscp_table, - (cmdline_parse_inst_t *)&cmd_set_port_meter_policer_action, (cmdline_parse_inst_t *)&cmd_set_port_meter_stats_mask, (cmdline_parse_inst_t *)&cmd_show_port_meter_stats, (cmdline_parse_inst_t *)&cmd_mcast_addr, diff --git a/app/test-pmd/cmdline_mtr.c b/app/test-pmd/cmdline_mtr.c index 3982787d20..44394e3ea1 100644 --- a/app/test-pmd/cmdline_mtr.c +++ b/app/test-pmd/cmdline_mtr.c @@ -146,53 +146,6 @@ parse_meter_color_str(char *c_str, uint32_t *use_prev_meter_color, return 0; } -static int -string_to_policer_action(char *s) -{ - if ((strcmp(s, "G") == 0) || (strcmp(s, "g") == 0)) - return MTR_POLICER_ACTION_COLOR_GREEN; - - if ((strcmp(s, "Y") == 0) || (strcmp(s, "y") == 0)) - return MTR_POLICER_ACTION_COLOR_YELLOW; - - if ((strcmp(s, "R") == 0) || (strcmp(s, "r") == 0)) - return MTR_POLICER_ACTION_COLOR_RED; - - if ((strcmp(s, "D") == 0) || (strcmp(s, "d") == 0)) - return MTR_POLICER_ACTION_DROP; - - return -1; -} - -static int -parse_policer_action_string(char *p_str, uint32_t action_mask, - enum rte_mtr_policer_action actions[]) -{ - char *token; - int count = __builtin_popcount(action_mask); - int g_color = 0, y_color = 0, action, i; - - for (i = 0; i < count; i++) { - token = strtok_r(p_str, PARSE_DELIMITER, &p_str); - if (token == NULL) - return -1; - - action = string_to_policer_action(token); - if (action == -1) - return -1; - - if (g_color == 0 && (action_mask & 0x1)) { - actions[RTE_COLOR_GREEN] = action; - g_color = 1; - } else if (y_color == 0 && (action_mask & 0x2)) { - actions[RTE_COLOR_YELLOW] = action; - y_color = 1; - } else - actions[RTE_COLOR_RED] = action; - } - return 0; -} - static int parse_multi_token_string(char *t_str, uint16_t *port_id, uint32_t *mtr_id, enum rte_color **dscp_table) @@ -302,10 +255,6 @@ static void cmd_show_port_meter_cap_parsed(void *parsed_result, cap.color_aware_trtcm_rfc2698_supported); printf("cap.color_aware_trtcm_rfc4115_supported %" PRId32 "\n", cap.color_aware_trtcm_rfc4115_supported); - printf("cap.policer_action_recolor_supported %" PRId32 "\n", - cap.policer_action_recolor_supported); - printf("cap.policer_action_drop_supported %" PRId32 "\n", - cap.policer_action_drop_supported); printf("cap.stats_mask %" PRIx64 "\n", cap.stats_mask); } @@ -808,12 +757,6 @@ static void cmd_create_port_meter_parsed(void *parsed_result, else params.meter_enable = 0; - params.action[RTE_COLOR_GREEN] = - string_to_policer_action(res->g_action); - params.action[RTE_COLOR_YELLOW] = - string_to_policer_action(res->y_action); - params.action[RTE_COLOR_RED] = - string_to_policer_action(res->r_action); params.stats_mask = res->statistics_mask; ret = rte_mtr_create(port_id, mtr_id, ¶ms, shared, &error); @@ -1181,121 +1124,6 @@ cmdline_parse_inst_t cmd_set_port_meter_dscp_table = { }, }; -/* *** Set Port Meter Policer Action *** */ -struct cmd_set_port_meter_policer_action_result { - cmdline_fixed_string_t set; - cmdline_fixed_string_t port; - cmdline_fixed_string_t meter; - cmdline_fixed_string_t policer; - cmdline_fixed_string_t action; - uint16_t port_id; - uint32_t mtr_id; - uint32_t action_mask; - cmdline_multi_string_t policer_action; -}; - -cmdline_parse_token_string_t cmd_set_port_meter_policer_action_set = - TOKEN_STRING_INITIALIZER( - struct cmd_set_port_meter_policer_action_result, set, "set"); -cmdline_parse_token_string_t cmd_set_port_meter_policer_action_port = - TOKEN_STRING_INITIALIZER( - struct cmd_set_port_meter_policer_action_result, port, "port"); -cmdline_parse_token_string_t cmd_set_port_meter_policer_action_meter = - TOKEN_STRING_INITIALIZER( - struct cmd_set_port_meter_policer_action_result, meter, - "meter"); -cmdline_parse_token_string_t cmd_set_port_meter_policer_action_policer = - TOKEN_STRING_INITIALIZER( - struct cmd_set_port_meter_policer_action_result, policer, - "policer"); -cmdline_parse_token_string_t cmd_set_port_meter_policer_action_action = - TOKEN_STRING_INITIALIZER( - struct cmd_set_port_meter_policer_action_result, action, - "action"); -cmdline_parse_token_num_t cmd_set_port_meter_policer_action_port_id = - TOKEN_NUM_INITIALIZER( - struct cmd_set_port_meter_policer_action_result, port_id, - RTE_UINT16); -cmdline_parse_token_num_t cmd_set_port_meter_policer_action_mtr_id = - TOKEN_NUM_INITIALIZER( - struct cmd_set_port_meter_policer_action_result, mtr_id, - RTE_UINT32); -cmdline_parse_token_num_t cmd_set_port_meter_policer_action_action_mask = - TOKEN_NUM_INITIALIZER( - struct cmd_set_port_meter_policer_action_result, action_mask, - RTE_UINT32); -cmdline_parse_token_string_t cmd_set_port_meter_policer_action_policer_action = - TOKEN_STRING_INITIALIZER( - struct cmd_set_port_meter_policer_action_result, - policer_action, TOKEN_STRING_MULTI); - -static void cmd_set_port_meter_policer_action_parsed(void *parsed_result, - __rte_unused struct cmdline *cl, - __rte_unused void *data) -{ - struct cmd_set_port_meter_policer_action_result *res = parsed_result; - enum rte_mtr_policer_action *actions; - struct rte_mtr_error error; - uint32_t mtr_id = res->mtr_id; - uint32_t action_mask = res->action_mask; - uint16_t port_id = res->port_id; - char *p_str = res->policer_action; - int ret; - - if (port_id_is_invalid(port_id, ENABLED_WARN)) - return; - - /* Check: action mask */ - if (action_mask == 0 || (action_mask & (~0x7UL))) { - printf(" Policer action mask not correct (error)\n"); - return; - } - - /* Allocate memory for policer actions */ - actions = (enum rte_mtr_policer_action *)malloc(RTE_COLORS * - sizeof(enum rte_mtr_policer_action)); - if (actions == NULL) { - printf("Memory for policer actions not allocated (error)\n"); - return; - } - /* Parse policer action string */ - ret = parse_policer_action_string(p_str, action_mask, actions); - if (ret) { - printf(" Policer action string parse error\n"); - free(actions); - return; - } - - ret = rte_mtr_policer_actions_update(port_id, mtr_id, - action_mask, actions, &error); - if (ret != 0) { - free(actions); - print_err_msg(&error); - return; - } - - free(actions); -} - -cmdline_parse_inst_t cmd_set_port_meter_policer_action = { - .f = cmd_set_port_meter_policer_action_parsed, - .data = NULL, - .help_str = "set port meter policer action " - " [ ]", - .tokens = { - (void *)&cmd_set_port_meter_policer_action_set, - (void *)&cmd_set_port_meter_policer_action_port, - (void *)&cmd_set_port_meter_policer_action_meter, - (void *)&cmd_set_port_meter_policer_action_policer, - (void *)&cmd_set_port_meter_policer_action_action, - (void *)&cmd_set_port_meter_policer_action_port_id, - (void *)&cmd_set_port_meter_policer_action_mtr_id, - (void *)&cmd_set_port_meter_policer_action_action_mask, - (void *)&cmd_set_port_meter_policer_action_policer_action, - NULL, - }, -}; - /* *** Set Port Meter Stats Mask *** */ struct cmd_set_port_meter_stats_mask_result { cmdline_fixed_string_t set; diff --git a/app/test-pmd/cmdline_mtr.h b/app/test-pmd/cmdline_mtr.h index e69d6da023..7e2713cea3 100644 --- a/app/test-pmd/cmdline_mtr.h +++ b/app/test-pmd/cmdline_mtr.h @@ -17,7 +17,6 @@ extern cmdline_parse_inst_t cmd_disable_port_meter; extern cmdline_parse_inst_t cmd_del_port_meter; extern cmdline_parse_inst_t cmd_set_port_meter_profile; extern cmdline_parse_inst_t cmd_set_port_meter_dscp_table; -extern cmdline_parse_inst_t cmd_set_port_meter_policer_action; extern cmdline_parse_inst_t cmd_set_port_meter_stats_mask; extern cmdline_parse_inst_t cmd_show_port_meter_stats; diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst index e1b93ecedf..2f5a6e0c31 100644 --- a/doc/guides/prog_guide/rte_flow.rst +++ b/doc/guides/prog_guide/rte_flow.rst @@ -2841,6 +2841,27 @@ for ``RTE_FLOW_FIELD_VALUE`` and ``RTE_FLOW_FIELD_POINTER`` respectively. | ``value`` | immediate value or a pointer to this value | +---------------+----------------------------------------------------------+ +Action: ``METER_COLOR`` +^^^^^^^^^^^^^^^^^^^^^^^ + +Color the packet to reflect the meter color result. + +The meter action must be configured before meter color action. +Meter color action is set to a color to reflect the meter color result. +Set the meter color in the mbuf to the selected color. +The meter color action output color is the output color of the packet, +which is set in the packet meta-data (i.e. struct ``rte_mbuf::sched::color``) + +.. _table_rte_flow_action_meter_color: + +.. table:: METER_COLOR + + +-----------------+--------------+ + | Field | Value | + +=================+==============+ + | ``meter_color`` | Packet color | + +-----------------+--------------+ + Negative types ~~~~~~~~~~~~~~ diff --git a/doc/guides/prog_guide/traffic_metering_and_policing.rst b/doc/guides/prog_guide/traffic_metering_and_policing.rst index 90c781eb1d..c0537e653c 100644 --- a/doc/guides/prog_guide/traffic_metering_and_policing.rst +++ b/doc/guides/prog_guide/traffic_metering_and_policing.rst @@ -56,18 +56,10 @@ The processing done for each input packet hitting an MTR object is: color blind mode, which is equivalent to considering all input packets initially colored as green. -* Policing: There is a separate policer action configured for each meter - output color, which can: - - * Drop the packet. - - * Keep the same packet color: the policer output color matches the meter - output color (essentially a no-op action). - - * Recolor the packet: the policer output color is set to a different color - than the meter output color. The policer output color is the output color - of the packet, which is set in the packet meta-data (i.e. struct - ``rte_mbuf::sched::color``). +* There is a meter policy API to manage pre-defined policies for meter. + Any rte_flow action list can be configured per color for each policy. + A meter object configured with a policy executes the actions per packet + according to the packet color. * Statistics: The set of counters maintained for each MTR object is configurable and subject to the implementation support. This set includes diff --git a/doc/guides/rel_notes/release_21_05.rst b/doc/guides/rel_notes/release_21_05.rst index 113b37cddc..1b1b4368f6 100644 --- a/doc/guides/rel_notes/release_21_05.rst +++ b/doc/guides/rel_notes/release_21_05.rst @@ -161,7 +161,27 @@ New Features ``dpdk-testpmd -- --eth-link-speed N`` * Added command to display Rx queue used descriptor count. ``show port (port_id) rxq (queue_id) desc used count`` - + * deleted the port meter policer action command . + ``set port meter policer action (port_id) (mtr_id) (action_mask) ...`` + * Added command to create meter policy. + ``add port meter policy (port_id) (policy_id) g_actions {action} end y_actions {action} end r_actions {action} end`` + * Added command to delete meter policy. + ``del port meter policy (port_id) (policy_id)`` + +* **Updated meter API.** + + * ethdev: Deleted meter policer API to support policy API. + ``rte_mtr_policer_actions_update()`` + * ethdev: Added meter API to support pre-defined policy, rte_flow action list per color. + ``rte_mtr_meter_policy_create()``, ``rte_mtr_meter_policy_delete()`` and + ``rte_mtr_create_with_policy()`` + * ethdev: Removed rte_mtr_policer_action from rte_mtr_params structures. + * ethdev: Added rte_mtr_meter_policy_params structures to support policy API. + * ethdev: Added meter_policy_id into rte_mtr_params structures. + * ethdev: Removed policer_action_recolor_supported and policer_action_drop_supported from rte_mtr_capabilities structures. + * ethdev: Added meter_policy_n_max into rte_mtr_capabilities structures. + * ethdev: Added RTE_FLOW_ACTION_TYPE_METER_COLOR in enum rte_flow_action_type. + * ethdev: Added RTE_MTR_ERROR_TYPE_METER_POLICY_ID and RTE_MTR_ERROR_TYPE_METER_POLICY_ID into rte_mtr_error_type. Removed Items ------------- diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst index 36f0a328a5..3f7a1c0e33 100644 --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst @@ -2830,24 +2830,6 @@ Set meter dscp table for the ethernet device:: testpmd> set port meter dscp table (port_id) (mtr_id) [(dscp_tbl_entry0) \ (dscp_tbl_entry1)...(dscp_tbl_entry63)] -set port meter policer action -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Set meter policer action for the ethernet device:: - - testpmd> set port meter policer action (port_id) (mtr_id) (action_mask) \ - (action0) [(action1) (action1)] - -where: - -* ``action_mask``: Bit mask indicating which policer actions need to be - updated. One or more policer actions can be updated in a single function - invocation. To update the policer action associated with color C, bit - (1 << C) needs to be set in *action_mask* and element at position C - in the *actions* array needs to be valid. -* ``actionx``: Policer action for the color x, - RTE_MTR_GREEN <= x < RTE_MTR_COLORS - set port meter stats mask ~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index 9a02aa4488..a8e11023cc 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -584,14 +584,6 @@ struct mlx5_dev_shared_port { /* Modify this value if enum rte_mtr_color changes. */ #define RTE_MTR_DROPPED RTE_COLORS -/* Meter policer statistics */ -struct mlx5_flow_policer_stats { - uint32_t pass_cnt; - /**< Color counter for pass. */ - uint32_t drop_cnt; - /**< Color counter for drop. */ -}; - /* Meter table structure. */ struct mlx5_meter_domain_info { struct mlx5_flow_tbl_resource *tbl; @@ -630,24 +622,12 @@ struct mlx5_meter_domains_infos { /* Meter parameter structure. */ struct mlx5_flow_meter_info { - uint32_t meter_id; - /**< Meter id. */ struct mlx5_flow_meter_profile *profile; /**< Meter profile parameters. */ rte_spinlock_t sl; /**< Meter action spinlock. */ - /** Policer actions (per meter output color). */ - enum rte_mtr_policer_action action[RTE_COLORS]; /** Set of stats counters to be enabled. * @see enum rte_mtr_stats_type */ - uint32_t green_bytes:1; - /** Set green bytes stats to be enabled. */ - uint32_t green_pkts:1; - /** Set green packets stats to be enabled. */ - uint32_t red_bytes:1; - /** Set red bytes stats to be enabled. */ - uint32_t red_pkts:1; - /** Set red packets stats to be enabled. */ uint32_t bytes_dropped:1; /** Set bytes dropped stats to be enabled. */ uint32_t pkts_dropped:1; @@ -682,8 +662,8 @@ struct mlx5_flow_meter_info { uint32_t transfer:1; struct mlx5_meter_domains_infos *mfts; /**< Flow table created for this meter. */ - struct mlx5_flow_policer_stats policer_stats; - /**< Meter policer statistics. */ + uint32_t drop_cnt; + /**< Color counter for drop. */ uint32_t ref_cnt; /**< Use count. */ struct mlx5_indexed_pool *flow_ipool; diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c index 242c6f2288..ee2c351649 100644 --- a/drivers/net/mlx5/mlx5_flow.c +++ b/drivers/net/mlx5/mlx5_flow.c @@ -6647,52 +6647,6 @@ mlx5_flow_destroy_mtr_tbls(struct rte_eth_dev *dev, return fops->destroy_mtr_tbls(dev, tbls); } -/** - * Prepare policer rules. - * - * @param[in] dev - * Pointer to Ethernet device. - * @param[in] fm - * Pointer to flow meter structure. - * @param[in] attr - * Pointer to flow attributes. - * - * @return - * 0 on success, -1 otherwise. - */ -int -mlx5_flow_prepare_policer_rules(struct rte_eth_dev *dev, - struct mlx5_flow_meter_info *fm, - const struct rte_flow_attr *attr) -{ - const struct mlx5_flow_driver_ops *fops; - - fops = flow_get_drv_ops(MLX5_FLOW_TYPE_DV); - return fops->prepare_policer_rules(dev, fm, attr); -} - -/** - * Destroy policer rules. - * - * @param[in] fm - * Pointer to flow meter structure. - * @param[in] attr - * Pointer to flow attributes. - * - * @return - * 0 on success, -1 otherwise. - */ -int -mlx5_flow_destroy_policer_rules(struct rte_eth_dev *dev, - struct mlx5_flow_meter_info *fm, - const struct rte_flow_attr *attr) -{ - const struct mlx5_flow_driver_ops *fops; - - fops = flow_get_drv_ops(MLX5_FLOW_TYPE_DV); - return fops->destroy_policer_rules(dev, fm, attr); -} - /** * Allocate the needed aso flow meter id. * diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h index cb2803d080..7fa15eef7b 100644 --- a/drivers/net/mlx5/mlx5_flow.h +++ b/drivers/net/mlx5/mlx5_flow.h @@ -839,6 +839,8 @@ struct mlx5_legacy_flow_meter { /* Must be the first in struct. */ TAILQ_ENTRY(mlx5_legacy_flow_meter) next; /**< Pointer to the next flow meter structure. */ + uint32_t meter_id; + /**< Meter id. */ uint32_t idx; /* Index to meter object. */ }; @@ -1097,14 +1099,6 @@ typedef struct mlx5_meter_domains_infos *(*mlx5_flow_create_mtr_tbls_t) (struct rte_eth_dev *dev); typedef int (*mlx5_flow_destroy_mtr_tbls_t)(struct rte_eth_dev *dev, struct mlx5_meter_domains_infos *tbls); -typedef int (*mlx5_flow_create_policer_rules_t) - (struct rte_eth_dev *dev, - struct mlx5_flow_meter_info *fm, - const struct rte_flow_attr *attr); -typedef int (*mlx5_flow_destroy_policer_rules_t) - (struct rte_eth_dev *dev, - const struct mlx5_flow_meter_info *fm, - const struct rte_flow_attr *attr); typedef uint32_t (*mlx5_flow_mtr_alloc_t) (struct rte_eth_dev *dev); typedef void (*mlx5_flow_mtr_free_t)(struct rte_eth_dev *dev, @@ -1161,8 +1155,6 @@ struct mlx5_flow_driver_ops { mlx5_flow_query_t query; mlx5_flow_create_mtr_tbls_t create_mtr_tbls; mlx5_flow_destroy_mtr_tbls_t destroy_mtr_tbls; - mlx5_flow_create_policer_rules_t prepare_policer_rules; - mlx5_flow_destroy_policer_rules_t destroy_policer_rules; mlx5_flow_mtr_alloc_t create_meter; mlx5_flow_mtr_free_t free_meter; mlx5_flow_counter_alloc_t counter_alloc; @@ -1392,12 +1384,6 @@ struct mlx5_meter_domains_infos *mlx5_flow_create_mtr_tbls (struct rte_eth_dev *dev); int mlx5_flow_destroy_mtr_tbls(struct rte_eth_dev *dev, struct mlx5_meter_domains_infos *tbl); -int mlx5_flow_prepare_policer_rules(struct rte_eth_dev *dev, - struct mlx5_flow_meter_info *fm, - const struct rte_flow_attr *attr); -int mlx5_flow_destroy_policer_rules(struct rte_eth_dev *dev, - struct mlx5_flow_meter_info *fm, - const struct rte_flow_attr *attr); int mlx5_flow_meter_flush(struct rte_eth_dev *dev, struct rte_mtr_error *error); int mlx5_flow_dv_discover_counter_offset_support(struct rte_eth_dev *dev); diff --git a/drivers/net/mlx5/mlx5_flow_aso.c b/drivers/net/mlx5/mlx5_flow_aso.c index cd2cc016b9..62d2df054b 100644 --- a/drivers/net/mlx5/mlx5_flow_aso.c +++ b/drivers/net/mlx5/mlx5_flow_aso.c @@ -808,8 +808,8 @@ mlx5_aso_meter_update_by_wqe(struct mlx5_dev_ctx_shared *sh, /* Waiting for wqe resource. */ rte_delay_us_sleep(MLX5_ASO_WQE_CQE_RESPONSE_DELAY); } while (--poll_wqe_times); - DRV_LOG(ERR, "Fail to send WQE for ASO meter %d", - mtr->fm.meter_id); + DRV_LOG(ERR, "Fail to send WQE for ASO meter offset %d", + mtr->offset); return -1; } @@ -844,7 +844,7 @@ mlx5_aso_mtr_wait(struct mlx5_dev_ctx_shared *sh, /* Waiting for CQE ready. */ rte_delay_us_sleep(MLX5_ASO_WQE_CQE_RESPONSE_DELAY); } while (--poll_cqe_times); - DRV_LOG(ERR, "Fail to poll CQE ready for ASO meter %d", - mtr->fm.meter_id); + DRV_LOG(ERR, "Fail to poll CQE ready for ASO meter offset %d", + mtr->offset); return -1; } diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index d8ea440668..af3397fb55 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -184,31 +184,6 @@ flow_dv_attr_init(const struct rte_flow_item *item, union flow_dv_attr *attr, attr->valid = 1; } -/** - * Convert rte_mtr_color to mlx5 color. - * - * @param[in] rcol - * rte_mtr_color. - * - * @return - * mlx5 color. - */ -static int -rte_col_2_mlx5_col(enum rte_color rcol) -{ - switch (rcol) { - case RTE_COLOR_GREEN: - return MLX5_FLOW_COLOR_GREEN; - case RTE_COLOR_YELLOW: - return MLX5_FLOW_COLOR_YELLOW; - case RTE_COLOR_RED: - return MLX5_FLOW_COLOR_RED; - default: - break; - } - return MLX5_FLOW_COLOR_UNDEFINED; -} - struct field_modify_info { uint32_t size; /* Size of field in protocol header, in bytes. */ uint32_t offset; /* Offset of field in protocol header, in bytes. */ @@ -6025,12 +6000,10 @@ flow_dv_mtr_pool_create(struct rte_eth_dev *dev, mtrmng->n_valid++; for (i = 1; i < MLX5_ASO_MTRS_PER_POOL; ++i) { pool->mtrs[i].offset = i; - pool->mtrs[i].fm.meter_id = UINT32_MAX; LIST_INSERT_HEAD(&mtrmng->meters, &pool->mtrs[i], next); } pool->mtrs[0].offset = 0; - pool->mtrs[0].fm.meter_id = UINT32_MAX; *mtr_free = &pool->mtrs[0]; return pool; } @@ -6054,7 +6027,6 @@ flow_dv_aso_mtr_release_to_pool(struct rte_eth_dev *dev, uint32_t mtr_idx) rte_spinlock_lock(&mtrmng->mtrsl); memset(&aso_mtr->fm, 0, sizeof(struct mlx5_flow_meter_info)); aso_mtr->state = ASO_METER_FREE; - aso_mtr->fm.meter_id = UINT32_MAX; LIST_INSERT_HEAD(&mtrmng->meters, aso_mtr, next); rte_spinlock_unlock(&mtrmng->mtrsl); } @@ -6094,8 +6066,8 @@ flow_dv_mtr_alloc(struct rte_eth_dev *dev) mtr_free->state = ASO_METER_WAIT; rte_spinlock_unlock(&mtrmng->mtrsl); pool = container_of(mtr_free, - struct mlx5_aso_mtr_pool, - mtrs[mtr_free->offset]); + struct mlx5_aso_mtr_pool, + mtrs[mtr_free->offset]); mtr_idx = MLX5_MAKE_MTR_IDX(pool->index, mtr_free->offset); if (!mtr_free->fm.meter_action) { #ifdef HAVE_MLX5_DR_CREATE_ACTION_ASO @@ -13702,433 +13674,6 @@ flow_dv_create_mtr_tbl(struct rte_eth_dev *dev) return NULL; } -/** - * Destroy the meter table matchers. - * Lock free, (mutex should be acquired by caller). - * - * @param[in] dev - * Pointer to Ethernet device. - * @param[in,out] dtb - * Pointer to DV meter table. - * - * @return - * Always 0. - */ -static int -flow_dv_destroy_mtr_matchers(struct rte_eth_dev *dev, - struct mlx5_meter_domain_info *dtb) -{ - struct mlx5_priv *priv = dev->data->dev_private; - struct mlx5_flow_tbl_data_entry *tbl; - - if (!priv->config.dv_flow_en) - return 0; - if (dtb->drop_matcher) { - tbl = container_of(dtb->drop_matcher->tbl, typeof(*tbl), tbl); - mlx5_cache_unregister(&tbl->matchers, - &dtb->drop_matcher->entry); - dtb->drop_matcher = NULL; - } - if (dtb->color_matcher) { - tbl = container_of(dtb->color_matcher->tbl, typeof(*tbl), tbl); - mlx5_cache_unregister(&tbl->matchers, - &dtb->color_matcher->entry); - dtb->color_matcher = NULL; - } - return 0; -} - -/** - * Create the matchers for meter table. - * - * @param[in] dev - * Pointer to Ethernet device. - * @param[in] color_reg_c_idx - * Reg C index for color match. - * @param[in] mtr_id_reg_c_idx - * Reg C index for meter_id match. - * @param[in] mtr_id_mask - * Mask for meter_id match criteria. - * @param[in,out] dtb - * Pointer to DV meter table. - * @param[out] error - * Perform verbose error reporting if not NULL. - * - * @return - * 0 on success, a negative errno value otherwise and rte_errno is set. - */ -static int -flow_dv_prepare_mtr_matchers(struct rte_eth_dev *dev, - uint32_t color_reg_c_idx, - uint32_t mtr_id_reg_c_idx, - uint32_t mtr_id_mask, - struct mlx5_meter_domain_info *dtb, - struct rte_flow_error *error) -{ - struct mlx5_priv *priv = dev->data->dev_private; - struct mlx5_flow_tbl_data_entry *tbl_data; - struct mlx5_cache_entry *entry; - struct mlx5_flow_dv_matcher matcher = { - .mask = { - .size = sizeof(matcher.mask.buf) - - MLX5_ST_SZ_BYTES(fte_match_set_misc4), - }, - .tbl = dtb->tbl, - }; - struct mlx5_flow_dv_match_params value = { - .size = sizeof(value.buf) - - MLX5_ST_SZ_BYTES(fte_match_set_misc4), - }; - struct mlx5_flow_cb_ctx ctx = { - .error = error, - .data = &matcher, - }; - uint32_t color_mask = (UINT32_C(1) << MLX5_MTR_COLOR_BITS) - 1; - - tbl_data = container_of(dtb->tbl, struct mlx5_flow_tbl_data_entry, tbl); - if (!dtb->drop_matcher) { - /* Create matchers for Drop. */ - flow_dv_match_meta_reg(matcher.mask.buf, value.buf, - mtr_id_reg_c_idx, 0, mtr_id_mask); - matcher.priority = MLX5_REG_BITS * 2 - priv->max_mtr_bits; - matcher.crc = rte_raw_cksum((const void *)matcher.mask.buf, - matcher.mask.size); - entry = mlx5_cache_register(&tbl_data->matchers, &ctx); - if (!entry) { - DRV_LOG(ERR, "Failed to register meter drop matcher."); - return -1; - } - dtb->drop_matcher = - container_of(entry, struct mlx5_flow_dv_matcher, entry); - } - if (!dtb->color_matcher) { - /* Create matchers for Color + meter_id. */ - if (priv->mtr_reg_share) { - flow_dv_match_meta_reg(matcher.mask.buf, value.buf, - color_reg_c_idx, 0, - (mtr_id_mask | color_mask)); - } else { - flow_dv_match_meta_reg(matcher.mask.buf, value.buf, - color_reg_c_idx, 0, color_mask); - flow_dv_match_meta_reg(matcher.mask.buf, value.buf, - mtr_id_reg_c_idx, 0, mtr_id_mask); - } - matcher.priority = MLX5_REG_BITS - priv->max_mtr_bits; - matcher.crc = rte_raw_cksum((const void *)matcher.mask.buf, - matcher.mask.size); - entry = mlx5_cache_register(&tbl_data->matchers, &ctx); - if (!entry) { - DRV_LOG(ERR, "Failed to register meter color matcher."); - return -1; - } - dtb->color_matcher = - container_of(entry, struct mlx5_flow_dv_matcher, entry); - } - return 0; -} - -/** - * Destroy domain policer rule. - * - * @param[in] dev - * Pointer to Ethernet device. - * @param[in] dt - * Pointer to domain table. - */ -static void -flow_dv_destroy_domain_policer_rule(struct rte_eth_dev *dev, - struct mlx5_meter_domain_info *dt) -{ - if (dt->drop_rule) { - claim_zero(mlx5_flow_os_destroy_flow(dt->drop_rule)); - dt->drop_rule = NULL; - } - if (dt->green_rule) { - claim_zero(mlx5_flow_os_destroy_flow(dt->green_rule)); - dt->green_rule = NULL; - } - flow_dv_destroy_mtr_matchers(dev, dt); - if (dt->jump_actn) { - claim_zero(mlx5_flow_os_destroy_flow_action(dt->jump_actn)); - dt->jump_actn = NULL; - } -} - -/** - * Destroy policer rules. - * - * @param[in] dev - * Pointer to Ethernet device. - * @param[in] fm - * Pointer to flow meter structure. - * @param[in] attr - * Pointer to flow attributes. - * - * @return - * Always 0. - */ -static int -flow_dv_destroy_policer_rules(struct rte_eth_dev *dev, - const struct mlx5_flow_meter_info *fm, - const struct rte_flow_attr *attr) -{ - struct mlx5_meter_domains_infos *mtb = fm ? fm->mfts : NULL; - - if (!mtb) - return 0; - if (attr->egress) - flow_dv_destroy_domain_policer_rule(dev, &mtb->egress); - if (attr->ingress) - flow_dv_destroy_domain_policer_rule(dev, &mtb->ingress); - if (attr->transfer) - flow_dv_destroy_domain_policer_rule(dev, &mtb->transfer); - return 0; -} - -/** - * Create specify domain meter policer rule. - * - * @param[in] dev - * Pointer to Ethernet device. - * @param[in] fm - * Pointer to flow meter structure. - * @param[in] mtr_idx - * meter index. - * @param[in] mtb - * Pointer to DV meter table set. - * @param[out] drop_rule - * The address of pointer saving drop rule. - * @param[out] color_rule - * The address of pointer saving green rule. - * - * @return - * 0 on success, -1 otherwise. - */ -static int -flow_dv_create_policer_forward_rule(struct rte_eth_dev *dev, - struct mlx5_flow_meter_info *fm, - uint32_t mtr_idx, - struct mlx5_meter_domain_info *dtb, - void **drop_rule, - void **green_rule) -{ - struct mlx5_priv *priv = dev->data->dev_private; - struct mlx5_flow_dv_match_params matcher = { - .size = sizeof(matcher.buf) - - MLX5_ST_SZ_BYTES(fte_match_set_misc4), - }; - struct mlx5_flow_dv_match_params value = { - .size = sizeof(value.buf) - - MLX5_ST_SZ_BYTES(fte_match_set_misc4), - }; - struct mlx5_meter_domains_infos *mtb = fm->mfts; - struct rte_flow_error error; - uint32_t color_reg_c = mlx5_flow_get_reg_id(dev, MLX5_MTR_COLOR, - 0, &error); - uint32_t mtr_id_reg_c = mlx5_flow_get_reg_id(dev, MLX5_MTR_ID, - 0, &error); - uint8_t mtr_id_offset = priv->mtr_reg_share ? MLX5_MTR_COLOR_BITS : 0; - uint32_t mtr_id_mask = - ((UINT32_C(1) << priv->max_mtr_bits) - 1) << mtr_id_offset; - void *actions[METER_ACTIONS]; - int i; - int ret = 0; - - /* Create jump action. */ - if (!dtb->jump_actn) - ret = mlx5_flow_os_create_flow_action_dest_flow_tbl - (dtb->sfx_tbl->obj, &dtb->jump_actn); - if (ret) { - DRV_LOG(ERR, "Failed to create policer jump action."); - goto error; - } - /* Prepare matchers. */ - if (!dtb->drop_matcher || !dtb->color_matcher) { - ret = flow_dv_prepare_mtr_matchers(dev, color_reg_c, - mtr_id_reg_c, mtr_id_mask, - dtb, &error); - if (ret) { - DRV_LOG(ERR, "Failed to setup matchers for mtr table."); - goto error; - } - } - /* Create Drop flow, matching meter_id only. */ - i = 0; - flow_dv_match_meta_reg(matcher.buf, value.buf, mtr_id_reg_c, - (mtr_idx << mtr_id_offset), UINT32_MAX); - if (mtb->drop_count) - actions[i++] = mtb->drop_count; - actions[i++] = priv->sh->dr_drop_action; - ret = mlx5_flow_os_create_flow(dtb->drop_matcher->matcher_object, - (void *)&value, i, actions, drop_rule); - if (ret) { - DRV_LOG(ERR, "Failed to create meter policer drop rule."); - goto error; - } - /* Create flow matching Green color + meter_id. */ - i = 0; - if (priv->mtr_reg_share) { - flow_dv_match_meta_reg(matcher.buf, value.buf, color_reg_c, - ((mtr_idx << mtr_id_offset) | - rte_col_2_mlx5_col(RTE_COLOR_GREEN)), - UINT32_MAX); - } else { - flow_dv_match_meta_reg(matcher.buf, value.buf, color_reg_c, - rte_col_2_mlx5_col(RTE_COLOR_GREEN), - UINT32_MAX); - flow_dv_match_meta_reg(matcher.buf, value.buf, mtr_id_reg_c, - mtr_idx, UINT32_MAX); - } - if (mtb->green_count) - actions[i++] = mtb->green_count; - actions[i++] = dtb->jump_actn; - ret = mlx5_flow_os_create_flow(dtb->color_matcher->matcher_object, - (void *)&value, i, actions, green_rule); - if (ret) { - DRV_LOG(ERR, "Failed to create meter policer color rule."); - goto error; - } - return 0; -error: - rte_errno = errno; - return -1; -} - -/** - * Prepare policer rules for all domains. - * If meter already initialized, this will replace all old rules with new ones. - * - * @param[in] dev - * Pointer to Ethernet device. - * @param[in] fm - * Pointer to flow meter structure. - * @param[in] attr - * Pointer to flow attributes. - * - * @return - * 0 on success, -1 otherwise. - */ -static int -flow_dv_prepare_policer_rules(struct rte_eth_dev *dev, - struct mlx5_flow_meter_info *fm, - const struct rte_flow_attr *attr) -{ - struct mlx5_priv *priv = dev->data->dev_private; - struct mlx5_meter_domains_infos *mtb = fm->mfts; - bool initialized = false; - struct mlx5_flow_counter *cnt; - void *egress_drop_rule = NULL; - void *egress_green_rule = NULL; - void *ingress_drop_rule = NULL; - void *ingress_green_rule = NULL; - void *transfer_drop_rule = NULL; - void *transfer_green_rule = NULL; - uint32_t mtr_idx; - int ret; - - /* Get the statistics counters for green/drop. */ - if (fm->policer_stats.pass_cnt) { - cnt = flow_dv_counter_get_by_idx(dev, - fm->policer_stats.pass_cnt, - NULL); - mtb->green_count = cnt->action; - } else { - mtb->green_count = NULL; - } - if (fm->policer_stats.drop_cnt) { - cnt = flow_dv_counter_get_by_idx(dev, - fm->policer_stats.drop_cnt, - NULL); - mtb->drop_count = cnt->action; - } else { - mtb->drop_count = NULL; - } - /** - * If flow meter has been initialized, all policer rules - * are created. So can get if meter initialized by checking - * any policer rule. - */ - if (mtb->egress.drop_rule) - initialized = true; - if (priv->sh->meter_aso_en) { - struct mlx5_aso_mtr *aso_mtr = NULL; - struct mlx5_aso_mtr_pool *pool; - - aso_mtr = container_of(fm, struct mlx5_aso_mtr, fm); - pool = container_of(aso_mtr, struct mlx5_aso_mtr_pool, - mtrs[aso_mtr->offset]); - mtr_idx = MLX5_MAKE_MTR_IDX(pool->index, aso_mtr->offset); - } else { - struct mlx5_legacy_flow_meter *legacy_fm; - - legacy_fm = container_of(fm, struct mlx5_legacy_flow_meter, fm); - mtr_idx = legacy_fm->idx; - } - if (attr->egress) { - ret = flow_dv_create_policer_forward_rule(dev, - fm, mtr_idx, &mtb->egress, - &egress_drop_rule, &egress_green_rule); - if (ret) { - DRV_LOG(ERR, "Failed to create egress policer."); - goto error; - } - } - if (attr->ingress) { - ret = flow_dv_create_policer_forward_rule(dev, - fm, mtr_idx, &mtb->ingress, - &ingress_drop_rule, &ingress_green_rule); - if (ret) { - DRV_LOG(ERR, "Failed to create ingress policer."); - goto error; - } - } - if (attr->transfer) { - ret = flow_dv_create_policer_forward_rule(dev, - fm, mtr_idx, &mtb->transfer, - &transfer_drop_rule, &transfer_green_rule); - if (ret) { - DRV_LOG(ERR, "Failed to create transfer policer."); - goto error; - } - } - /* Replace old flows if existing. */ - if (mtb->egress.drop_rule) - claim_zero(mlx5_flow_os_destroy_flow(mtb->egress.drop_rule)); - if (mtb->egress.green_rule) - claim_zero(mlx5_flow_os_destroy_flow(mtb->egress.green_rule)); - if (mtb->ingress.drop_rule) - claim_zero(mlx5_flow_os_destroy_flow(mtb->ingress.drop_rule)); - if (mtb->ingress.green_rule) - claim_zero(mlx5_flow_os_destroy_flow(mtb->ingress.green_rule)); - if (mtb->transfer.drop_rule) - claim_zero(mlx5_flow_os_destroy_flow(mtb->transfer.drop_rule)); - if (mtb->transfer.green_rule) - claim_zero(mlx5_flow_os_destroy_flow(mtb->transfer.green_rule)); - mtb->egress.drop_rule = egress_drop_rule; - mtb->egress.green_rule = egress_green_rule; - mtb->ingress.drop_rule = ingress_drop_rule; - mtb->ingress.green_rule = ingress_green_rule; - mtb->transfer.drop_rule = transfer_drop_rule; - mtb->transfer.green_rule = transfer_green_rule; - return 0; -error: - if (egress_drop_rule) - claim_zero(mlx5_flow_os_destroy_flow(egress_drop_rule)); - if (egress_green_rule) - claim_zero(mlx5_flow_os_destroy_flow(egress_green_rule)); - if (ingress_drop_rule) - claim_zero(mlx5_flow_os_destroy_flow(ingress_drop_rule)); - if (ingress_green_rule) - claim_zero(mlx5_flow_os_destroy_flow(ingress_green_rule)); - if (transfer_drop_rule) - claim_zero(mlx5_flow_os_destroy_flow(transfer_drop_rule)); - if (transfer_green_rule) - claim_zero(mlx5_flow_os_destroy_flow(transfer_green_rule)); - if (!initialized) - flow_dv_destroy_policer_rules(dev, fm, attr); - return -1; -} - /** * Validate the batch counter support in root table. * @@ -14423,8 +13968,6 @@ const struct mlx5_flow_driver_ops mlx5_flow_dv_drv_ops = { .query = flow_dv_query, .create_mtr_tbls = flow_dv_create_mtr_tbl, .destroy_mtr_tbls = flow_dv_destroy_mtr_tbl, - .prepare_policer_rules = flow_dv_prepare_policer_rules, - .destroy_policer_rules = flow_dv_destroy_policer_rules, .create_meter = flow_dv_mtr_alloc, .free_meter = flow_dv_aso_mtr_release_to_pool, .counter_alloc = flow_dv_counter_allocate, diff --git a/drivers/net/mlx5/mlx5_flow_meter.c b/drivers/net/mlx5/mlx5_flow_meter.c index 714b382d55..af0a1c18cb 100644 --- a/drivers/net/mlx5/mlx5_flow_meter.c +++ b/drivers/net/mlx5/mlx5_flow_meter.c @@ -329,7 +329,6 @@ mlx5_flow_mtr_cap_get(struct rte_eth_dev *dev, cap->chaining_n_mtrs_per_flow_max = 1; /* Chaining is not supported. */ cap->meter_srtcm_rfc2697_n_max = qattr->flow_meter_old ? cap->n_max : 0; cap->meter_rate_max = 1ULL << 40; /* 1 Tera tokens per sec. */ - cap->policer_action_drop_supported = 1; cap->stats_mask = RTE_MTR_STATS_N_BYTES_DROPPED | RTE_MTR_STATS_N_PKTS_DROPPED; return 0; @@ -436,90 +435,6 @@ mlx5_flow_meter_profile_delete(struct rte_eth_dev *dev, return 0; } -/** - * Convert wrong color setting action to verbose error. - * - * @param[in] action - * Policy color action. - * - * @return - * Verbose meter color error type. - */ -static inline enum rte_mtr_error_type -action2error(enum rte_mtr_policer_action action) -{ - switch (action) { - case MTR_POLICER_ACTION_COLOR_GREEN: - return RTE_MTR_ERROR_TYPE_POLICER_ACTION_GREEN; - case MTR_POLICER_ACTION_COLOR_YELLOW: - return RTE_MTR_ERROR_TYPE_POLICER_ACTION_YELLOW; - case MTR_POLICER_ACTION_COLOR_RED: - return RTE_MTR_ERROR_TYPE_POLICER_ACTION_RED; - default: - break; - } - return RTE_MTR_ERROR_TYPE_UNSPECIFIED; -} - -/** - * Check meter validation. - * - * @param[in] priv - * Pointer to mlx5 private data structure. - * @param[in] meter_id - * Meter id. - * @param[in] params - * Pointer to rte meter parameters. - * @param[out] error - * Pointer to rte meter error structure. - * - * @return - * 0 on success, a negative errno value otherwise and rte_errno is set. - */ -static int -mlx5_flow_meter_validate(struct mlx5_priv *priv, uint32_t meter_id, - struct rte_mtr_params *params, - struct rte_mtr_error *error) -{ - /* Meter must use global drop action. */ - if (!priv->sh->dr_drop_action) - return -rte_mtr_error_set(error, ENOTSUP, - RTE_MTR_ERROR_TYPE_MTR_PARAMS, - NULL, - "No drop action ready for meter."); - /* Meter params must not be NULL. */ - if (params == NULL) - return -rte_mtr_error_set(error, EINVAL, - RTE_MTR_ERROR_TYPE_MTR_PARAMS, - NULL, "Meter object params null."); - /* Previous meter color is not supported. */ - if (params->use_prev_mtr_color) - return -rte_mtr_error_set(error, ENOTSUP, - RTE_MTR_ERROR_TYPE_MTR_PARAMS, - NULL, - "Previous meter color " - "not supported."); - /* Validate policer settings. */ - if (params->action[RTE_COLOR_RED] != MTR_POLICER_ACTION_DROP) - return -rte_mtr_error_set - (error, ENOTSUP, - action2error(params->action[RTE_COLOR_RED]), - NULL, - "Red color only supports drop action."); - if (params->action[RTE_COLOR_GREEN] != MTR_POLICER_ACTION_COLOR_GREEN) - return -rte_mtr_error_set - (error, ENOTSUP, - action2error(params->action[RTE_COLOR_GREEN]), - NULL, - "Green color only supports recolor green action."); - /* Validate meter id. */ - if (mlx5_flow_meter_find(priv, meter_id, NULL)) - return -rte_mtr_error_set(error, EEXIST, - RTE_MTR_ERROR_TYPE_MTR_ID, NULL, - "Meter object already exists."); - return 0; -} - /** * Modify the flow meter action. * @@ -629,167 +544,14 @@ static void mlx5_flow_meter_stats_enable_update(struct mlx5_flow_meter_info *fm, uint64_t stats_mask) { - fm->green_bytes = (stats_mask & RTE_MTR_STATS_N_BYTES_GREEN) ? 1 : 0; - fm->green_pkts = (stats_mask & RTE_MTR_STATS_N_PKTS_GREEN) ? 1 : 0; - fm->red_bytes = (stats_mask & RTE_MTR_STATS_N_BYTES_RED) ? 1 : 0; - fm->red_pkts = (stats_mask & RTE_MTR_STATS_N_PKTS_RED) ? 1 : 0; fm->bytes_dropped = (stats_mask & RTE_MTR_STATS_N_BYTES_DROPPED) ? 1 : 0; fm->pkts_dropped = (stats_mask & RTE_MTR_STATS_N_PKTS_DROPPED) ? 1 : 0; } -/** - * Create meter rules. - * - * @param[in] dev - * Pointer to Ethernet device. - * @param[in] meter_id - * Meter id. - * @param[in] params - * Pointer to rte meter parameters. - * @param[in] shared - * Meter shared with other flow or not. - * @param[out] error - * Pointer to rte meter error structure. - * - * @return - * 0 on success, a negative errno value otherwise and rte_errno is set. - */ -static int -mlx5_flow_meter_create(struct rte_eth_dev *dev, uint32_t meter_id, - struct rte_mtr_params *params, int shared, - struct rte_mtr_error *error) -{ - struct mlx5_priv *priv = dev->data->dev_private; - struct mlx5_legacy_flow_meters *fms = &priv->flow_meters; - struct mlx5_flow_meter_profile *fmp; - struct mlx5_legacy_flow_meter *legacy_fm; - struct mlx5_flow_meter_info *fm; - const struct rte_flow_attr attr = { - .ingress = 1, - .egress = 1, - .transfer = priv->config.dv_esw_en ? 1 : 0, - }; - struct mlx5_indexed_pool_config flow_ipool_cfg = { - .size = 0, - .trunk_size = 64, - .need_lock = 1, - .type = "mlx5_flow_mtr_flow_id_pool", - }; - struct mlx5_aso_mtr *aso_mtr; - union mlx5_l3t_data data; - uint32_t mtr_idx; - int ret; - uint8_t mtr_id_bits; - uint8_t mtr_reg_bits = priv->mtr_reg_share ? - MLX5_MTR_IDLE_BITS_IN_COLOR_REG : MLX5_REG_BITS; - - if (!priv->mtr_en) - return -rte_mtr_error_set(error, ENOTSUP, - RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL, - "Meter is not supported"); - /* Validate the parameters. */ - ret = mlx5_flow_meter_validate(priv, meter_id, params, error); - if (ret) - return ret; - /* Meter profile must exist. */ - fmp = mlx5_flow_meter_profile_find(priv, params->meter_profile_id); - if (fmp == NULL) - return -rte_mtr_error_set(error, ENOENT, - RTE_MTR_ERROR_TYPE_METER_PROFILE_ID, - NULL, "Meter profile id not valid."); - /* Allocate the flow meter memory. */ - if (priv->sh->meter_aso_en) { - mtr_idx = mlx5_flow_mtr_alloc(dev); - if (!mtr_idx) - return -rte_mtr_error_set(error, ENOMEM, - RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL, - "Memory alloc failed for meter."); - aso_mtr = mlx5_aso_meter_by_idx(priv, mtr_idx); - fm = &aso_mtr->fm; - } else { - legacy_fm = mlx5_ipool_zmalloc - (priv->sh->ipool[MLX5_IPOOL_MTR], &mtr_idx); - if (legacy_fm == NULL) - return -rte_mtr_error_set(error, ENOMEM, - RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL, - "Memory alloc failed for meter."); - legacy_fm->idx = mtr_idx; - fm = &legacy_fm->fm; - } - mtr_id_bits = MLX5_REG_BITS - __builtin_clz(mtr_idx); - if ((mtr_id_bits + priv->max_mtr_flow_bits) > mtr_reg_bits) { - DRV_LOG(ERR, "Meter number exceeds max limit."); - goto error; - } - if (mtr_id_bits > priv->max_mtr_bits) - priv->max_mtr_bits = mtr_id_bits; - /* Fill the flow meter parameters. */ - fm->meter_id = meter_id; - fm->profile = fmp; - memcpy(fm->action, params->action, sizeof(params->action)); - mlx5_flow_meter_stats_enable_update(fm, params->stats_mask); - /* Alloc policer counters. */ - if (fm->green_bytes || fm->green_pkts) { - fm->policer_stats.pass_cnt = mlx5_counter_alloc(dev); - if (!fm->policer_stats.pass_cnt) - goto error; - } - if (fm->red_bytes || fm->red_pkts || - fm->bytes_dropped || fm->pkts_dropped) { - fm->policer_stats.drop_cnt = mlx5_counter_alloc(dev); - if (!fm->policer_stats.drop_cnt) - goto error; - } - fm->mfts = mlx5_flow_create_mtr_tbls(dev); - if (!fm->mfts) - goto error; - ret = mlx5_flow_prepare_policer_rules(dev, fm, &attr); - if (ret) - goto error; - /* Add to the flow meter list. */ - if (!priv->sh->meter_aso_en) - TAILQ_INSERT_TAIL(fms, legacy_fm, next); - fm->active_state = 1; /* Config meter starts as active. */ - fm->is_enable = 1; - fm->shared = !!shared; - __atomic_add_fetch(&fm->profile->ref_cnt, 1, __ATOMIC_RELAXED); - fm->flow_ipool = mlx5_ipool_create(&flow_ipool_cfg); - if (!fm->flow_ipool) - goto error; - rte_spinlock_init(&fm->sl); - /* If ASO meter supported, allocate ASO flow meter. */ - if (priv->sh->meter_aso_en) { - aso_mtr = container_of(fm, struct mlx5_aso_mtr, fm); - ret = mlx5_aso_meter_update_by_wqe(priv->sh, aso_mtr); - if (ret) - goto error; - data.dword = mtr_idx; - if (mlx5_l3t_set_entry(priv->mtr_idx_tbl, meter_id, &data)) - goto error; - } - return 0; -error: - mlx5_flow_destroy_policer_rules(dev, fm, &attr); - mlx5_flow_destroy_mtr_tbls(dev, fm->mfts); - /* Free policer counters. */ - if (fm->policer_stats.pass_cnt) - mlx5_counter_free(dev, fm->policer_stats.pass_cnt); - if (fm->policer_stats.drop_cnt) - mlx5_counter_free(dev, fm->policer_stats.drop_cnt); - if (priv->sh->meter_aso_en) - mlx5_flow_mtr_free(dev, mtr_idx); - else - mlx5_ipool_free(priv->sh->ipool[MLX5_IPOOL_MTR], mtr_idx); - return -rte_mtr_error_set(error, -ret, - RTE_MTR_ERROR_TYPE_UNSPECIFIED, - NULL, "Failed to create devx meter."); -} - static int mlx5_flow_meter_params_flush(struct rte_eth_dev *dev, struct mlx5_flow_meter_info *fm, - const struct rte_flow_attr *attr, uint32_t mtr_idx) { struct mlx5_priv *priv = dev->data->dev_private; @@ -810,15 +572,12 @@ mlx5_flow_meter_params_flush(struct rte_eth_dev *dev, legacy_fm = container_of(fm, struct mlx5_legacy_flow_meter, fm); TAILQ_REMOVE(fms, legacy_fm, next); } - /* Free policer counters. */ - if (fm->policer_stats.pass_cnt) - mlx5_counter_free(dev, fm->policer_stats.pass_cnt); - if (fm->policer_stats.drop_cnt) - mlx5_counter_free(dev, fm->policer_stats.drop_cnt); + /* Free drop counters. */ + if (fm->drop_cnt) + mlx5_counter_free(dev, fm->drop_cnt); /* Free meter flow table. */ if (fm->flow_ipool) mlx5_ipool_destroy(fm->flow_ipool); - mlx5_flow_destroy_policer_rules(dev, fm, attr); mlx5_flow_destroy_mtr_tbls(dev, fm->mfts); if (priv->sh->meter_aso_en) mlx5_flow_mtr_free(dev, mtr_idx); @@ -847,11 +606,6 @@ mlx5_flow_meter_destroy(struct rte_eth_dev *dev, uint32_t meter_id, { struct mlx5_priv *priv = dev->data->dev_private; struct mlx5_flow_meter_info *fm; - const struct rte_flow_attr attr = { - .ingress = 1, - .egress = 1, - .transfer = priv->config.dv_esw_en ? 1 : 0, - }; uint32_t mtr_idx = 0; if (!priv->mtr_en) @@ -876,7 +630,7 @@ mlx5_flow_meter_destroy(struct rte_eth_dev *dev, uint32_t meter_id, "Fail to delete ASO Meter in index table."); } /* Destroy the meter profile. */ - if (mlx5_flow_meter_params_flush(dev, fm, &attr, mtr_idx)) + if (mlx5_flow_meter_params_flush(dev, fm, mtr_idx)) return -rte_mtr_error_set(error, EINVAL, RTE_MTR_ERROR_TYPE_METER_PROFILE_ID, NULL, "MTR object meter profile invalid."); @@ -1102,13 +856,6 @@ mlx5_flow_meter_stats_update(struct rte_eth_dev *dev, { struct mlx5_priv *priv = dev->data->dev_private; struct mlx5_flow_meter_info *fm; - const struct rte_flow_attr attr = { - .ingress = 1, - .egress = 1, - .transfer = priv->config.dv_esw_en ? 1 : 0, - }; - bool need_updated = false; - struct mlx5_flow_policer_stats old_policer_stats; if (!priv->mtr_en) return -rte_mtr_error_set(error, ENOTSUP, @@ -1120,69 +867,6 @@ mlx5_flow_meter_stats_update(struct rte_eth_dev *dev, return -rte_mtr_error_set(error, ENOENT, RTE_MTR_ERROR_TYPE_MTR_ID, NULL, "Meter object id not valid."); - old_policer_stats.pass_cnt = 0; - old_policer_stats.drop_cnt = 0; - if (!!((RTE_MTR_STATS_N_PKTS_GREEN | - RTE_MTR_STATS_N_BYTES_GREEN) & stats_mask) != - !!fm->policer_stats.pass_cnt) { - need_updated = true; - if (fm->policer_stats.pass_cnt) { - old_policer_stats.pass_cnt = fm->policer_stats.pass_cnt; - fm->policer_stats.pass_cnt = 0; - } else { - fm->policer_stats.pass_cnt = - mlx5_counter_alloc(dev); - if (!fm->policer_stats.pass_cnt) - return -rte_mtr_error_set(error, ENOMEM, - RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL, - "Counter alloc failed for meter."); - } - } - if (!!((RTE_MTR_STATS_N_PKTS_RED | RTE_MTR_STATS_N_BYTES_RED | - RTE_MTR_STATS_N_PKTS_DROPPED | RTE_MTR_STATS_N_BYTES_DROPPED) & - stats_mask) != - !!fm->policer_stats.drop_cnt) { - need_updated = true; - if (fm->policer_stats.drop_cnt) { - old_policer_stats.drop_cnt = fm->policer_stats.drop_cnt; - fm->policer_stats.drop_cnt = 0; - } else { - fm->policer_stats.drop_cnt = - mlx5_counter_alloc(dev); - if (!fm->policer_stats.drop_cnt) - return -rte_mtr_error_set(error, ENOMEM, - RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL, - "Counter alloc failed for meter."); - } - } - if (need_updated) { - if (mlx5_flow_prepare_policer_rules(dev, fm, &attr)) { - if (fm->policer_stats.pass_cnt && - fm->policer_stats.pass_cnt != - old_policer_stats.pass_cnt) - mlx5_counter_free(dev, - fm->policer_stats.pass_cnt); - fm->policer_stats.pass_cnt = - old_policer_stats.pass_cnt; - if (fm->policer_stats.drop_cnt && - fm->policer_stats.drop_cnt != - old_policer_stats.drop_cnt) - mlx5_counter_free(dev, - fm->policer_stats.drop_cnt); - fm->policer_stats.pass_cnt = - old_policer_stats.pass_cnt; - return -rte_mtr_error_set(error, ENOTSUP, - RTE_MTR_ERROR_TYPE_UNSPECIFIED, - NULL, "Failed to create meter policer rules."); - } - /* Free old policer counters. */ - if (old_policer_stats.pass_cnt) - mlx5_counter_free(dev, - old_policer_stats.pass_cnt); - if (old_policer_stats.drop_cnt) - mlx5_counter_free(dev, - old_policer_stats.drop_cnt); - } mlx5_flow_meter_stats_enable_update(fm, stats_mask); return 0; } @@ -1216,7 +900,6 @@ mlx5_flow_meter_stats_read(struct rte_eth_dev *dev, { struct mlx5_priv *priv = dev->data->dev_private; struct mlx5_flow_meter_info *fm; - struct mlx5_flow_policer_stats *ps; uint64_t pkts; uint64_t bytes; int ret = 0; @@ -1231,35 +914,14 @@ mlx5_flow_meter_stats_read(struct rte_eth_dev *dev, return -rte_mtr_error_set(error, ENOENT, RTE_MTR_ERROR_TYPE_MTR_ID, NULL, "Meter object id not valid."); - ps = &fm->policer_stats; *stats_mask = 0; - if (fm->green_bytes) - *stats_mask |= RTE_MTR_STATS_N_BYTES_GREEN; - if (fm->green_pkts) - *stats_mask |= RTE_MTR_STATS_N_PKTS_GREEN; - if (fm->red_bytes) - *stats_mask |= RTE_MTR_STATS_N_BYTES_RED; - if (fm->red_pkts) - *stats_mask |= RTE_MTR_STATS_N_PKTS_RED; if (fm->bytes_dropped) *stats_mask |= RTE_MTR_STATS_N_BYTES_DROPPED; if (fm->pkts_dropped) *stats_mask |= RTE_MTR_STATS_N_PKTS_DROPPED; memset(stats, 0, sizeof(*stats)); - if (ps->pass_cnt) { - ret = mlx5_counter_query(dev, ps->pass_cnt, clear, &pkts, - &bytes); - if (ret) - goto error; - /* If need to read the packets, set it. */ - if (fm->green_pkts) - stats->n_pkts[RTE_COLOR_GREEN] = pkts; - /* If need to read the bytes, set it. */ - if (fm->green_bytes) - stats->n_bytes[RTE_COLOR_GREEN] = bytes; - } - if (ps->drop_cnt) { - ret = mlx5_counter_query(dev, ps->drop_cnt, clear, &pkts, + if (fm->drop_cnt) { + ret = mlx5_counter_query(dev, fm->drop_cnt, clear, &pkts, &bytes); if (ret) goto error; @@ -1273,20 +935,18 @@ mlx5_flow_meter_stats_read(struct rte_eth_dev *dev, return 0; error: return -rte_mtr_error_set(error, ret, RTE_MTR_ERROR_TYPE_STATS, NULL, - "Failed to read policer counters."); + "Failed to read meter drop counters."); } static const struct rte_mtr_ops mlx5_flow_mtr_ops = { .capabilities_get = mlx5_flow_mtr_cap_get, .meter_profile_add = mlx5_flow_meter_profile_add, .meter_profile_delete = mlx5_flow_meter_profile_delete, - .create = mlx5_flow_meter_create, .destroy = mlx5_flow_meter_destroy, .meter_enable = mlx5_flow_meter_enable, .meter_disable = mlx5_flow_meter_disable, .meter_profile_update = mlx5_flow_meter_profile_update, .meter_dscp_table_update = NULL, - .policer_actions_update = NULL, .stats_update = mlx5_flow_meter_stats_update, .stats_read = mlx5_flow_meter_stats_read, }; @@ -1344,12 +1004,11 @@ mlx5_flow_meter_find(struct mlx5_priv *priv, uint32_t meter_id, aso_mtr = mlx5_aso_meter_by_idx(priv, data.dword); /* Remove reference taken by the mlx5_l3t_get_entry. */ mlx5_l3t_clear_entry(priv->mtr_idx_tbl, meter_id); - MLX5_ASSERT(meter_id == aso_mtr->fm.meter_id); rte_spinlock_unlock(&mtrmng->mtrsl); return &aso_mtr->fm; } TAILQ_FOREACH(legacy_fm, fms, next) - if (meter_id == legacy_fm->fm.meter_id) { + if (meter_id == legacy_fm->meter_id) { if (mtr_idx) *mtr_idx = legacy_fm->idx; return &legacy_fm->fm; @@ -1517,11 +1176,6 @@ mlx5_flow_meter_flush(struct rte_eth_dev *dev, struct rte_mtr_error *error) struct mlx5_legacy_flow_meter *legacy_fm; struct mlx5_flow_meter_info *fm; struct mlx5_aso_mtr_pool *mtr_pool; - const struct rte_flow_attr attr = { - .ingress = 1, - .egress = 1, - .transfer = priv->config.dv_esw_en ? 1 : 0, - }; void *tmp; uint32_t i, offset, mtr_idx; @@ -1533,9 +1187,8 @@ mlx5_flow_meter_flush(struct rte_eth_dev *dev, struct rte_mtr_error *error) offset++) { fm = &mtr_pool->mtrs[offset].fm; mtr_idx = MLX5_MAKE_MTR_IDX(i, offset); - if (fm->meter_id != UINT32_MAX && - mlx5_flow_meter_params_flush(dev, - fm, &attr, mtr_idx)) + if (mlx5_flow_meter_params_flush(dev, + fm, mtr_idx)) return -rte_mtr_error_set (error, EINVAL, RTE_MTR_ERROR_TYPE_METER_PROFILE_ID, @@ -1545,7 +1198,7 @@ mlx5_flow_meter_flush(struct rte_eth_dev *dev, struct rte_mtr_error *error) } else { TAILQ_FOREACH_SAFE(legacy_fm, fms, next, tmp) { fm = &legacy_fm->fm; - if (mlx5_flow_meter_params_flush(dev, fm, &attr, 0)) + if (mlx5_flow_meter_params_flush(dev, fm, 0)) return -rte_mtr_error_set(error, EINVAL, RTE_MTR_ERROR_TYPE_METER_PROFILE_ID, NULL, "MTR object meter profile invalid."); diff --git a/drivers/net/softnic/rte_eth_softnic_flow.c b/drivers/net/softnic/rte_eth_softnic_flow.c index 7925bad1c0..27eaf380cd 100644 --- a/drivers/net/softnic/rte_eth_softnic_flow.c +++ b/drivers/net/softnic/rte_eth_softnic_flow.c @@ -1166,6 +1166,7 @@ flow_rule_action_get(struct pmd_internals *softnic, { struct softnic_table_action_profile *profile; struct softnic_table_action_profile_params *params; + struct softnic_mtr_meter_policy *policy; int n_jump_queue_rss_drop = 0; int n_count = 0; int n_mark = 0; @@ -1621,15 +1622,25 @@ flow_rule_action_get(struct pmd_internals *softnic, return -1; } } - + /* Meter policy must exist */ + policy = softnic_mtr_meter_policy_find(softnic, + m->params.meter_policy_id); + if (policy == NULL) { + rte_flow_error_set(error, + EINVAL, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, + "METER: fail to find meter policy"); + return -1; + } /* RTE_TABLE_ACTION_METER */ rule_action->mtr.mtr[0].meter_profile_id = meter_profile_id; rule_action->mtr.mtr[0].policer[RTE_COLOR_GREEN] = - softnic_table_action_policer(m->params.action[RTE_COLOR_GREEN]); + policy->policer[RTE_COLOR_GREEN]; rule_action->mtr.mtr[0].policer[RTE_COLOR_YELLOW] = - softnic_table_action_policer(m->params.action[RTE_COLOR_YELLOW]); + policy->policer[RTE_COLOR_YELLOW]; rule_action->mtr.mtr[0].policer[RTE_COLOR_RED] = - softnic_table_action_policer(m->params.action[RTE_COLOR_RED]); + policy->policer[RTE_COLOR_RED]; rule_action->mtr.tc_mask = 1; rule_action->action_mask |= 1 << RTE_TABLE_ACTION_MTR; break; diff --git a/drivers/net/softnic/rte_eth_softnic_internals.h b/drivers/net/softnic/rte_eth_softnic_internals.h index faf90a5a8c..1b3186ef0b 100644 --- a/drivers/net/softnic/rte_eth_softnic_internals.h +++ b/drivers/net/softnic/rte_eth_softnic_internals.h @@ -83,6 +83,16 @@ struct softnic_mtr_meter_profile { TAILQ_HEAD(softnic_mtr_meter_profile_list, softnic_mtr_meter_profile); +/* MTR meter policy */ +struct softnic_mtr_meter_policy { + TAILQ_ENTRY(softnic_mtr_meter_policy) node; + uint32_t meter_policy_id; + enum rte_table_action_policer policer[RTE_COLORS]; + uint32_t n_users; +}; + +TAILQ_HEAD(softnic_mtr_meter_policy_list, softnic_mtr_meter_policy); + /* MTR meter object */ struct softnic_mtr { TAILQ_ENTRY(softnic_mtr) node; @@ -95,6 +105,7 @@ TAILQ_HEAD(softnic_mtr_list, softnic_mtr); struct mtr_internals { struct softnic_mtr_meter_profile_list meter_profiles; + struct softnic_mtr_meter_policy_list meter_policies; struct softnic_mtr_list mtrs; }; @@ -678,6 +689,10 @@ struct softnic_mtr_meter_profile * softnic_mtr_meter_profile_find(struct pmd_internals *p, uint32_t meter_profile_id); +struct softnic_mtr_meter_policy * +softnic_mtr_meter_policy_find(struct pmd_internals *p, + uint32_t meter_policy_id); + extern const struct rte_mtr_ops pmd_mtr_ops; /** @@ -841,9 +856,6 @@ softnic_table_action_profile_create(struct pmd_internals *p, const char *name, struct softnic_table_action_profile_params *params); -enum rte_table_action_policer -softnic_table_action_policer(enum rte_mtr_policer_action action); - /** * Pipeline */ diff --git a/drivers/net/softnic/rte_eth_softnic_meter.c b/drivers/net/softnic/rte_eth_softnic_meter.c index 31a2a0e6d9..2a05a85cdb 100644 --- a/drivers/net/softnic/rte_eth_softnic_meter.c +++ b/drivers/net/softnic/rte_eth_softnic_meter.c @@ -65,27 +65,6 @@ softnic_mtr_meter_profile_find(struct pmd_internals *p, return NULL; } -enum rte_table_action_policer -softnic_table_action_policer(enum rte_mtr_policer_action action) -{ - switch (action) { - case MTR_POLICER_ACTION_COLOR_GREEN: - return RTE_TABLE_ACTION_POLICER_COLOR_GREEN; - - /* FALLTHROUGH */ - case MTR_POLICER_ACTION_COLOR_YELLOW: - return RTE_TABLE_ACTION_POLICER_COLOR_YELLOW; - - /* FALLTHROUGH */ - case MTR_POLICER_ACTION_COLOR_RED: - return RTE_TABLE_ACTION_POLICER_COLOR_RED; - - /* FALLTHROUGH */ - default: - return RTE_TABLE_ACTION_POLICER_DROP; - } -} - static int meter_profile_check(struct rte_eth_dev *dev, uint32_t meter_profile_id, @@ -200,6 +179,129 @@ pmd_mtr_meter_profile_delete(struct rte_eth_dev *dev, return 0; } +struct softnic_mtr_meter_policy * +softnic_mtr_meter_policy_find(struct pmd_internals *p, + uint32_t meter_policy_id) +{ + struct softnic_mtr_meter_policy_list *mpl = &p->mtr.meter_policies; + struct softnic_mtr_meter_policy *mp; + + TAILQ_FOREACH(mp, mpl, node) + if (meter_policy_id == mp->meter_policy_id) + return mp; + + return NULL; +} + +/* MTR meter policy create */ +static int +pmd_mtr_meter_policy_create(struct rte_eth_dev *dev, + uint32_t meter_policy_id, + struct rte_mtr_meter_policy_params *policy, + struct rte_mtr_error *error) +{ + struct pmd_internals *p = dev->data->dev_private; + struct softnic_mtr_meter_policy_list *mpl = &p->mtr.meter_policies; + struct softnic_mtr_meter_policy *mp; + const struct rte_flow_action *act; + const struct rte_flow_action_meter_color *recolor; + uint32_t i; + + /* Meter policy ID must be valid. */ + if (meter_policy_id == UINT32_MAX) + return -rte_mtr_error_set(error, + EINVAL, + RTE_MTR_ERROR_TYPE_METER_POLICY_ID, + NULL, + "Meter policy id not valid"); + + for (i = 0; i < RTE_COLORS; i++) { + act = policy->actions[i]; + if (act && act->type != RTE_FLOW_ACTION_TYPE_METER_COLOR && + act->type != RTE_FLOW_ACTION_TYPE_DROP) + return -rte_mtr_error_set(error, + EINVAL, + RTE_MTR_ERROR_TYPE_METER_POLICY, + NULL, + "Action invalid"); + } + + /* Memory allocation */ + mp = calloc(1, sizeof(struct softnic_mtr_meter_policy)); + if (mp == NULL) + return -rte_mtr_error_set(error, + ENOMEM, + RTE_MTR_ERROR_TYPE_UNSPECIFIED, + NULL, + "Memory alloc failed"); + + /* Fill in */ + mp->meter_policy_id = meter_policy_id; + for (i = 0; i < RTE_COLORS; i++) { + mp->policer[i] = RTE_TABLE_ACTION_POLICER_DROP; + act = policy->actions[i]; + if (!act) + continue; + if (act->type == RTE_FLOW_ACTION_TYPE_METER_COLOR) { + recolor = act->conf; + switch (recolor->color) { + case RTE_COLOR_GREEN: + mp->policer[i] = + RTE_TABLE_ACTION_POLICER_COLOR_GREEN; + break; + case RTE_COLOR_YELLOW: + mp->policer[i] = + RTE_TABLE_ACTION_POLICER_COLOR_YELLOW; + break; + case RTE_COLOR_RED: + mp->policer[i] = + RTE_TABLE_ACTION_POLICER_COLOR_RED; + break; + default: + break; + } + } + } + + /* Add to list */ + TAILQ_INSERT_TAIL(mpl, mp, node); + + return 0; +} + +/* MTR meter policy delete */ +static int +pmd_mtr_meter_policy_delete(struct rte_eth_dev *dev, + uint32_t meter_policy_id, + struct rte_mtr_error *error) +{ + struct pmd_internals *p = dev->data->dev_private; + struct softnic_mtr_meter_policy *mp; + + /* Meter policy must exist */ + mp = softnic_mtr_meter_policy_find(p, meter_policy_id); + if (mp == NULL) + return -rte_mtr_error_set(error, + EINVAL, + RTE_MTR_ERROR_TYPE_METER_POLICY_ID, + NULL, + "Meter policy id invalid"); + + /* Check unused */ + if (mp->n_users) + return -rte_mtr_error_set(error, + EBUSY, + RTE_MTR_ERROR_TYPE_METER_POLICY_ID, + NULL, + "Meter policy in use"); + + /* Remove from list */ + TAILQ_REMOVE(&p->mtr.meter_policies, mp, node); + free(mp); + + return 0; +} + struct softnic_mtr * softnic_mtr_find(struct pmd_internals *p, uint32_t mtr_id) { @@ -267,6 +369,7 @@ pmd_mtr_create(struct rte_eth_dev *dev, struct pmd_internals *p = dev->data->dev_private; struct softnic_mtr_list *ml = &p->mtr.mtrs; struct softnic_mtr_meter_profile *mp; + struct softnic_mtr_meter_policy *policy; struct softnic_mtr *m; int status; @@ -284,6 +387,16 @@ pmd_mtr_create(struct rte_eth_dev *dev, NULL, "Meter profile id not valid"); + /* Meter policy must exist */ + policy = softnic_mtr_meter_policy_find(p, params->meter_policy_id); + if (policy == NULL) { + return -rte_mtr_error_set(error, + EINVAL, + RTE_MTR_ERROR_TYPE_METER_POLICY_ID, + NULL, + "Meter policy id invalid"); + } + /* Memory allocation */ m = calloc(1, sizeof(struct softnic_mtr)); if (m == NULL) @@ -302,6 +415,7 @@ pmd_mtr_create(struct rte_eth_dev *dev, /* Update dependencies */ mp->n_users++; + policy->n_users++; return 0; } @@ -316,6 +430,7 @@ pmd_mtr_destroy(struct rte_eth_dev *dev, struct softnic_mtr_list *ml = &p->mtr.mtrs; struct softnic_mtr_meter_profile *mp; struct softnic_mtr *m; + struct softnic_mtr_meter_policy *policy; /* MTR object must exist */ m = softnic_mtr_find(p, mtr_id); @@ -343,8 +458,18 @@ pmd_mtr_destroy(struct rte_eth_dev *dev, NULL, "MTR object meter profile invalid"); + /* Meter policy must exist */ + policy = softnic_mtr_meter_policy_find(p, m->params.meter_policy_id); + if (policy == NULL) + return -rte_mtr_error_set(error, + EINVAL, + RTE_MTR_ERROR_TYPE_METER_POLICY_ID, + NULL, + "MTR object meter policy invalid"); + /* Update dependencies */ mp->n_users--; + policy->n_users--; /* Remove from list */ TAILQ_REMOVE(ml, m, node); @@ -506,18 +631,18 @@ pmd_mtr_meter_dscp_table_update(struct rte_eth_dev *dev, return 0; } -/* MTR object policer action update */ +/* MTR object policy update */ static int -pmd_mtr_policer_actions_update(struct rte_eth_dev *dev, +pmd_mtr_meter_policy_update(struct rte_eth_dev *dev, uint32_t mtr_id, - uint32_t action_mask, - enum rte_mtr_policer_action *actions, + uint32_t meter_policy_id, struct rte_mtr_error *error) { struct pmd_internals *p = dev->data->dev_private; struct softnic_mtr *m; uint32_t i; int status; + struct softnic_mtr_meter_policy *mp_new, *mp_old; /* MTR object id must be valid */ m = softnic_mtr_find(p, mtr_id); @@ -527,29 +652,14 @@ pmd_mtr_policer_actions_update(struct rte_eth_dev *dev, RTE_MTR_ERROR_TYPE_MTR_ID, NULL, "MTR object id not valid"); - - /* Valid policer actions */ - if (actions == NULL) + /* Meter policy must exist */ + mp_new = softnic_mtr_meter_policy_find(p, meter_policy_id); + if (mp_new == NULL) return -rte_mtr_error_set(error, EINVAL, - RTE_MTR_ERROR_TYPE_UNSPECIFIED, + RTE_MTR_ERROR_TYPE_METER_POLICY_ID, NULL, - "Invalid actions"); - - for (i = 0; i < RTE_COLORS; i++) { - if (action_mask & (1 << i)) { - if (actions[i] != MTR_POLICER_ACTION_COLOR_GREEN && - actions[i] != MTR_POLICER_ACTION_COLOR_YELLOW && - actions[i] != MTR_POLICER_ACTION_COLOR_RED && - actions[i] != MTR_POLICER_ACTION_DROP) { - return -rte_mtr_error_set(error, - EINVAL, - RTE_MTR_ERROR_TYPE_UNSPECIFIED, - NULL, - " Invalid action value"); - } - } - } + "Meter policy id invalid"); /* MTR object owner valid? */ if (m->flow) { @@ -561,9 +671,7 @@ pmd_mtr_policer_actions_update(struct rte_eth_dev *dev, /* Set action */ for (i = 0; i < RTE_COLORS; i++) - if (action_mask & (1 << i)) - action.mtr.mtr[0].policer[i] = - softnic_table_action_policer(actions[i]); + action.mtr.mtr[0].policer[i] = mp_new->policer[i]; /* Re-add the rule */ status = softnic_pipeline_table_rule_add(p, @@ -587,10 +695,20 @@ pmd_mtr_policer_actions_update(struct rte_eth_dev *dev, 1, NULL, 1); } - /* Meter: Update policer actions */ - for (i = 0; i < RTE_COLORS; i++) - if (action_mask & (1 << i)) - m->params.action[i] = actions[i]; + mp_old = softnic_mtr_meter_policy_find(p, m->params.meter_policy_id); + if (mp_old == NULL) + return -rte_mtr_error_set(error, + EINVAL, + RTE_MTR_ERROR_TYPE_METER_POLICY_ID, + NULL, + "Old meter policy id invalid"); + + /* Meter: Set meter profile */ + m->params.meter_policy_id = meter_policy_id; + + /* Update dependencies*/ + mp_old->n_users--; + mp_new->n_users++; return 0; } @@ -607,28 +725,40 @@ pmd_mtr_policer_actions_update(struct rte_eth_dev *dev, /* MTR object stats read */ static void -mtr_stats_convert(struct softnic_mtr *m, +mtr_stats_convert(struct pmd_internals *p, + struct softnic_mtr *m, struct rte_table_action_mtr_counters_tc *in, struct rte_mtr_stats *out, uint64_t *out_mask) { + struct softnic_mtr_meter_policy *mp; + memset(&out, 0, sizeof(out)); *out_mask = 0; + /* Meter policy must exist */ + mp = softnic_mtr_meter_policy_find(p, m->params.meter_policy_id); + if (mp == NULL) + return; + if (in->n_packets_valid) { uint32_t i; for (i = 0; i < RTE_COLORS; i++) { - if (m->params.action[i] == MTR_POLICER_ACTION_COLOR_GREEN) + if (mp->policer[i] == + RTE_TABLE_ACTION_POLICER_COLOR_GREEN) out->n_pkts[RTE_COLOR_GREEN] += in->n_packets[i]; - if (m->params.action[i] == MTR_POLICER_ACTION_COLOR_YELLOW) + if (mp->policer[i] == + RTE_TABLE_ACTION_POLICER_COLOR_YELLOW) out->n_pkts[RTE_COLOR_YELLOW] += in->n_packets[i]; - if (m->params.action[i] == MTR_POLICER_ACTION_COLOR_RED) + if (mp->policer[i] == + RTE_TABLE_ACTION_POLICER_COLOR_RED) out->n_pkts[RTE_COLOR_RED] += in->n_packets[i]; - if (m->params.action[i] == MTR_POLICER_ACTION_DROP) + if (mp->policer[i] == + RTE_TABLE_ACTION_POLICER_DROP) out->n_pkts_dropped += in->n_packets[i]; } @@ -639,16 +769,20 @@ mtr_stats_convert(struct softnic_mtr *m, uint32_t i; for (i = 0; i < RTE_COLORS; i++) { - if (m->params.action[i] == MTR_POLICER_ACTION_COLOR_GREEN) + if (mp->policer[i] == + RTE_TABLE_ACTION_POLICER_COLOR_GREEN) out->n_bytes[RTE_COLOR_GREEN] += in->n_bytes[i]; - if (m->params.action[i] == MTR_POLICER_ACTION_COLOR_YELLOW) + if (mp->policer[i] == + RTE_TABLE_ACTION_POLICER_COLOR_YELLOW) out->n_bytes[RTE_COLOR_YELLOW] += in->n_bytes[i]; - if (m->params.action[i] == MTR_POLICER_ACTION_COLOR_RED) + if (mp->policer[i] == + RTE_TABLE_ACTION_POLICER_COLOR_RED) out->n_bytes[RTE_COLOR_RED] += in->n_bytes[i]; - if (m->params.action[i] == MTR_POLICER_ACTION_DROP) + if (mp->policer[i] == + RTE_TABLE_ACTION_POLICER_DROP) out->n_bytes_dropped += in->n_bytes[i]; } @@ -714,7 +848,8 @@ pmd_mtr_stats_read(struct rte_eth_dev *dev, struct rte_mtr_stats s; uint64_t s_mask = 0; - mtr_stats_convert(m, + mtr_stats_convert(p, + m, &counters.stats[0], &s, &s_mask); @@ -735,6 +870,9 @@ const struct rte_mtr_ops pmd_mtr_ops = { .meter_profile_add = pmd_mtr_meter_profile_add, .meter_profile_delete = pmd_mtr_meter_profile_delete, + .meter_policy_create = pmd_mtr_meter_policy_create, + .meter_policy_delete = pmd_mtr_meter_policy_delete, + .create = pmd_mtr_create, .destroy = pmd_mtr_destroy, .meter_enable = NULL, @@ -742,7 +880,7 @@ const struct rte_mtr_ops pmd_mtr_ops = { .meter_profile_update = pmd_mtr_meter_profile_update, .meter_dscp_table_update = pmd_mtr_meter_dscp_table_update, - .policer_actions_update = pmd_mtr_policer_actions_update, + .meter_policy_update = pmd_mtr_meter_policy_update, .stats_update = NULL, .stats_read = pmd_mtr_stats_read, diff --git a/lib/librte_ethdev/rte_flow.h b/lib/librte_ethdev/rte_flow.h index 6cc57136ac..d4fd36dd0e 100644 --- a/lib/librte_ethdev/rte_flow.h +++ b/lib/librte_ethdev/rte_flow.h @@ -32,6 +32,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { @@ -2267,6 +2268,14 @@ enum rte_flow_action_type { * See struct rte_flow_action_modify_field. */ RTE_FLOW_ACTION_TYPE_MODIFY_FIELD, + + /** + * Color the packet to reflect the meter color result. + * Set the meter color in the mbuf to the selected color. + * + * See struct rte_flow_action_meter_color. + */ + RTE_FLOW_ACTION_TYPE_METER_COLOR, }; /** @@ -2859,6 +2868,19 @@ struct rte_flow_action_set_dscp { */ struct rte_flow_shared_action; +/** + * @warning + * @b EXPERIMENTAL: this structure may change without prior notice + * + * RTE_FLOW_ACTION_TYPE_METER_COLOR + * + * The meter color should be set in the packet meta-data + * (i.e. struct rte_mbuf::sched::color). + */ +struct rte_flow_action_meter_color { + enum rte_color color; /**< Packet color. */ +}; + /** * Field IDs for MODIFY_FIELD action. */ diff --git a/lib/librte_ethdev/rte_mtr.c b/lib/librte_ethdev/rte_mtr.c index 3073ac03f2..9b03cf1d50 100644 --- a/lib/librte_ethdev/rte_mtr.c +++ b/lib/librte_ethdev/rte_mtr.c @@ -91,6 +91,40 @@ rte_mtr_meter_profile_delete(uint16_t port_id, meter_profile_id, error); } +/* MTR meter policy validate */ +int +rte_mtr_meter_policy_validate(uint16_t port_id, + struct rte_mtr_meter_policy_params *policy, + struct rte_mtr_error *error) +{ + struct rte_eth_dev *dev = &rte_eth_devices[port_id]; + return RTE_MTR_FUNC(port_id, meter_policy_validate)(dev, + policy, error); +} + +/* MTR meter policy create */ +int +rte_mtr_meter_policy_create(uint16_t port_id, + uint32_t policy_id, + struct rte_mtr_meter_policy_params *policy, + struct rte_mtr_error *error) +{ + struct rte_eth_dev *dev = &rte_eth_devices[port_id]; + return RTE_MTR_FUNC(port_id, meter_policy_create)(dev, + policy_id, policy, error); +} + +/** MTR meter policy delete */ +int +rte_mtr_meter_policy_delete(uint16_t port_id, + uint32_t policy_id, + struct rte_mtr_error *error) +{ + struct rte_eth_dev *dev = &rte_eth_devices[port_id]; + return RTE_MTR_FUNC(port_id, meter_policy_delete)(dev, + policy_id, error); +} + /** MTR object create */ int rte_mtr_create(uint16_t port_id, @@ -149,29 +183,28 @@ rte_mtr_meter_profile_update(uint16_t port_id, mtr_id, meter_profile_id, error); } -/** MTR object meter DSCP table update */ +/** MTR object meter policy update */ int -rte_mtr_meter_dscp_table_update(uint16_t port_id, +rte_mtr_meter_policy_update(uint16_t port_id, uint32_t mtr_id, - enum rte_color *dscp_table, + uint32_t meter_policy_id, struct rte_mtr_error *error) { struct rte_eth_dev *dev = &rte_eth_devices[port_id]; - return RTE_MTR_FUNC(port_id, meter_dscp_table_update)(dev, - mtr_id, dscp_table, error); + return RTE_MTR_FUNC(port_id, meter_policy_update)(dev, + mtr_id, meter_policy_id, error); } -/** MTR object policer action update */ +/** MTR object meter DSCP table update */ int -rte_mtr_policer_actions_update(uint16_t port_id, +rte_mtr_meter_dscp_table_update(uint16_t port_id, uint32_t mtr_id, - uint32_t action_mask, - enum rte_mtr_policer_action *actions, + enum rte_color *dscp_table, struct rte_mtr_error *error) { struct rte_eth_dev *dev = &rte_eth_devices[port_id]; - return RTE_MTR_FUNC(port_id, policer_actions_update)(dev, - mtr_id, action_mask, actions, error); + return RTE_MTR_FUNC(port_id, meter_dscp_table_update)(dev, + mtr_id, dscp_table, error); } /** MTR object enabled stats update */ diff --git a/lib/librte_ethdev/rte_mtr.h b/lib/librte_ethdev/rte_mtr.h index 916a09c5c3..9f6f5e1a45 100644 --- a/lib/librte_ethdev/rte_mtr.h +++ b/lib/librte_ethdev/rte_mtr.h @@ -49,6 +49,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { @@ -175,20 +176,16 @@ struct rte_mtr_meter_profile { }; /** - * Policer actions + * Meter policy */ -enum rte_mtr_policer_action { - /** Recolor the packet as green. */ - MTR_POLICER_ACTION_COLOR_GREEN = 0, - - /** Recolor the packet as yellow. */ - MTR_POLICER_ACTION_COLOR_YELLOW, - - /** Recolor the packet as red. */ - MTR_POLICER_ACTION_COLOR_RED, - - /** Drop the packet. */ - MTR_POLICER_ACTION_DROP, +struct rte_mtr_meter_policy_params { + /** + * Policy action list per color. + * actions[i] potentially represents a chain of rte_flow actions + * terminated by the END action, exactly as specified by the rte_flow + * API for the flow definition, and not just a single action. + */ + const struct rte_flow_action *actions[RTE_COLORS]; }; /** @@ -232,13 +229,13 @@ struct rte_mtr_params { */ int meter_enable; - /** Policer actions (per meter output color). */ - enum rte_mtr_policer_action action[RTE_COLORS]; - /** Set of stats counters to be enabled. * @see enum rte_mtr_stats_type */ uint64_t stats_mask; + + /** Meter policy ID. */ + uint32_t meter_policy_id; }; /** @@ -324,6 +321,13 @@ struct rte_mtr_capabilities { */ uint64_t meter_rate_max; + /** + * Maximum number of policy objects that can have. + * The value of 0 is invalid. Policy must be supported for meter. + * The maximum value is *n_max*. + */ + uint64_t meter_policy_n_max; + /** * When non-zero, it indicates that color aware mode is supported for * the srTCM RFC 2697 metering algorithm. @@ -342,18 +346,6 @@ struct rte_mtr_capabilities { */ int color_aware_trtcm_rfc4115_supported; - /** When non-zero, it indicates that the policer packet recolor actions - * are supported. - * @see enum rte_mtr_policer_action - */ - int policer_action_recolor_supported; - - /** When non-zero, it indicates that the policer packet drop action is - * supported. - * @see enum rte_mtr_policer_action - */ - int policer_action_drop_supported; - /** Set of supported statistics counter types. * @see enum rte_mtr_stats_type */ @@ -379,6 +371,8 @@ enum rte_mtr_error_type { RTE_MTR_ERROR_TYPE_STATS_MASK, RTE_MTR_ERROR_TYPE_STATS, RTE_MTR_ERROR_TYPE_SHARED, + RTE_MTR_ERROR_TYPE_METER_POLICY_ID, + RTE_MTR_ERROR_TYPE_METER_POLICY, }; /** @@ -462,6 +456,136 @@ rte_mtr_meter_profile_delete(uint16_t port_id, uint32_t meter_profile_id, struct rte_mtr_error *error); +/** + * Check whether a meter policy can be created on a given port. + * + * The meter policy is validated for correctness and + * whether it could be accepted by the device given sufficient resources. + * The policy is checked against the current capability information + * meter_policy_n_max configuration. + * The policy may also optionally be validated against existing + * device policy resources. + * This function has no effect on the target device. + * + * @param[in] port_id + * The port identifier of the Ethernet device. + * @param[in] policy + * Associated action list per color. + * list NULL is legal and means no special action. + * (list terminated by the END action). + * @param[out] error + * Error details. Filled in only on error, when not NULL. + * @return + * 0 on success, non-zero error code otherwise. + */ +__rte_experimental +int +rte_mtr_meter_policy_validate(uint16_t port_id, + struct rte_mtr_meter_policy_params *policy, + struct rte_mtr_error *error); + +/** + * Meter policy add + * + * Create a new meter policy. The new policy + * is used to create single or multiple MTR objects. + * + * Two common examples to define meter policy action list: + * Example #1: GREEN - GREEN, YELLOW - YELLOW, RED - RED + * struct rte_mtr_meter_policy_params policy_0 = + * (struct rte_mtr_meter_policy_params) { + * .actions[RTE_COLOR_GREEN] = (struct rte_flow_action[]) { + * { + * .type = RTE_FLOW_ACTION_TYPE_METER_COLOR, + * .conf = &(struct rte_flow_action_meter_color) { + * .color = RTE_COLOR_GREEN, + * }, + * }, + * { + * .type = RTE_FLOW_ACTION_TYPE_END, + * }, + * }, + * .actions[RTE_COLOR_YELLOW] = (struct rte_flow_action[]) { + * { + * .type = RTE_FLOW_ACTION_TYPE_METER_COLOR, + * .conf = &(struct rte_flow_action_meter_color) { + * .color = RTE_COLOR_YELLOW, + * }, + * }, + * { + * .type = RTE_FLOW_ACTION_TYPE_END, + * }, + * }, + * .actions[RTE_COLOR_RED] = (struct rte_flow_action[]) { + * { + * .type = RTE_FLOW_ACTION_TYPE_METER_COLOR, + * .conf = &(struct rte_flow_action_meter_color) { + * .color = RTE_COLOR_RED, + * }, + * }, + * { + * .type = RTE_FLOW_ACTION_TYPE_END, + * }, + * }, + * }; + * + * Example #2: GREEN - Do nothing, YELLOW - Do nothing, RED - DROP + * struct rte_mtr_meter_policy_params policy_1 = + * (struct rte_mtr_meter_policy_params) { + * .actions[RTE_COLOR_GREEN] = NULL, + * .actions[RTE_COLOR_YELLOW] = NULL, + * .actions[RTE_COLOR_RED] = (struct rte_flow_action[]) { + * { + * .type = RTE_FLOW_ACTION_TYPE_DROP, + * }, + * { + * .type = RTE_FLOW_ACTION_TYPE_END, + * }, + * }, + * }; + * + * @param[in] port_id + * The port identifier of the Ethernet device. + * @param[in] policy_id + * Policy identifier for the new meter policy. + * @param[in] policy + * Associated actions per color. + * list NULL is legal and means no special action. + * Non-NULL list must be terminated. + * (list terminated by the END action). + * @param[out] error + * Error details. Filled in only on error, when not NULL. + * @return + * 0 on success, non-zero error code otherwise. + */ +__rte_experimental +int +rte_mtr_meter_policy_create(uint16_t port_id, + uint32_t policy_id, + struct rte_mtr_meter_policy_params *policy, + struct rte_mtr_error *error); + +/** + * Meter policy delete + * + * Delete an existing meter policy. This operation fails when there is + * currently at least one user (i.e. MTR object) of this policy. + * + * @param[in] port_id + * The port identifier of the Ethernet device. + * @param[in] policy_id + * Policy identifier. + * @param[out] error + * Error details. Filled in only on error, when not NULL. + * @return + * 0 on success, non-zero error code otherwise. + */ +__rte_experimental +int +rte_mtr_meter_policy_delete(uint16_t port_id, + uint32_t policy_id, + struct rte_mtr_error *error); + /** * MTR object create * @@ -587,18 +711,14 @@ rte_mtr_meter_profile_update(uint16_t port_id, struct rte_mtr_error *error); /** - * MTR object DSCP table update + * MTR object meter policy update * * @param[in] port_id * The port identifier of the Ethernet device. * @param[in] mtr_id * MTR object ID. Needs to be valid. - * @param[in] dscp_table - * When non-NULL: it points to a pre-allocated and pre-populated table with - * exactly 64 elements providing the input color for each value of the - * IPv4/IPv6 Differentiated Services Code Point (DSCP) input packet field. - * When NULL: it is equivalent to setting this parameter to an “all-green” - * populated table (i.e. table with all the 64 elements set to green color). + * @param[in] meter_policy_id + * Meter policy ID for the current MTR object. Needs to be valid. * @param[out] error * Error details. Filled in only on error, when not NULL. * @return @@ -606,26 +726,24 @@ rte_mtr_meter_profile_update(uint16_t port_id, */ __rte_experimental int -rte_mtr_meter_dscp_table_update(uint16_t port_id, +rte_mtr_meter_policy_update(uint16_t port_id, uint32_t mtr_id, - enum rte_color *dscp_table, + uint32_t meter_policy_id, struct rte_mtr_error *error); /** - * MTR object policer actions update + * MTR object DSCP table update * * @param[in] port_id * The port identifier of the Ethernet device. * @param[in] mtr_id * MTR object ID. Needs to be valid. - * @param[in] action_mask - * Bit mask indicating which policer actions need to be updated. One or more - * policer actions can be updated in a single function invocation. To update - * the policer action associated with color C, bit (1 << C) needs to be set in - * *action_mask* and element at position C in the *actions* array needs to be - * valid. - * @param[in] actions - * Pre-allocated and pre-populated array of policer actions. + * @param[in] dscp_table + * When non-NULL: it points to a pre-allocated and pre-populated table with + * exactly 64 elements providing the input color for each value of the + * IPv4/IPv6 Differentiated Services Code Point (DSCP) input packet field. + * When NULL: it is equivalent to setting this parameter to an “all-green” + * populated table (i.e. table with all the 64 elements set to green color). * @param[out] error * Error details. Filled in only on error, when not NULL. * @return @@ -633,10 +751,9 @@ rte_mtr_meter_dscp_table_update(uint16_t port_id, */ __rte_experimental int -rte_mtr_policer_actions_update(uint16_t port_id, +rte_mtr_meter_dscp_table_update(uint16_t port_id, uint32_t mtr_id, - uint32_t action_mask, - enum rte_mtr_policer_action *actions, + enum rte_color *dscp_table, struct rte_mtr_error *error); /** diff --git a/lib/librte_ethdev/rte_mtr_driver.h b/lib/librte_ethdev/rte_mtr_driver.h index a0ddc2b5f4..462a1e862c 100644 --- a/lib/librte_ethdev/rte_mtr_driver.h +++ b/lib/librte_ethdev/rte_mtr_driver.h @@ -41,6 +41,22 @@ typedef int (*rte_mtr_meter_profile_delete_t)(struct rte_eth_dev *dev, struct rte_mtr_error *error); /**< @internal MTR meter profile delete */ +typedef int (*rte_mtr_meter_policy_validate_t)(struct rte_eth_dev *dev, + struct rte_mtr_meter_policy_params *policy, + struct rte_mtr_error *error); +/**< @internal MTR meter policy validate */ + +typedef int (*rte_mtr_meter_policy_create_t)(struct rte_eth_dev *dev, + uint32_t policy_id, + struct rte_mtr_meter_policy_params *policy, + struct rte_mtr_error *error); +/**< @internal MTR meter policy add */ + +typedef int (*rte_mtr_meter_policy_delete_t)(struct rte_eth_dev *dev, + uint32_t policy_id, + struct rte_mtr_error *error); +/**< @internal MTR meter policy delete */ + typedef int (*rte_mtr_create_t)(struct rte_eth_dev *dev, uint32_t mtr_id, struct rte_mtr_params *params, @@ -69,18 +85,17 @@ typedef int (*rte_mtr_meter_profile_update_t)(struct rte_eth_dev *dev, struct rte_mtr_error *error); /**< @internal MTR object meter profile update */ -typedef int (*rte_mtr_meter_dscp_table_update_t)(struct rte_eth_dev *dev, +typedef int (*rte_mtr_meter_policy_update_t)(struct rte_eth_dev *dev, uint32_t mtr_id, - enum rte_color *dscp_table, + uint32_t meter_policy_id, struct rte_mtr_error *error); -/**< @internal MTR object meter DSCP table update */ +/**< @internal MTR object meter policy update */ -typedef int (*rte_mtr_policer_actions_update_t)(struct rte_eth_dev *dev, +typedef int (*rte_mtr_meter_dscp_table_update_t)(struct rte_eth_dev *dev, uint32_t mtr_id, - uint32_t action_mask, - enum rte_mtr_policer_action *actions, + enum rte_color *dscp_table, struct rte_mtr_error *error); -/**< @internal MTR object policer action update*/ +/**< @internal MTR object meter DSCP table update */ typedef int (*rte_mtr_stats_update_t)(struct rte_eth_dev *dev, uint32_t mtr_id, @@ -124,14 +139,23 @@ struct rte_mtr_ops { /** MTR object meter DSCP table update */ rte_mtr_meter_dscp_table_update_t meter_dscp_table_update; - /** MTR object policer action update */ - rte_mtr_policer_actions_update_t policer_actions_update; - /** MTR object enabled stats update */ rte_mtr_stats_update_t stats_update; /** MTR object stats read */ rte_mtr_stats_read_t stats_read; + + /** MTR meter policy validate */ + rte_mtr_meter_policy_validate_t meter_policy_validate; + + /** MTR meter policy create */ + rte_mtr_meter_policy_create_t meter_policy_create; + + /** MTR meter policy delete */ + rte_mtr_meter_policy_delete_t meter_policy_delete; + + /** MTR object meter policy update */ + rte_mtr_meter_policy_update_t meter_policy_update; }; /** diff --git a/lib/librte_ethdev/version.map b/lib/librte_ethdev/version.map index 93ad388e96..0045baff8c 100644 --- a/lib/librte_ethdev/version.map +++ b/lib/librte_ethdev/version.map @@ -138,7 +138,6 @@ EXPERIMENTAL { rte_mtr_meter_profile_add; rte_mtr_meter_profile_delete; rte_mtr_meter_profile_update; - rte_mtr_policer_actions_update; rte_mtr_stats_read; rte_mtr_stats_update; @@ -246,6 +245,10 @@ EXPERIMENTAL { # added in 21.05 rte_eth_representor_info_get; + rte_mtr_meter_policy_create; + rte_mtr_meter_policy_delete; + rte_mtr_meter_policy_update; + rte_mtr_meter_policy_validate; }; INTERNAL {