* Attach meter to flow. * Unidirectional Meter creation can only be done * when flow direction is known, i.e. when calling meter_attach. * * @param [in] priv * Pointer to mlx5 private data. * @param[in] fm * Pointer to flow meter. * @param [in] attr * Pointer to flow attributes. * @param [out] error * Pointer to error structure. * * @return * 0 on success, a negative errno val
| 2109 | * 0 on success, a negative errno value otherwise and rte_errno is set. |
| 2110 | */ |
| 2111 | int |
| 2112 | mlx5_flow_meter_attach(struct mlx5_priv *priv, |
| 2113 | struct mlx5_flow_meter_info *fm, |
| 2114 | const struct rte_flow_attr *attr, |
| 2115 | struct rte_flow_error *error) |
| 2116 | { |
| 2117 | int ret = 0; |
| 2118 | |
| 2119 | if (priv->sh->meter_aso_en) { |
| 2120 | struct mlx5_aso_mtr *aso_mtr; |
| 2121 | |
| 2122 | aso_mtr = container_of(fm, struct mlx5_aso_mtr, fm); |
| 2123 | if (mlx5_aso_mtr_wait(priv, aso_mtr, false)) { |
| 2124 | return rte_flow_error_set(error, ENOENT, |
| 2125 | RTE_FLOW_ERROR_TYPE_UNSPECIFIED, |
| 2126 | NULL, |
| 2127 | "Timeout in meter configuration"); |
| 2128 | } |
| 2129 | rte_spinlock_lock(&fm->sl); |
| 2130 | if (fm->shared || !fm->ref_cnt) { |
| 2131 | fm->ref_cnt++; |
| 2132 | } else { |
| 2133 | rte_flow_error_set(error, EINVAL, |
| 2134 | RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, |
| 2135 | "Meter cannot be shared"); |
| 2136 | ret = -1; |
| 2137 | } |
| 2138 | rte_spinlock_unlock(&fm->sl); |
| 2139 | } else { |
| 2140 | rte_spinlock_lock(&fm->sl); |
| 2141 | if (fm->meter_action_g) { |
| 2142 | if (fm->shared && |
| 2143 | attr->transfer == fm->transfer && |
| 2144 | attr->ingress == fm->ingress && |
| 2145 | attr->egress == fm->egress) { |
| 2146 | fm->ref_cnt++; |
| 2147 | } else { |
| 2148 | rte_flow_error_set(error, EINVAL, |
| 2149 | RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, |
| 2150 | fm->shared ? |
| 2151 | "Meter attr not match." : |
| 2152 | "Meter cannot be shared."); |
| 2153 | ret = -1; |
| 2154 | } |
| 2155 | } else { |
| 2156 | fm->ingress = attr->ingress; |
| 2157 | fm->egress = attr->egress; |
| 2158 | fm->transfer = attr->transfer; |
| 2159 | fm->ref_cnt = 1; |
| 2160 | /* This also creates the meter object. */ |
| 2161 | fm->meter_action_g = mlx5_flow_meter_action_create(priv, |
| 2162 | fm); |
| 2163 | if (!fm->meter_action_g) { |
| 2164 | fm->ref_cnt = 0; |
| 2165 | fm->ingress = 0; |
| 2166 | fm->egress = 0; |
| 2167 | fm->transfer = 0; |
| 2168 | rte_flow_error_set(error, EINVAL, |
no test coverage detected