Commit 1267f722 authored by Amit Cohen's avatar Amit Cohen Committed by Paolo Abeni

mlxsw: Use refcount_t for reference counting

mlxsw driver uses 'unsigned int' for reference counters in several
structures. Instead, use refcount_t type which allows us to catch overflow
and underflow issues. Change the type of the counters and use the
appropriate API.
Signed-off-by: default avatarAmit Cohen <amcohen@nvidia.com>
Reviewed-by: default avatarIdo Schimmel <idosch@nvidia.com>
Signed-off-by: default avatarIdo Schimmel <idosch@nvidia.com>
Signed-off-by: default avatarPetr Machata <petrm@nvidia.com>
Reviewed-by: default avatarSimon Horman <horms@kernel.org>
Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parent be2f16a9
...@@ -95,7 +95,7 @@ struct mlxsw_afa_set { ...@@ -95,7 +95,7 @@ struct mlxsw_afa_set {
*/ */
has_trap:1, has_trap:1,
has_police:1; has_police:1;
unsigned int ref_count; refcount_t ref_count;
struct mlxsw_afa_set *next; /* Pointer to the next set. */ struct mlxsw_afa_set *next; /* Pointer to the next set. */
struct mlxsw_afa_set *prev; /* Pointer to the previous set, struct mlxsw_afa_set *prev; /* Pointer to the previous set,
* note that set may have multiple * note that set may have multiple
...@@ -120,7 +120,7 @@ struct mlxsw_afa_fwd_entry { ...@@ -120,7 +120,7 @@ struct mlxsw_afa_fwd_entry {
struct rhash_head ht_node; struct rhash_head ht_node;
struct mlxsw_afa_fwd_entry_ht_key ht_key; struct mlxsw_afa_fwd_entry_ht_key ht_key;
u32 kvdl_index; u32 kvdl_index;
unsigned int ref_count; refcount_t ref_count;
}; };
static const struct rhashtable_params mlxsw_afa_fwd_entry_ht_params = { static const struct rhashtable_params mlxsw_afa_fwd_entry_ht_params = {
...@@ -282,7 +282,7 @@ static struct mlxsw_afa_set *mlxsw_afa_set_create(bool is_first) ...@@ -282,7 +282,7 @@ static struct mlxsw_afa_set *mlxsw_afa_set_create(bool is_first)
/* Need to initialize the set to pass by default */ /* Need to initialize the set to pass by default */
mlxsw_afa_set_goto_set(set, MLXSW_AFA_SET_GOTO_BINDING_CMD_TERM, 0); mlxsw_afa_set_goto_set(set, MLXSW_AFA_SET_GOTO_BINDING_CMD_TERM, 0);
set->ht_key.is_first = is_first; set->ht_key.is_first = is_first;
set->ref_count = 1; refcount_set(&set->ref_count, 1);
return set; return set;
} }
...@@ -330,7 +330,7 @@ static void mlxsw_afa_set_unshare(struct mlxsw_afa *mlxsw_afa, ...@@ -330,7 +330,7 @@ static void mlxsw_afa_set_unshare(struct mlxsw_afa *mlxsw_afa,
static void mlxsw_afa_set_put(struct mlxsw_afa *mlxsw_afa, static void mlxsw_afa_set_put(struct mlxsw_afa *mlxsw_afa,
struct mlxsw_afa_set *set) struct mlxsw_afa_set *set)
{ {
if (--set->ref_count) if (!refcount_dec_and_test(&set->ref_count))
return; return;
if (set->shared) if (set->shared)
mlxsw_afa_set_unshare(mlxsw_afa, set); mlxsw_afa_set_unshare(mlxsw_afa, set);
...@@ -350,7 +350,7 @@ static struct mlxsw_afa_set *mlxsw_afa_set_get(struct mlxsw_afa *mlxsw_afa, ...@@ -350,7 +350,7 @@ static struct mlxsw_afa_set *mlxsw_afa_set_get(struct mlxsw_afa *mlxsw_afa,
set = rhashtable_lookup_fast(&mlxsw_afa->set_ht, &orig_set->ht_key, set = rhashtable_lookup_fast(&mlxsw_afa->set_ht, &orig_set->ht_key,
mlxsw_afa_set_ht_params); mlxsw_afa_set_ht_params);
if (set) { if (set) {
set->ref_count++; refcount_inc(&set->ref_count);
mlxsw_afa_set_put(mlxsw_afa, orig_set); mlxsw_afa_set_put(mlxsw_afa, orig_set);
} else { } else {
set = orig_set; set = orig_set;
...@@ -564,7 +564,7 @@ mlxsw_afa_fwd_entry_create(struct mlxsw_afa *mlxsw_afa, u16 local_port) ...@@ -564,7 +564,7 @@ mlxsw_afa_fwd_entry_create(struct mlxsw_afa *mlxsw_afa, u16 local_port)
if (!fwd_entry) if (!fwd_entry)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
fwd_entry->ht_key.local_port = local_port; fwd_entry->ht_key.local_port = local_port;
fwd_entry->ref_count = 1; refcount_set(&fwd_entry->ref_count, 1);
err = rhashtable_insert_fast(&mlxsw_afa->fwd_entry_ht, err = rhashtable_insert_fast(&mlxsw_afa->fwd_entry_ht,
&fwd_entry->ht_node, &fwd_entry->ht_node,
...@@ -607,7 +607,7 @@ mlxsw_afa_fwd_entry_get(struct mlxsw_afa *mlxsw_afa, u16 local_port) ...@@ -607,7 +607,7 @@ mlxsw_afa_fwd_entry_get(struct mlxsw_afa *mlxsw_afa, u16 local_port)
fwd_entry = rhashtable_lookup_fast(&mlxsw_afa->fwd_entry_ht, &ht_key, fwd_entry = rhashtable_lookup_fast(&mlxsw_afa->fwd_entry_ht, &ht_key,
mlxsw_afa_fwd_entry_ht_params); mlxsw_afa_fwd_entry_ht_params);
if (fwd_entry) { if (fwd_entry) {
fwd_entry->ref_count++; refcount_inc(&fwd_entry->ref_count);
return fwd_entry; return fwd_entry;
} }
return mlxsw_afa_fwd_entry_create(mlxsw_afa, local_port); return mlxsw_afa_fwd_entry_create(mlxsw_afa, local_port);
...@@ -616,7 +616,7 @@ mlxsw_afa_fwd_entry_get(struct mlxsw_afa *mlxsw_afa, u16 local_port) ...@@ -616,7 +616,7 @@ mlxsw_afa_fwd_entry_get(struct mlxsw_afa *mlxsw_afa, u16 local_port)
static void mlxsw_afa_fwd_entry_put(struct mlxsw_afa *mlxsw_afa, static void mlxsw_afa_fwd_entry_put(struct mlxsw_afa *mlxsw_afa,
struct mlxsw_afa_fwd_entry *fwd_entry) struct mlxsw_afa_fwd_entry *fwd_entry)
{ {
if (--fwd_entry->ref_count) if (!refcount_dec_and_test(&fwd_entry->ref_count))
return; return;
mlxsw_afa_fwd_entry_destroy(mlxsw_afa, fwd_entry); mlxsw_afa_fwd_entry_destroy(mlxsw_afa, fwd_entry);
} }
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/refcount.h>
#include "item.h" #include "item.h"
#include "core_acl_flex_keys.h" #include "core_acl_flex_keys.h"
...@@ -107,7 +108,7 @@ EXPORT_SYMBOL(mlxsw_afk_destroy); ...@@ -107,7 +108,7 @@ EXPORT_SYMBOL(mlxsw_afk_destroy);
struct mlxsw_afk_key_info { struct mlxsw_afk_key_info {
struct list_head list; struct list_head list;
unsigned int ref_count; refcount_t ref_count;
unsigned int blocks_count; unsigned int blocks_count;
int element_to_block[MLXSW_AFK_ELEMENT_MAX]; /* index is element, value int element_to_block[MLXSW_AFK_ELEMENT_MAX]; /* index is element, value
* is index inside "blocks" * is index inside "blocks"
...@@ -334,7 +335,7 @@ mlxsw_afk_key_info_create(struct mlxsw_afk *mlxsw_afk, ...@@ -334,7 +335,7 @@ mlxsw_afk_key_info_create(struct mlxsw_afk *mlxsw_afk,
if (err) if (err)
goto err_picker; goto err_picker;
list_add(&key_info->list, &mlxsw_afk->key_info_list); list_add(&key_info->list, &mlxsw_afk->key_info_list);
key_info->ref_count = 1; refcount_set(&key_info->ref_count, 1);
return key_info; return key_info;
err_picker: err_picker:
...@@ -356,7 +357,7 @@ mlxsw_afk_key_info_get(struct mlxsw_afk *mlxsw_afk, ...@@ -356,7 +357,7 @@ mlxsw_afk_key_info_get(struct mlxsw_afk *mlxsw_afk,
key_info = mlxsw_afk_key_info_find(mlxsw_afk, elusage); key_info = mlxsw_afk_key_info_find(mlxsw_afk, elusage);
if (key_info) { if (key_info) {
key_info->ref_count++; refcount_inc(&key_info->ref_count);
return key_info; return key_info;
} }
return mlxsw_afk_key_info_create(mlxsw_afk, elusage); return mlxsw_afk_key_info_create(mlxsw_afk, elusage);
...@@ -365,7 +366,7 @@ EXPORT_SYMBOL(mlxsw_afk_key_info_get); ...@@ -365,7 +366,7 @@ EXPORT_SYMBOL(mlxsw_afk_key_info_get);
void mlxsw_afk_key_info_put(struct mlxsw_afk_key_info *key_info) void mlxsw_afk_key_info_put(struct mlxsw_afk_key_info *key_info)
{ {
if (--key_info->ref_count) if (!refcount_dec_and_test(&key_info->ref_count))
return; return;
mlxsw_afk_key_info_destroy(key_info); mlxsw_afk_key_info_destroy(key_info);
} }
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <linux/rhashtable.h> #include <linux/rhashtable.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/refcount.h>
#include <net/net_namespace.h> #include <net/net_namespace.h>
#include <net/tc_act/tc_vlan.h> #include <net/tc_act/tc_vlan.h>
...@@ -55,7 +56,7 @@ struct mlxsw_sp_acl_ruleset { ...@@ -55,7 +56,7 @@ struct mlxsw_sp_acl_ruleset {
struct rhash_head ht_node; /* Member of acl HT */ struct rhash_head ht_node; /* Member of acl HT */
struct mlxsw_sp_acl_ruleset_ht_key ht_key; struct mlxsw_sp_acl_ruleset_ht_key ht_key;
struct rhashtable rule_ht; struct rhashtable rule_ht;
unsigned int ref_count; refcount_t ref_count;
unsigned int min_prio; unsigned int min_prio;
unsigned int max_prio; unsigned int max_prio;
unsigned long priv[]; unsigned long priv[];
...@@ -99,7 +100,7 @@ static bool ...@@ -99,7 +100,7 @@ static bool
mlxsw_sp_acl_ruleset_is_singular(const struct mlxsw_sp_acl_ruleset *ruleset) mlxsw_sp_acl_ruleset_is_singular(const struct mlxsw_sp_acl_ruleset *ruleset)
{ {
/* We hold a reference on ruleset ourselves */ /* We hold a reference on ruleset ourselves */
return ruleset->ref_count == 2; return refcount_read(&ruleset->ref_count) == 2;
} }
int mlxsw_sp_acl_ruleset_bind(struct mlxsw_sp *mlxsw_sp, int mlxsw_sp_acl_ruleset_bind(struct mlxsw_sp *mlxsw_sp,
...@@ -176,7 +177,7 @@ mlxsw_sp_acl_ruleset_create(struct mlxsw_sp *mlxsw_sp, ...@@ -176,7 +177,7 @@ mlxsw_sp_acl_ruleset_create(struct mlxsw_sp *mlxsw_sp,
ruleset = kzalloc(alloc_size, GFP_KERNEL); ruleset = kzalloc(alloc_size, GFP_KERNEL);
if (!ruleset) if (!ruleset)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
ruleset->ref_count = 1; refcount_set(&ruleset->ref_count, 1);
ruleset->ht_key.block = block; ruleset->ht_key.block = block;
ruleset->ht_key.chain_index = chain_index; ruleset->ht_key.chain_index = chain_index;
ruleset->ht_key.ops = ops; ruleset->ht_key.ops = ops;
...@@ -222,13 +223,13 @@ static void mlxsw_sp_acl_ruleset_destroy(struct mlxsw_sp *mlxsw_sp, ...@@ -222,13 +223,13 @@ static void mlxsw_sp_acl_ruleset_destroy(struct mlxsw_sp *mlxsw_sp,
static void mlxsw_sp_acl_ruleset_ref_inc(struct mlxsw_sp_acl_ruleset *ruleset) static void mlxsw_sp_acl_ruleset_ref_inc(struct mlxsw_sp_acl_ruleset *ruleset)
{ {
ruleset->ref_count++; refcount_inc(&ruleset->ref_count);
} }
static void mlxsw_sp_acl_ruleset_ref_dec(struct mlxsw_sp *mlxsw_sp, static void mlxsw_sp_acl_ruleset_ref_dec(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_acl_ruleset *ruleset) struct mlxsw_sp_acl_ruleset *ruleset)
{ {
if (--ruleset->ref_count) if (!refcount_dec_and_test(&ruleset->ref_count))
return; return;
mlxsw_sp_acl_ruleset_destroy(mlxsw_sp, ruleset); mlxsw_sp_acl_ruleset_destroy(mlxsw_sp, ruleset);
} }
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <linux/rhashtable.h> #include <linux/rhashtable.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/refcount.h>
#include <net/devlink.h> #include <net/devlink.h>
#include <trace/events/mlxsw.h> #include <trace/events/mlxsw.h>
...@@ -155,7 +156,7 @@ struct mlxsw_sp_acl_tcam_vregion { ...@@ -155,7 +156,7 @@ struct mlxsw_sp_acl_tcam_vregion {
struct mlxsw_sp_acl_tcam_rehash_ctx ctx; struct mlxsw_sp_acl_tcam_rehash_ctx ctx;
} rehash; } rehash;
struct mlxsw_sp *mlxsw_sp; struct mlxsw_sp *mlxsw_sp;
unsigned int ref_count; refcount_t ref_count;
}; };
struct mlxsw_sp_acl_tcam_vchunk; struct mlxsw_sp_acl_tcam_vchunk;
...@@ -176,7 +177,7 @@ struct mlxsw_sp_acl_tcam_vchunk { ...@@ -176,7 +177,7 @@ struct mlxsw_sp_acl_tcam_vchunk {
unsigned int priority; /* Priority within the vregion and group */ unsigned int priority; /* Priority within the vregion and group */
struct mlxsw_sp_acl_tcam_vgroup *vgroup; struct mlxsw_sp_acl_tcam_vgroup *vgroup;
struct mlxsw_sp_acl_tcam_vregion *vregion; struct mlxsw_sp_acl_tcam_vregion *vregion;
unsigned int ref_count; refcount_t ref_count;
}; };
struct mlxsw_sp_acl_tcam_entry { struct mlxsw_sp_acl_tcam_entry {
...@@ -769,7 +770,7 @@ mlxsw_sp_acl_tcam_vregion_create(struct mlxsw_sp *mlxsw_sp, ...@@ -769,7 +770,7 @@ mlxsw_sp_acl_tcam_vregion_create(struct mlxsw_sp *mlxsw_sp,
vregion->tcam = tcam; vregion->tcam = tcam;
vregion->mlxsw_sp = mlxsw_sp; vregion->mlxsw_sp = mlxsw_sp;
vregion->vgroup = vgroup; vregion->vgroup = vgroup;
vregion->ref_count = 1; refcount_set(&vregion->ref_count, 1);
vregion->key_info = mlxsw_afk_key_info_get(afk, elusage); vregion->key_info = mlxsw_afk_key_info_get(afk, elusage);
if (IS_ERR(vregion->key_info)) { if (IS_ERR(vregion->key_info)) {
...@@ -856,7 +857,7 @@ mlxsw_sp_acl_tcam_vregion_get(struct mlxsw_sp *mlxsw_sp, ...@@ -856,7 +857,7 @@ mlxsw_sp_acl_tcam_vregion_get(struct mlxsw_sp *mlxsw_sp,
*/ */
return ERR_PTR(-EOPNOTSUPP); return ERR_PTR(-EOPNOTSUPP);
} }
vregion->ref_count++; refcount_inc(&vregion->ref_count);
return vregion; return vregion;
} }
...@@ -871,7 +872,7 @@ static void ...@@ -871,7 +872,7 @@ static void
mlxsw_sp_acl_tcam_vregion_put(struct mlxsw_sp *mlxsw_sp, mlxsw_sp_acl_tcam_vregion_put(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_acl_tcam_vregion *vregion) struct mlxsw_sp_acl_tcam_vregion *vregion)
{ {
if (--vregion->ref_count) if (!refcount_dec_and_test(&vregion->ref_count))
return; return;
mlxsw_sp_acl_tcam_vregion_destroy(mlxsw_sp, vregion); mlxsw_sp_acl_tcam_vregion_destroy(mlxsw_sp, vregion);
} }
...@@ -924,7 +925,7 @@ mlxsw_sp_acl_tcam_vchunk_create(struct mlxsw_sp *mlxsw_sp, ...@@ -924,7 +925,7 @@ mlxsw_sp_acl_tcam_vchunk_create(struct mlxsw_sp *mlxsw_sp,
INIT_LIST_HEAD(&vchunk->ventry_list); INIT_LIST_HEAD(&vchunk->ventry_list);
vchunk->priority = priority; vchunk->priority = priority;
vchunk->vgroup = vgroup; vchunk->vgroup = vgroup;
vchunk->ref_count = 1; refcount_set(&vchunk->ref_count, 1);
vregion = mlxsw_sp_acl_tcam_vregion_get(mlxsw_sp, vgroup, vregion = mlxsw_sp_acl_tcam_vregion_get(mlxsw_sp, vgroup,
priority, elusage); priority, elusage);
...@@ -1008,7 +1009,7 @@ mlxsw_sp_acl_tcam_vchunk_get(struct mlxsw_sp *mlxsw_sp, ...@@ -1008,7 +1009,7 @@ mlxsw_sp_acl_tcam_vchunk_get(struct mlxsw_sp *mlxsw_sp,
if (WARN_ON(!mlxsw_afk_key_info_subset(vchunk->vregion->key_info, if (WARN_ON(!mlxsw_afk_key_info_subset(vchunk->vregion->key_info,
elusage))) elusage)))
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
vchunk->ref_count++; refcount_inc(&vchunk->ref_count);
return vchunk; return vchunk;
} }
return mlxsw_sp_acl_tcam_vchunk_create(mlxsw_sp, vgroup, return mlxsw_sp_acl_tcam_vchunk_create(mlxsw_sp, vgroup,
...@@ -1019,7 +1020,7 @@ static void ...@@ -1019,7 +1020,7 @@ static void
mlxsw_sp_acl_tcam_vchunk_put(struct mlxsw_sp *mlxsw_sp, mlxsw_sp_acl_tcam_vchunk_put(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_acl_tcam_vchunk *vchunk) struct mlxsw_sp_acl_tcam_vchunk *vchunk)
{ {
if (--vchunk->ref_count) if (!refcount_dec_and_test(&vchunk->ref_count))
return; return;
mlxsw_sp_acl_tcam_vchunk_destroy(mlxsw_sp, vchunk); mlxsw_sp_acl_tcam_vchunk_destroy(mlxsw_sp, vchunk);
} }
......
...@@ -501,7 +501,7 @@ struct mlxsw_sp_rt6 { ...@@ -501,7 +501,7 @@ struct mlxsw_sp_rt6 {
struct mlxsw_sp_lpm_tree { struct mlxsw_sp_lpm_tree {
u8 id; /* tree ID */ u8 id; /* tree ID */
unsigned int ref_count; refcount_t ref_count;
enum mlxsw_sp_l3proto proto; enum mlxsw_sp_l3proto proto;
unsigned long prefix_ref_count[MLXSW_SP_PREFIX_COUNT]; unsigned long prefix_ref_count[MLXSW_SP_PREFIX_COUNT];
struct mlxsw_sp_prefix_usage prefix_usage; struct mlxsw_sp_prefix_usage prefix_usage;
...@@ -578,7 +578,7 @@ mlxsw_sp_lpm_tree_find_unused(struct mlxsw_sp *mlxsw_sp) ...@@ -578,7 +578,7 @@ mlxsw_sp_lpm_tree_find_unused(struct mlxsw_sp *mlxsw_sp)
for (i = 0; i < mlxsw_sp->router->lpm.tree_count; i++) { for (i = 0; i < mlxsw_sp->router->lpm.tree_count; i++) {
lpm_tree = &mlxsw_sp->router->lpm.trees[i]; lpm_tree = &mlxsw_sp->router->lpm.trees[i];
if (lpm_tree->ref_count == 0) if (refcount_read(&lpm_tree->ref_count) == 0)
return lpm_tree; return lpm_tree;
} }
return NULL; return NULL;
...@@ -654,7 +654,7 @@ mlxsw_sp_lpm_tree_create(struct mlxsw_sp *mlxsw_sp, ...@@ -654,7 +654,7 @@ mlxsw_sp_lpm_tree_create(struct mlxsw_sp *mlxsw_sp,
sizeof(lpm_tree->prefix_usage)); sizeof(lpm_tree->prefix_usage));
memset(&lpm_tree->prefix_ref_count, 0, memset(&lpm_tree->prefix_ref_count, 0,
sizeof(lpm_tree->prefix_ref_count)); sizeof(lpm_tree->prefix_ref_count));
lpm_tree->ref_count = 1; refcount_set(&lpm_tree->ref_count, 1);
return lpm_tree; return lpm_tree;
err_left_struct_set: err_left_struct_set:
...@@ -678,7 +678,7 @@ mlxsw_sp_lpm_tree_get(struct mlxsw_sp *mlxsw_sp, ...@@ -678,7 +678,7 @@ mlxsw_sp_lpm_tree_get(struct mlxsw_sp *mlxsw_sp,
for (i = 0; i < mlxsw_sp->router->lpm.tree_count; i++) { for (i = 0; i < mlxsw_sp->router->lpm.tree_count; i++) {
lpm_tree = &mlxsw_sp->router->lpm.trees[i]; lpm_tree = &mlxsw_sp->router->lpm.trees[i];
if (lpm_tree->ref_count != 0 && if (refcount_read(&lpm_tree->ref_count) &&
lpm_tree->proto == proto && lpm_tree->proto == proto &&
mlxsw_sp_prefix_usage_eq(&lpm_tree->prefix_usage, mlxsw_sp_prefix_usage_eq(&lpm_tree->prefix_usage,
prefix_usage)) { prefix_usage)) {
...@@ -691,14 +691,15 @@ mlxsw_sp_lpm_tree_get(struct mlxsw_sp *mlxsw_sp, ...@@ -691,14 +691,15 @@ mlxsw_sp_lpm_tree_get(struct mlxsw_sp *mlxsw_sp,
static void mlxsw_sp_lpm_tree_hold(struct mlxsw_sp_lpm_tree *lpm_tree) static void mlxsw_sp_lpm_tree_hold(struct mlxsw_sp_lpm_tree *lpm_tree)
{ {
lpm_tree->ref_count++; refcount_inc(&lpm_tree->ref_count);
} }
static void mlxsw_sp_lpm_tree_put(struct mlxsw_sp *mlxsw_sp, static void mlxsw_sp_lpm_tree_put(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_lpm_tree *lpm_tree) struct mlxsw_sp_lpm_tree *lpm_tree)
{ {
if (--lpm_tree->ref_count == 0) if (!refcount_dec_and_test(&lpm_tree->ref_count))
mlxsw_sp_lpm_tree_destroy(mlxsw_sp, lpm_tree); return;
mlxsw_sp_lpm_tree_destroy(mlxsw_sp, lpm_tree);
} }
#define MLXSW_SP_LPM_TREE_MIN 1 /* tree 0 is reserved */ #define MLXSW_SP_LPM_TREE_MIN 1 /* tree 0 is reserved */
......
...@@ -61,7 +61,7 @@ struct mlxsw_sp_bridge_port { ...@@ -61,7 +61,7 @@ struct mlxsw_sp_bridge_port {
struct mlxsw_sp_bridge_device *bridge_device; struct mlxsw_sp_bridge_device *bridge_device;
struct list_head list; struct list_head list;
struct list_head vlans_list; struct list_head vlans_list;
unsigned int ref_count; refcount_t ref_count;
u8 stp_state; u8 stp_state;
unsigned long flags; unsigned long flags;
bool mrouter; bool mrouter;
...@@ -495,7 +495,7 @@ mlxsw_sp_bridge_port_create(struct mlxsw_sp_bridge_device *bridge_device, ...@@ -495,7 +495,7 @@ mlxsw_sp_bridge_port_create(struct mlxsw_sp_bridge_device *bridge_device,
BR_MCAST_FLOOD; BR_MCAST_FLOOD;
INIT_LIST_HEAD(&bridge_port->vlans_list); INIT_LIST_HEAD(&bridge_port->vlans_list);
list_add(&bridge_port->list, &bridge_device->ports_list); list_add(&bridge_port->list, &bridge_device->ports_list);
bridge_port->ref_count = 1; refcount_set(&bridge_port->ref_count, 1);
err = switchdev_bridge_port_offload(brport_dev, mlxsw_sp_port->dev, err = switchdev_bridge_port_offload(brport_dev, mlxsw_sp_port->dev,
NULL, NULL, NULL, false, extack); NULL, NULL, NULL, false, extack);
...@@ -531,7 +531,7 @@ mlxsw_sp_bridge_port_get(struct mlxsw_sp_bridge *bridge, ...@@ -531,7 +531,7 @@ mlxsw_sp_bridge_port_get(struct mlxsw_sp_bridge *bridge,
bridge_port = mlxsw_sp_bridge_port_find(bridge, brport_dev); bridge_port = mlxsw_sp_bridge_port_find(bridge, brport_dev);
if (bridge_port) { if (bridge_port) {
bridge_port->ref_count++; refcount_inc(&bridge_port->ref_count);
return bridge_port; return bridge_port;
} }
...@@ -558,7 +558,7 @@ static void mlxsw_sp_bridge_port_put(struct mlxsw_sp_bridge *bridge, ...@@ -558,7 +558,7 @@ static void mlxsw_sp_bridge_port_put(struct mlxsw_sp_bridge *bridge,
{ {
struct mlxsw_sp_bridge_device *bridge_device; struct mlxsw_sp_bridge_device *bridge_device;
if (--bridge_port->ref_count != 0) if (!refcount_dec_and_test(&bridge_port->ref_count))
return; return;
bridge_device = bridge_port->bridge_device; bridge_device = bridge_port->bridge_device;
mlxsw_sp_bridge_port_destroy(bridge_port); mlxsw_sp_bridge_port_destroy(bridge_port);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment