ethdev: add pre-defined meter policy API
authorLi Zhang <lizh@nvidia.com>
Tue, 20 Apr 2021 14:04:49 +0000 (17:04 +0300)
committerFerruh Yigit <ferruh.yigit@intel.com>
Wed, 21 Apr 2021 10:22:17 +0000 (12:22 +0200)
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.

Add two common policy template as macros in the head file.

The next API function were added:
- rte_mtr_meter_policy_add
- 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. Supports 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 <lizh@nvidia.com>
Signed-off-by: Haifei Luo <haifeil@nvidia.com>
Signed-off-by: Jiawei Wang <jiaweiw@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
Acked-by: Ray Kinsella <mdr@ashroe.eu>
Acked-by: Ori Kam <orika@nvidia.com>
Acked-by: Jasvinder Singh <jasvinder.singh@intel.com>
Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
Acked-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
22 files changed:
app/test-flow-perf/main.c
app/test-pmd/cmdline.c
app/test-pmd/cmdline_mtr.c
app/test-pmd/cmdline_mtr.h
doc/guides/prog_guide/rte_flow.rst
doc/guides/prog_guide/traffic_metering_and_policing.rst
doc/guides/rel_notes/release_21_05.rst
doc/guides/testpmd_app_ug/testpmd_funcs.rst
drivers/net/mlx5/mlx5.h
drivers/net/mlx5/mlx5_flow.c
drivers/net/mlx5/mlx5_flow.h
drivers/net/mlx5/mlx5_flow_aso.c
drivers/net/mlx5/mlx5_flow_dv.c
drivers/net/mlx5/mlx5_flow_meter.c
drivers/net/softnic/rte_eth_softnic_flow.c
drivers/net/softnic/rte_eth_softnic_internals.h
drivers/net/softnic/rte_eth_softnic_meter.c
lib/ethdev/rte_flow.h
lib/ethdev/rte_mtr.c
lib/ethdev/rte_mtr.h
lib/ethdev/rte_mtr_driver.h
lib/ethdev/version.map

index 8e22967..9be8edc 100644 (file)
@@ -928,13 +928,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, &params, 1, &error);
        if (ret != 0) {
                printf("Port %u create meter idx(%d) error(%d) message: %s\n",
index d282c7c..21c2c1d 100644 (file)
@@ -17427,7 +17427,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,
index 4d9bfde..aa454af 100644 (file)
@@ -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.srtcm_rfc2697_byte_mode_supported %" PRId32 "\n",
                cap.srtcm_rfc2697_byte_mode_supported);
        printf("cap.srtcm_rfc2697_packet_mode_supported %" PRId32 "\n",
@@ -842,12 +791,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, &params, shared, &error);
@@ -1215,121 +1158,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 <port_id> <mtr_id> "
-               "<action_mask> <action0> [<action1> <action2>]",
-       .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;
index e69d6da..7e2713c 100644 (file)
@@ -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;
 
index 1a70dde..1bacbdc 100644 (file)
@@ -2982,6 +2982,27 @@ The current conntrack context information could be queried via the
    | ``reserved``   | reserved bits                                   |
    +----------------+-------------------------------------------------+
 
+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
 ~~~~~~~~~~~~~~
 
index 90c781e..c0537e6 100644 (file)
@@ -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
index b136f1f..1cb002b 100644 (file)
@@ -88,11 +88,12 @@ New Features
   * Added new field ``queue_state`` to ``rte_eth_txq_info`` structure to
     provide indicated Tx queue state.
 
-* **Added support for meter PPS profile.**
+* **Updated meter API.**
 
-  Added packet mode in the meter profile parameters data structures
-  to support metering traffic by packet per second (PPS),
-  in addition to the initial bytes per second (BPS) mode (value 0).
+  * Added packet mode in the meter profile parameters data structures
+    to support metering traffic by packet per second (PPS),
+    in addition to the initial bytes per second (BPS) mode (value 0).
+  * Added support of pre-defined meter policy via flow action list per color.
 
 * **Added packet integrity match to flow rules.**
 
@@ -308,6 +309,11 @@ API Changes
   The action ``RTE_FLOW_ACTION_TYPE_SHARED`` is deprecated and can be
   replaced with ``RTE_FLOW_ACTION_TYPE_INDIRECT``.
 
+* ethdev: The experimental function ``rte_mtr_policer_actions_update()``,
+  the enum ``rte_mtr_policer_action``, and the struct members
+  ``policer_action_recolor_supported`` and ``policer_action_drop_supported``
+  have been removed.
+
 
 ABI Changes
 -----------
index c0cbc40..ac2c0d6 100644 (file)
@@ -2831,24 +2831,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
 ~~~~~~~~~~~~~~~~~~~~~~~~~
 
index 55ff17a..c9bc45c 100644 (file)
@@ -593,14 +593,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;
@@ -639,24 +631,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;
@@ -691,8 +671,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;
index bed8f31..05d86b5 100644 (file)
@@ -6655,52 +6655,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.
  *
index 1a74b17..5c80dc8 100644 (file)
@@ -838,6 +838,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. */
 };
 
