net/mlx5: fix age action pool protection
The age action with flows creation could be supported on the multiple threads. The age pools were created to manage the age resources, if there is no room in the current pool then resize the age pool to the new pool size and free the old one. There's a race condition while one thread resizes the age pool and the old pool resource be freed, and another thread query the age action value of the old pool so the queried value is invalid. This patch uses the read-write lock to protect the pool resource while resizing and query. Fixes: a5835d530f00 ("net/mlx5: optimize Rx queue match") Cc: stable@dpdk.org Signed-off-by: Jiawei Wang <jiaweiw@nvidia.com> Acked-by: Matan Azrad <matan@nvidia.com>
This commit is contained in:
parent
cbf4cfa8f6
commit
7cf2d15a39
@ -450,7 +450,7 @@ mlx5_flow_aso_age_mng_init(struct mlx5_dev_ctx_shared *sh)
|
||||
mlx5_free(sh->aso_age_mng);
|
||||
return -1;
|
||||
}
|
||||
rte_spinlock_init(&sh->aso_age_mng->resize_sl);
|
||||
rte_rwlock_init(&sh->aso_age_mng->resize_rwl);
|
||||
rte_spinlock_init(&sh->aso_age_mng->free_sl);
|
||||
LIST_INIT(&sh->aso_age_mng->free);
|
||||
return 0;
|
||||
|
@ -549,7 +549,7 @@ struct mlx5_aso_age_mng {
|
||||
struct mlx5_aso_age_pool **pools;
|
||||
uint16_t n; /* Total number of pools. */
|
||||
uint16_t next; /* Number of pools in use, index of next free pool. */
|
||||
rte_spinlock_t resize_sl; /* Lock for resize objects. */
|
||||
rte_rwlock_t resize_rwl; /* Lock for resize objects. */
|
||||
rte_spinlock_t free_sl; /* Lock for free list access. */
|
||||
struct aso_age_list free; /* Free age actions list - ready to use. */
|
||||
struct mlx5_aso_sq aso_sq; /* ASO queue objects. */
|
||||
|
@ -3675,8 +3675,11 @@ flow_aso_age_get_by_idx(struct rte_eth_dev *dev, uint32_t age_idx)
|
||||
uint16_t offset = (age_idx >> 16) & UINT16_MAX;
|
||||
struct mlx5_priv *priv = dev->data->dev_private;
|
||||
struct mlx5_aso_age_mng *mng = priv->sh->aso_age_mng;
|
||||
struct mlx5_aso_age_pool *pool = mng->pools[pool_idx];
|
||||
struct mlx5_aso_age_pool *pool;
|
||||
|
||||
rte_rwlock_read_lock(&mng->resize_rwl);
|
||||
pool = mng->pools[pool_idx];
|
||||
rte_rwlock_read_unlock(&mng->resize_rwl);
|
||||
return &pool->actions[offset - 1];
|
||||
}
|
||||
|
||||
|
@ -417,9 +417,9 @@ mlx5_aso_sq_enqueue_burst(struct mlx5_aso_age_mng *mng, uint16_t n)
|
||||
wqe = &sq->sq_obj.aso_wqes[sq->head & mask];
|
||||
rte_prefetch0(&sq->sq_obj.aso_wqes[(sq->head + 1) & mask]);
|
||||
/* Fill next WQE. */
|
||||
rte_spinlock_lock(&mng->resize_sl);
|
||||
rte_rwlock_read_lock(&mng->resize_rwl);
|
||||
pool = mng->pools[sq->next];
|
||||
rte_spinlock_unlock(&mng->resize_sl);
|
||||
rte_rwlock_read_unlock(&mng->resize_rwl);
|
||||
sq->elts[sq->head & mask].pool = pool;
|
||||
wqe->general_cseg.misc =
|
||||
rte_cpu_to_be_32(((struct mlx5_devx_obj *)
|
||||
@ -635,9 +635,9 @@ mlx5_flow_aso_alarm(void *arg)
|
||||
uint32_t us = 100u;
|
||||
uint16_t n;
|
||||
|
||||
rte_spinlock_lock(&sh->aso_age_mng->resize_sl);
|
||||
rte_rwlock_read_lock(&sh->aso_age_mng->resize_rwl);
|
||||
n = sh->aso_age_mng->next;
|
||||
rte_spinlock_unlock(&sh->aso_age_mng->resize_sl);
|
||||
rte_rwlock_read_unlock(&sh->aso_age_mng->resize_rwl);
|
||||
mlx5_aso_completion_handle(sh);
|
||||
if (sq->next == n) {
|
||||
/* End of loop: wait 1 second. */
|
||||
|
@ -11857,18 +11857,18 @@ flow_dv_age_pool_create(struct rte_eth_dev *dev,
|
||||
}
|
||||
pool->flow_hit_aso_obj = obj;
|
||||
pool->time_of_last_age_check = MLX5_CURR_TIME_SEC;
|
||||
rte_spinlock_lock(&mng->resize_sl);
|
||||
rte_rwlock_write_lock(&mng->resize_rwl);
|
||||
pool->index = mng->next;
|
||||
/* Resize pools array if there is no room for the new pool in it. */
|
||||
if (pool->index == mng->n && flow_dv_aso_age_pools_resize(dev)) {
|
||||
claim_zero(mlx5_devx_cmd_destroy(obj));
|
||||
mlx5_free(pool);
|
||||
rte_spinlock_unlock(&mng->resize_sl);
|
||||
rte_rwlock_write_unlock(&mng->resize_rwl);
|
||||
return NULL;
|
||||
}
|
||||
mng->pools[pool->index] = pool;
|
||||
mng->next++;
|
||||
rte_spinlock_unlock(&mng->resize_sl);
|
||||
rte_rwlock_write_unlock(&mng->resize_rwl);
|
||||
/* Assign the first action in the new pool, the rest go to free list. */
|
||||
*age_free = &pool->actions[0];
|
||||
for (i = 1; i < MLX5_ASO_AGE_ACTIONS_PER_POOL; i++) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user