net/mlx5: DR, No need for atomic refcount for internal SW steering resources
[ Upstream commit 4ce380ca477507e2f413584cdd99e1698d6682d6 ]
No need for an atomic refcounter for the STE and hashtables.
These are internal SW steering resources and they are always
under domain mutex.
This also fixes the following refcount error:
refcount_t: addition on 0; use-after-free.
WARNING: CPU: 9 PID: 3527 at lib/refcount.c:25 refcount_warn_saturate+0x81/0xe0
Call Trace:
dr_table_init_nic+0x10d/0x110 [mlx5_core]
mlx5dr_table_create+0xb4/0x230 [mlx5_core]
mlx5_cmd_dr_create_flow_table+0x39/0x120 [mlx5_core]
__mlx5_create_flow_table+0x221/0x5f0 [mlx5_core]
esw_create_offloads_fdb_tables+0x180/0x5a0 [mlx5_core]
...
Fixes: 26d688e33f
("net/mlx5: DR, Add Steering entry (STE) utilities")
Signed-off-by: Yevgeny Kliteynik <kliteyn@mellanox.com>
Reviewed-by: Alex Vesker <valex@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
0c3990776f
commit
c48a78c083
@ -209,7 +209,7 @@ static void dr_rule_rehash_copy_ste_ctrl(struct mlx5dr_matcher *matcher,
|
||||
/* We need to copy the refcount since this ste
|
||||
* may have been traversed several times
|
||||
*/
|
||||
refcount_set(&new_ste->refcount, refcount_read(&cur_ste->refcount));
|
||||
new_ste->refcount = cur_ste->refcount;
|
||||
|
||||
/* Link old STEs rule_mem list to the new ste */
|
||||
mlx5dr_rule_update_rule_member(cur_ste, new_ste);
|
||||
|
@ -340,7 +340,7 @@ static void dr_ste_replace(struct mlx5dr_ste *dst, struct mlx5dr_ste *src)
|
||||
if (dst->next_htbl)
|
||||
dst->next_htbl->pointing_ste = dst;
|
||||
|
||||
refcount_set(&dst->refcount, refcount_read(&src->refcount));
|
||||
dst->refcount = src->refcount;
|
||||
|
||||
INIT_LIST_HEAD(&dst->rule_list);
|
||||
list_splice_tail_init(&src->rule_list, &dst->rule_list);
|
||||
@ -557,7 +557,7 @@ bool mlx5dr_ste_is_not_valid_entry(u8 *p_hw_ste)
|
||||
|
||||
bool mlx5dr_ste_not_used_ste(struct mlx5dr_ste *ste)
|
||||
{
|
||||
return !refcount_read(&ste->refcount);
|
||||
return !ste->refcount;
|
||||
}
|
||||
|
||||
/* Init one ste as a pattern for ste data array */
|
||||
@ -681,14 +681,14 @@ struct mlx5dr_ste_htbl *mlx5dr_ste_htbl_alloc(struct mlx5dr_icm_pool *pool,
|
||||
htbl->ste_arr = chunk->ste_arr;
|
||||
htbl->hw_ste_arr = chunk->hw_ste_arr;
|
||||
htbl->miss_list = chunk->miss_list;
|
||||
refcount_set(&htbl->refcount, 0);
|
||||
htbl->refcount = 0;
|
||||
|
||||
for (i = 0; i < chunk->num_of_entries; i++) {
|
||||
struct mlx5dr_ste *ste = &htbl->ste_arr[i];
|
||||
|
||||
ste->hw_ste = htbl->hw_ste_arr + i * DR_STE_SIZE_REDUCED;
|
||||
ste->htbl = htbl;
|
||||
refcount_set(&ste->refcount, 0);
|
||||
ste->refcount = 0;
|
||||
INIT_LIST_HEAD(&ste->miss_list_node);
|
||||
INIT_LIST_HEAD(&htbl->miss_list[i]);
|
||||
INIT_LIST_HEAD(&ste->rule_list);
|
||||
@ -705,7 +705,7 @@ out_free_htbl:
|
||||
|
||||
int mlx5dr_ste_htbl_free(struct mlx5dr_ste_htbl *htbl)
|
||||
{
|
||||
if (refcount_read(&htbl->refcount))
|
||||
if (htbl->refcount)
|
||||
return -EBUSY;
|
||||
|
||||
mlx5dr_icm_free_chunk(htbl->chunk);
|
||||
|
@ -117,7 +117,7 @@ struct mlx5dr_matcher_rx_tx;
|
||||
struct mlx5dr_ste {
|
||||
u8 *hw_ste;
|
||||
/* refcount: indicates the num of rules that using this ste */
|
||||
refcount_t refcount;
|
||||
u32 refcount;
|
||||
|
||||
/* attached to the miss_list head at each htbl entry */
|
||||
struct list_head miss_list_node;
|
||||
@ -149,7 +149,7 @@ struct mlx5dr_ste_htbl_ctrl {
|
||||
struct mlx5dr_ste_htbl {
|
||||
u8 lu_type;
|
||||
u16 byte_mask;
|
||||
refcount_t refcount;
|
||||
u32 refcount;
|
||||
struct mlx5dr_icm_chunk *chunk;
|
||||
struct mlx5dr_ste *ste_arr;
|
||||
u8 *hw_ste_arr;
|
||||
@ -200,13 +200,14 @@ int mlx5dr_ste_htbl_free(struct mlx5dr_ste_htbl *htbl);
|
||||
|
||||
static inline void mlx5dr_htbl_put(struct mlx5dr_ste_htbl *htbl)
|
||||
{
|
||||
if (refcount_dec_and_test(&htbl->refcount))
|
||||
htbl->refcount--;
|
||||
if (!htbl->refcount)
|
||||
mlx5dr_ste_htbl_free(htbl);
|
||||
}
|
||||
|
||||
static inline void mlx5dr_htbl_get(struct mlx5dr_ste_htbl *htbl)
|
||||
{
|
||||
refcount_inc(&htbl->refcount);
|
||||
htbl->refcount++;
|
||||
}
|
||||
|
||||
/* STE utils */
|
||||
@ -248,14 +249,15 @@ static inline void mlx5dr_ste_put(struct mlx5dr_ste *ste,
|
||||
struct mlx5dr_matcher *matcher,
|
||||
struct mlx5dr_matcher_rx_tx *nic_matcher)
|
||||
{
|
||||
if (refcount_dec_and_test(&ste->refcount))
|
||||
ste->refcount--;
|
||||
if (!ste->refcount)
|
||||
mlx5dr_ste_free(ste, matcher, nic_matcher);
|
||||
}
|
||||
|
||||
/* initial as 0, increased only when ste appears in a new rule */
|
||||
static inline void mlx5dr_ste_get(struct mlx5dr_ste *ste)
|
||||
{
|
||||
refcount_inc(&ste->refcount);
|
||||
ste->refcount++;
|
||||
}
|
||||
|
||||
void mlx5dr_ste_set_hit_addr_by_next_htbl(u8 *hw_ste,
|
||||
|
Loading…
Reference in New Issue
Block a user