@@ -1096,14 +1098,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,
@@ -1160,8 +1154,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;
@@ -1391,12 +1383,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);
index cd2cc01..62d2df0 100644 (file)
@@ -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;
 }
index ffd9f63..4fdcfce 100644 (file)
@@ -185,31 +185,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. */
@@ -6026,12 +6001,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;
 }
@@ -6055,7 +6028,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);
 }
@@ -6095,8 +6067,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
@@ -13721,433 +13693,6 @@ error_exit:
        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.
  *
@@ -14442,8 +13987,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,
index 714b382..af0a1c1 100644 (file)
@@ -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.");
index 7925bad..27eaf38 100644 (file)
@@ -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;
index faf90a5..1b3186e 100644 (file)
@@ -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
  */
index b27b128..acb8b87 100644 (file)
@@ -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,
@@ -208,6 +187,160 @@ 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 add */
+static int
+pmd_mtr_meter_policy_add(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;
+       bool valid_act_found;
+
+       if (policy == NULL)
+               return -rte_mtr_error_set(error,
+                       EINVAL,
+                       RTE_MTR_ERROR_TYPE_METER_POLICY,
+                       NULL,
+                       "Null meter policy invalid");
+
+       /* Meter policy must not 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 already exists");
+
+       for (i = 0; i < RTE_COLORS; i++) {
+               if (policy->actions[i] == NULL)
+                       return -rte_mtr_error_set(error,
+                               EINVAL,
+                               RTE_MTR_ERROR_TYPE_METER_POLICY,
+                               NULL,
+                               "Null action list");
+               for (act = policy->actions[i], valid_act_found = false;
+                    act->type != RTE_FLOW_ACTION_TYPE_END; act++) {
+                       if (act->type == RTE_FLOW_ACTION_TYPE_VOID)
+                               continue;
+                       /*
+                        * Support one (and one only) of
+                        * METER_COLOR or DROP action.
+                        */
+                       if ((act->type != RTE_FLOW_ACTION_TYPE_METER_COLOR &&
+                               act->type != RTE_FLOW_ACTION_TYPE_DROP) ||
+                               valid_act_found)
+                               return -rte_mtr_error_set(error,
+                                       EINVAL,
+                                       RTE_MTR_ERROR_TYPE_METER_POLICY,
+                                       NULL,
+                                       "Action invalid");
+                       valid_act_found = true;
+               }
+               if (!valid_act_found)
+                       return -rte_mtr_error_set(error,
+                               EINVAL,
+                               RTE_MTR_ERROR_TYPE_METER_POLICY,
+                               NULL,
+                               "No valid action found");
+       }
+
+       /* 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)
 {
@@ -275,6 +408,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;
 
@@ -292,6 +426,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)
@@ -310,6 +454,7 @@ pmd_mtr_create(struct rte_eth_dev *dev,
 
        /* Update dependencies */
        mp->n_users++;
+       policy->n_users++;
 
        return 0;
 }
