net/mlx5: fix use of atomic cmpset for age state
authorDekel Peled <dekelp@nvidia.com>
Thu, 15 Oct 2020 11:44:24 +0000 (14:44 +0300)
committerFerruh Yigit <ferruh.yigit@intel.com>
Tue, 3 Nov 2020 21:29:25 +0000 (22:29 +0100)
According to documentation [1], function rte_atomic16_cmpset()
return value is non-zero on success; 0 on failure.
In existing code this function is called, and the return value
is compared to AGE_CANDIDATE, which is defined as 1.
Such comparison is incorrect and can lead to unwanted behavior.

This patch updates the calls to rte_atomic16_cmpset(), to check
that the return value is 0 or non-zero.

[1] https://doc.dpdk.org/api/rte__atomic_8h.html

Fixes: fa2d01c87d2b ("net/mlx5: support flow aging")
Cc: stable@dpdk.org
Signed-off-by: Dekel Peled <dekelp@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
drivers/net/mlx5/mlx5_flow.c
drivers/net/mlx5/mlx5_flow_dv.c

index a51a0a8..8faa83e 100644 (file)
@@ -6771,12 +6771,8 @@ mlx5_flow_aging_check(struct mlx5_dev_ctx_shared *sh,
                priv = rte_eth_devices[age_param->port_id].data->dev_private;
                age_info = GET_PORT_AGE_INFO(priv);
                rte_spinlock_lock(&age_info->aged_sl);
-               /* If the cpmset fails, release happens. */
-               if (rte_atomic16_cmpset((volatile uint16_t *)
-                                       &age_param->state,
-                                       AGE_CANDIDATE,
-                                       AGE_TMOUT) ==
-                                       AGE_CANDIDATE) {
+               if (rte_atomic16_cmpset((volatile uint16_t *)&age_param->state,
+                                       AGE_CANDIDATE, AGE_TMOUT)) {
                        TAILQ_INSERT_TAIL(&age_info->aged_counters, cnt, next);
                        MLX5_AGE_SET(age_info, MLX5_AGE_EVENT_NEW);
                }
index 06c8b08..b7ad847 100644 (file)
@@ -5332,10 +5332,8 @@ flow_dv_counter_remove_from_age(struct rte_eth_dev *dev,
 
        age_info = GET_PORT_AGE_INFO(priv);
        age_param = flow_dv_counter_idx_get_age(dev, counter);
-       if (rte_atomic16_cmpset((volatile uint16_t *)
-                       &age_param->state,
-                       AGE_CANDIDATE, AGE_FREE)
-                       != AGE_CANDIDATE) {
+       if (!rte_atomic16_cmpset((volatile uint16_t *)&age_param->state,
+                                AGE_CANDIDATE, AGE_FREE)) {
                /**
                 * We need the lock even it is age timeout,
                 * since counter may still in process.
@@ -5343,9 +5341,10 @@ flow_dv_counter_remove_from_age(struct rte_eth_dev *dev,
                rte_spinlock_lock(&age_info->aged_sl);
                TAILQ_REMOVE(&age_info->aged_counters, cnt, next);
                rte_spinlock_unlock(&age_info->aged_sl);
+               rte_atomic16_set(&age_param->state, AGE_FREE);
        }
-       rte_atomic16_set(&age_param->state, AGE_FREE);
 }
+
 /**
  * Release a flow counter.
  *