@@ -324,6 +469,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);
@@ -351,8 +497,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);
@@ -514,18 +670,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);
@@ -536,28 +692,17 @@ pmd_mtr_policer_actions_update(struct rte_eth_dev *dev,
                        NULL,
                        "MTR object id not valid");
 
-       /* Valid policer actions */
-       if (actions == NULL)
+       if (m->params.meter_policy_id == meter_policy_id)
+               return 0;
+
+       /* 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) {
@@ -569,9 +714,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,
@@ -595,10 +738,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;
 }
@@ -615,28 +768,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];
                }
 
@@ -647,16 +812,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];
                }
 
@@ -722,7 +891,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);
@@ -743,6 +913,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_add = pmd_mtr_meter_policy_add,
+       .meter_policy_delete = pmd_mtr_meter_policy_delete,
+
        .create = pmd_mtr_create,
        .destroy = pmd_mtr_destroy,
        .meter_enable = NULL,
@@ -750,7 +923,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,
index c16f5ba..94c8c1c 100644 (file)
@@ -33,6 +33,7 @@
 #include <rte_bitops.h>
 #include <rte_mbuf.h>
 #include <rte_mbuf_dyn.h>
+#include <rte_meter.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -2392,6 +2393,14 @@ enum rte_flow_action_type {
         * @see struct rte_flow_action_conntrack.
         */
        RTE_FLOW_ACTION_TYPE_CONNTRACK,
+
+       /**
+        * 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,
 };
 
 /**
@@ -3138,6 +3147,19 @@ struct rte_flow_modify_conntrack {
        uint32_t reserved:30;
 };
 
+/**
+ * @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.
  */
index 3073ac0..e49fcf2 100644 (file)
@@ -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 add */
+int
+rte_mtr_meter_policy_add(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_add)(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 */
index ceb5dcb..dc246dd 100644 (file)
@@ -49,6 +49,7 @@
 #include <rte_compat.h>
 #include <rte_common.h>
 #include <rte_meter.h>
+#include <rte_flow.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -200,20 +201,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];
 };
 
 /**
@@ -257,13 +254,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;
 };
 
 /**
@@ -349,6 +346,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.
@@ -367,18 +371,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;
-
        /**
         * srTCM rfc2697 byte mode supported.
         * When non-zero, it indicates that byte mode is supported for
@@ -447,6 +439,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,
 };
 
 /**
@@ -530,6 +524,144 @@ 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.
+ * The same policy can be used to create multiple MTR objects.
+ *
+ * @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_add(uint16_t port_id,
+       uint32_t policy_id,
+       struct rte_mtr_meter_policy_params *policy,
+       struct rte_mtr_error *error);
+
+/**
+ * Define meter policy action list:
+ * GREEN - GREEN, YELLOW - YELLOW, RED - RED
+ */
+#define rte_mtr_policy_pass_color(policy) \
+struct rte_mtr_meter_policy_params policy = \
+{ \
+       .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, \
+               }, \
+       }, \
+}
+
+/**
+ * Define meter policy action list:
+ * GREEN - Do nothing, YELLOW - Do nothing, RED - DROP
+ */
+#define rte_mtr_policy_drop_red(policy) \
+struct rte_mtr_meter_policy_params policy = \
+{ \
+       .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, \
+               }, \
+       }, \
+}
+
+/**
+ * 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
  *
@@ -655,18 +787,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
@@ -674,26 +802,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
@@ -701,10 +827,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);
 
 /**
index a0ddc2b..62273ed 100644 (file)
@@ -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_add_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 add */
+       rte_mtr_meter_policy_add_t meter_policy_add;
+
+       /** 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;
 };
 
 /**
index 4eb561a..44d30b0 100644 (file)
@@ -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 {
        rte_flow_action_handle_destroy;
        rte_flow_action_handle_update;
        rte_flow_action_handle_query;
+       rte_mtr_meter_policy_add;
+       rte_mtr_meter_policy_delete;
+       rte_mtr_meter_policy_update;
+       rte_mtr_meter_policy_validate;
 };
 
 INTERNAL {