Merge branch 'mlxsw-refactor-reference-counting-code'
Petr Machata says: ==================== mlxsw: Refactor reference counting code Amit Cohen writes: This set converts all reference counters defined as 'unsigned int' to refcount_t type. The reference counting of LAGs can be simplified, so first refactor the related code and then change the type of the reference counter. Patch set overview: Patches #1-#4 are preparations for LAG refactor Patch #5 refactors LAG code and change the type of reference counter Patch #6 converts the remaining reference counters in mlxsw driver ==================== Link: https://lore.kernel.org/r/cover.1706293430.git.petrm@nvidia.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
commit
d0005e76b7
@ -95,7 +95,7 @@ struct mlxsw_afa_set {
|
||||
*/
|
||||
has_trap: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 *prev; /* Pointer to the previous set,
|
||||
* note that set may have multiple
|
||||
@ -120,7 +120,7 @@ struct mlxsw_afa_fwd_entry {
|
||||
struct rhash_head ht_node;
|
||||
struct mlxsw_afa_fwd_entry_ht_key ht_key;
|
||||
u32 kvdl_index;
|
||||
unsigned int ref_count;
|
||||
refcount_t ref_count;
|
||||
};
|
||||
|
||||
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)
|
||||
/* Need to initialize the set to pass by default */
|
||||
mlxsw_afa_set_goto_set(set, MLXSW_AFA_SET_GOTO_BINDING_CMD_TERM, 0);
|
||||
set->ht_key.is_first = is_first;
|
||||
set->ref_count = 1;
|
||||
refcount_set(&set->ref_count, 1);
|
||||
return set;
|
||||
}
|
||||
|
||||
@ -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,
|
||||
struct mlxsw_afa_set *set)
|
||||
{
|
||||
if (--set->ref_count)
|
||||
if (!refcount_dec_and_test(&set->ref_count))
|
||||
return;
|
||||
if (set->shared)
|
||||
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,
|
||||
set = rhashtable_lookup_fast(&mlxsw_afa->set_ht, &orig_set->ht_key,
|
||||
mlxsw_afa_set_ht_params);
|
||||
if (set) {
|
||||
set->ref_count++;
|
||||
refcount_inc(&set->ref_count);
|
||||
mlxsw_afa_set_put(mlxsw_afa, orig_set);
|
||||
} else {
|
||||
set = orig_set;
|
||||
@ -564,7 +564,7 @@ mlxsw_afa_fwd_entry_create(struct mlxsw_afa *mlxsw_afa, u16 local_port)
|
||||
if (!fwd_entry)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
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,
|
||||
&fwd_entry->ht_node,
|
||||
@ -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,
|
||||
mlxsw_afa_fwd_entry_ht_params);
|
||||
if (fwd_entry) {
|
||||
fwd_entry->ref_count++;
|
||||
refcount_inc(&fwd_entry->ref_count);
|
||||
return fwd_entry;
|
||||
}
|
||||
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)
|
||||
static void mlxsw_afa_fwd_entry_put(struct mlxsw_afa *mlxsw_afa,
|
||||
struct mlxsw_afa_fwd_entry *fwd_entry)
|
||||
{
|
||||
if (--fwd_entry->ref_count)
|
||||
if (!refcount_dec_and_test(&fwd_entry->ref_count))
|
||||
return;
|
||||
mlxsw_afa_fwd_entry_destroy(mlxsw_afa, fwd_entry);
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/refcount.h>
|
||||
|
||||
#include "item.h"
|
||||
#include "core_acl_flex_keys.h"
|
||||
@ -107,7 +108,7 @@ EXPORT_SYMBOL(mlxsw_afk_destroy);
|
||||
|
||||
struct mlxsw_afk_key_info {
|
||||
struct list_head list;
|
||||
unsigned int ref_count;
|
||||
refcount_t ref_count;
|
||||
unsigned int blocks_count;
|
||||
int element_to_block[MLXSW_AFK_ELEMENT_MAX]; /* index is element, value
|
||||
* is index inside "blocks"
|
||||
@ -334,7 +335,7 @@ mlxsw_afk_key_info_create(struct mlxsw_afk *mlxsw_afk,
|
||||
if (err)
|
||||
goto err_picker;
|
||||
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;
|
||||
|
||||
err_picker:
|
||||
@ -356,7 +357,7 @@ mlxsw_afk_key_info_get(struct mlxsw_afk *mlxsw_afk,
|
||||
|
||||
key_info = mlxsw_afk_key_info_find(mlxsw_afk, elusage);
|
||||
if (key_info) {
|
||||
key_info->ref_count++;
|
||||
refcount_inc(&key_info->ref_count);
|
||||
return key_info;
|
||||
}
|
||||
return mlxsw_afk_key_info_create(mlxsw_afk, elusage);
|
||||
@ -365,7 +366,7 @@ EXPORT_SYMBOL(mlxsw_afk_key_info_get);
|
||||
|
||||
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;
|
||||
mlxsw_afk_key_info_destroy(key_info);
|
||||
}
|
||||
|
@ -2695,23 +2695,18 @@ static void mlxsw_sp_traps_fini(struct mlxsw_sp *mlxsw_sp)
|
||||
static int mlxsw_sp_lag_pgt_init(struct mlxsw_sp *mlxsw_sp)
|
||||
{
|
||||
char sgcr_pl[MLXSW_REG_SGCR_LEN];
|
||||
u16 max_lag;
|
||||
int err;
|
||||
|
||||
if (mlxsw_core_lag_mode(mlxsw_sp->core) !=
|
||||
MLXSW_CMD_MBOX_CONFIG_PROFILE_LAG_MODE_SW)
|
||||
return 0;
|
||||
|
||||
err = mlxsw_core_max_lag(mlxsw_sp->core, &max_lag);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* In DDD mode, which we by default use, each LAG entry is 8 PGT
|
||||
* entries. The LAG table address needs to be 8-aligned, but that ought
|
||||
* to be the case, since the LAG table is allocated first.
|
||||
*/
|
||||
err = mlxsw_sp_pgt_mid_alloc_range(mlxsw_sp, &mlxsw_sp->lag_pgt_base,
|
||||
max_lag * 8);
|
||||
mlxsw_sp->max_lag * 8);
|
||||
if (err)
|
||||
return err;
|
||||
if (WARN_ON_ONCE(mlxsw_sp->lag_pgt_base % 8)) {
|
||||
@ -2728,33 +2723,31 @@ static int mlxsw_sp_lag_pgt_init(struct mlxsw_sp *mlxsw_sp)
|
||||
|
||||
err_mid_alloc_range:
|
||||
mlxsw_sp_pgt_mid_free_range(mlxsw_sp, mlxsw_sp->lag_pgt_base,
|
||||
max_lag * 8);
|
||||
mlxsw_sp->max_lag * 8);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void mlxsw_sp_lag_pgt_fini(struct mlxsw_sp *mlxsw_sp)
|
||||
{
|
||||
u16 max_lag;
|
||||
int err;
|
||||
|
||||
if (mlxsw_core_lag_mode(mlxsw_sp->core) !=
|
||||
MLXSW_CMD_MBOX_CONFIG_PROFILE_LAG_MODE_SW)
|
||||
return;
|
||||
|
||||
err = mlxsw_core_max_lag(mlxsw_sp->core, &max_lag);
|
||||
if (err)
|
||||
return;
|
||||
|
||||
mlxsw_sp_pgt_mid_free_range(mlxsw_sp, mlxsw_sp->lag_pgt_base,
|
||||
max_lag * 8);
|
||||
mlxsw_sp->max_lag * 8);
|
||||
}
|
||||
|
||||
#define MLXSW_SP_LAG_SEED_INIT 0xcafecafe
|
||||
|
||||
struct mlxsw_sp_lag {
|
||||
struct net_device *dev;
|
||||
refcount_t ref_count;
|
||||
u16 lag_id;
|
||||
};
|
||||
|
||||
static int mlxsw_sp_lag_init(struct mlxsw_sp *mlxsw_sp)
|
||||
{
|
||||
char slcr_pl[MLXSW_REG_SLCR_LEN];
|
||||
u16 max_lag;
|
||||
u32 seed;
|
||||
int err;
|
||||
|
||||
@ -2773,7 +2766,7 @@ static int mlxsw_sp_lag_init(struct mlxsw_sp *mlxsw_sp)
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = mlxsw_core_max_lag(mlxsw_sp->core, &max_lag);
|
||||
err = mlxsw_core_max_lag(mlxsw_sp->core, &mlxsw_sp->max_lag);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@ -2784,7 +2777,7 @@ static int mlxsw_sp_lag_init(struct mlxsw_sp *mlxsw_sp)
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
mlxsw_sp->lags = kcalloc(max_lag, sizeof(struct mlxsw_sp_upper),
|
||||
mlxsw_sp->lags = kcalloc(mlxsw_sp->max_lag, sizeof(struct mlxsw_sp_lag),
|
||||
GFP_KERNEL);
|
||||
if (!mlxsw_sp->lags) {
|
||||
err = -ENOMEM;
|
||||
@ -4269,19 +4262,48 @@ mlxsw_sp_port_lag_uppers_cleanup(struct mlxsw_sp_port *mlxsw_sp_port,
|
||||
}
|
||||
}
|
||||
|
||||
static int mlxsw_sp_lag_create(struct mlxsw_sp *mlxsw_sp, u16 lag_id)
|
||||
static struct mlxsw_sp_lag *
|
||||
mlxsw_sp_lag_create(struct mlxsw_sp *mlxsw_sp, struct net_device *lag_dev,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
char sldr_pl[MLXSW_REG_SLDR_LEN];
|
||||
struct mlxsw_sp_lag *lag;
|
||||
u16 lag_id;
|
||||
int i, err;
|
||||
|
||||
for (i = 0; i < mlxsw_sp->max_lag; i++) {
|
||||
if (!mlxsw_sp->lags[i].dev)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == mlxsw_sp->max_lag) {
|
||||
NL_SET_ERR_MSG_MOD(extack,
|
||||
"Exceeded number of supported LAG devices");
|
||||
return ERR_PTR(-EBUSY);
|
||||
}
|
||||
|
||||
lag_id = i;
|
||||
mlxsw_reg_sldr_lag_create_pack(sldr_pl, lag_id);
|
||||
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sldr), sldr_pl);
|
||||
err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sldr), sldr_pl);
|
||||
if (err)
|
||||
return ERR_PTR(err);
|
||||
|
||||
lag = &mlxsw_sp->lags[lag_id];
|
||||
lag->lag_id = lag_id;
|
||||
lag->dev = lag_dev;
|
||||
refcount_set(&lag->ref_count, 1);
|
||||
|
||||
return lag;
|
||||
}
|
||||
|
||||
static int mlxsw_sp_lag_destroy(struct mlxsw_sp *mlxsw_sp, u16 lag_id)
|
||||
static int
|
||||
mlxsw_sp_lag_destroy(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_lag *lag)
|
||||
{
|
||||
char sldr_pl[MLXSW_REG_SLDR_LEN];
|
||||
|
||||
mlxsw_reg_sldr_lag_destroy_pack(sldr_pl, lag_id);
|
||||
lag->dev = NULL;
|
||||
|
||||
mlxsw_reg_sldr_lag_destroy_pack(sldr_pl, lag->lag_id);
|
||||
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sldr), sldr_pl);
|
||||
}
|
||||
|
||||
@ -4329,34 +4351,44 @@ static int mlxsw_sp_lag_col_port_disable(struct mlxsw_sp_port *mlxsw_sp_port,
|
||||
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(slcor), slcor_pl);
|
||||
}
|
||||
|
||||
static int mlxsw_sp_lag_index_get(struct mlxsw_sp *mlxsw_sp,
|
||||
struct net_device *lag_dev,
|
||||
u16 *p_lag_id)
|
||||
static struct mlxsw_sp_lag *
|
||||
mlxsw_sp_lag_find(struct mlxsw_sp *mlxsw_sp, struct net_device *lag_dev)
|
||||
{
|
||||
struct mlxsw_sp_upper *lag;
|
||||
int free_lag_id = -1;
|
||||
u16 max_lag;
|
||||
int err, i;
|
||||
int i;
|
||||
|
||||
err = mlxsw_core_max_lag(mlxsw_sp->core, &max_lag);
|
||||
if (err)
|
||||
return err;
|
||||
for (i = 0; i < mlxsw_sp->max_lag; i++) {
|
||||
if (!mlxsw_sp->lags[i].dev)
|
||||
continue;
|
||||
|
||||
for (i = 0; i < max_lag; i++) {
|
||||
lag = mlxsw_sp_lag_get(mlxsw_sp, i);
|
||||
if (lag->ref_count) {
|
||||
if (lag->dev == lag_dev) {
|
||||
*p_lag_id = i;
|
||||
return 0;
|
||||
}
|
||||
} else if (free_lag_id < 0) {
|
||||
free_lag_id = i;
|
||||
}
|
||||
if (mlxsw_sp->lags[i].dev == lag_dev)
|
||||
return &mlxsw_sp->lags[i];
|
||||
}
|
||||
if (free_lag_id < 0)
|
||||
return -EBUSY;
|
||||
*p_lag_id = free_lag_id;
|
||||
return 0;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct mlxsw_sp_lag *
|
||||
mlxsw_sp_lag_get(struct mlxsw_sp *mlxsw_sp, struct net_device *lag_dev,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct mlxsw_sp_lag *lag;
|
||||
|
||||
lag = mlxsw_sp_lag_find(mlxsw_sp, lag_dev);
|
||||
if (lag) {
|
||||
refcount_inc(&lag->ref_count);
|
||||
return lag;
|
||||
}
|
||||
|
||||
return mlxsw_sp_lag_create(mlxsw_sp, lag_dev, extack);
|
||||
}
|
||||
|
||||
static void
|
||||
mlxsw_sp_lag_put(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_lag *lag)
|
||||
{
|
||||
if (!refcount_dec_and_test(&lag->ref_count))
|
||||
return;
|
||||
|
||||
mlxsw_sp_lag_destroy(mlxsw_sp, lag);
|
||||
}
|
||||
|
||||
static bool
|
||||
@ -4365,12 +4397,6 @@ mlxsw_sp_master_lag_check(struct mlxsw_sp *mlxsw_sp,
|
||||
struct netdev_lag_upper_info *lag_upper_info,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
u16 lag_id;
|
||||
|
||||
if (mlxsw_sp_lag_index_get(mlxsw_sp, lag_dev, &lag_id) != 0) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "Exceeded number of supported LAG devices");
|
||||
return false;
|
||||
}
|
||||
if (lag_upper_info->tx_type != NETDEV_LAG_TX_TYPE_HASH) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "LAG device using unsupported Tx type");
|
||||
return false;
|
||||
@ -4482,22 +4508,16 @@ static int mlxsw_sp_port_lag_join(struct mlxsw_sp_port *mlxsw_sp_port,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
|
||||
struct mlxsw_sp_upper *lag;
|
||||
struct mlxsw_sp_lag *lag;
|
||||
u16 lag_id;
|
||||
u8 port_index;
|
||||
int err;
|
||||
|
||||
err = mlxsw_sp_lag_index_get(mlxsw_sp, lag_dev, &lag_id);
|
||||
if (err)
|
||||
return err;
|
||||
lag = mlxsw_sp_lag_get(mlxsw_sp, lag_id);
|
||||
if (!lag->ref_count) {
|
||||
err = mlxsw_sp_lag_create(mlxsw_sp, lag_id);
|
||||
if (err)
|
||||
return err;
|
||||
lag->dev = lag_dev;
|
||||
}
|
||||
lag = mlxsw_sp_lag_get(mlxsw_sp, lag_dev, extack);
|
||||
if (IS_ERR(lag))
|
||||
return PTR_ERR(lag);
|
||||
|
||||
lag_id = lag->lag_id;
|
||||
err = mlxsw_sp_port_lag_index_get(mlxsw_sp, lag_id, &port_index);
|
||||
if (err)
|
||||
return err;
|
||||
@ -4515,7 +4535,6 @@ static int mlxsw_sp_port_lag_join(struct mlxsw_sp_port *mlxsw_sp_port,
|
||||
mlxsw_sp_port->local_port);
|
||||
mlxsw_sp_port->lag_id = lag_id;
|
||||
mlxsw_sp_port->lagged = 1;
|
||||
lag->ref_count++;
|
||||
|
||||
err = mlxsw_sp_fid_port_join_lag(mlxsw_sp_port);
|
||||
if (err)
|
||||
@ -4542,7 +4561,6 @@ err_replay:
|
||||
err_router_join:
|
||||
mlxsw_sp_fid_port_leave_lag(mlxsw_sp_port);
|
||||
err_fid_port_join_lag:
|
||||
lag->ref_count--;
|
||||
mlxsw_sp_port->lagged = 0;
|
||||
mlxsw_core_lag_mapping_clear(mlxsw_sp->core, lag_id,
|
||||
mlxsw_sp_port->local_port);
|
||||
@ -4550,8 +4568,7 @@ err_fid_port_join_lag:
|
||||
err_col_port_add:
|
||||
mlxsw_sp_lag_uppers_bridge_leave(mlxsw_sp_port, lag_dev);
|
||||
err_lag_uppers_bridge_join:
|
||||
if (!lag->ref_count)
|
||||
mlxsw_sp_lag_destroy(mlxsw_sp, lag_id);
|
||||
mlxsw_sp_lag_put(mlxsw_sp, lag);
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -4560,12 +4577,11 @@ static void mlxsw_sp_port_lag_leave(struct mlxsw_sp_port *mlxsw_sp_port,
|
||||
{
|
||||
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
|
||||
u16 lag_id = mlxsw_sp_port->lag_id;
|
||||
struct mlxsw_sp_upper *lag;
|
||||
struct mlxsw_sp_lag *lag;
|
||||
|
||||
if (!mlxsw_sp_port->lagged)
|
||||
return;
|
||||
lag = mlxsw_sp_lag_get(mlxsw_sp, lag_id);
|
||||
WARN_ON(lag->ref_count == 0);
|
||||
lag = &mlxsw_sp->lags[lag_id];
|
||||
|
||||
mlxsw_sp_lag_col_port_remove(mlxsw_sp_port, lag_id);
|
||||
|
||||
@ -4579,13 +4595,11 @@ static void mlxsw_sp_port_lag_leave(struct mlxsw_sp_port *mlxsw_sp_port,
|
||||
|
||||
mlxsw_sp_fid_port_leave_lag(mlxsw_sp_port);
|
||||
|
||||
if (lag->ref_count == 1)
|
||||
mlxsw_sp_lag_destroy(mlxsw_sp, lag_id);
|
||||
mlxsw_sp_lag_put(mlxsw_sp, lag);
|
||||
|
||||
mlxsw_core_lag_mapping_clear(mlxsw_sp->core, lag_id,
|
||||
mlxsw_sp_port->local_port);
|
||||
mlxsw_sp_port->lagged = 0;
|
||||
lag->ref_count--;
|
||||
|
||||
/* Make sure untagged frames are allowed to ingress */
|
||||
mlxsw_sp_port_pvid_set(mlxsw_sp_port, MLXSW_SP_DEFAULT_VID,
|
||||
|
@ -78,11 +78,6 @@ struct mlxsw_sp_span_entry;
|
||||
enum mlxsw_sp_l3proto;
|
||||
union mlxsw_sp_l3addr;
|
||||
|
||||
struct mlxsw_sp_upper {
|
||||
struct net_device *dev;
|
||||
unsigned int ref_count;
|
||||
};
|
||||
|
||||
enum mlxsw_sp_rif_type {
|
||||
MLXSW_SP_RIF_TYPE_SUBPORT,
|
||||
MLXSW_SP_RIF_TYPE_VLAN,
|
||||
@ -136,6 +131,7 @@ struct mlxsw_sp_span_ops;
|
||||
struct mlxsw_sp_qdisc_state;
|
||||
struct mlxsw_sp_mall_entry;
|
||||
struct mlxsw_sp_pgt;
|
||||
struct mlxsw_sp_lag;
|
||||
|
||||
struct mlxsw_sp_port_mapping {
|
||||
u8 module;
|
||||
@ -164,7 +160,8 @@ struct mlxsw_sp {
|
||||
const struct mlxsw_bus_info *bus_info;
|
||||
unsigned char base_mac[ETH_ALEN];
|
||||
const unsigned char *mac_mask;
|
||||
struct mlxsw_sp_upper *lags;
|
||||
struct mlxsw_sp_lag *lags;
|
||||
u16 max_lag;
|
||||
struct mlxsw_sp_port_mapping *port_mapping;
|
||||
struct mlxsw_sp_port_mapping_events port_mapping_events;
|
||||
struct rhashtable sample_trigger_ht;
|
||||
@ -257,12 +254,6 @@ struct mlxsw_sp_fid_core_ops {
|
||||
void (*fini)(struct mlxsw_sp *mlxsw_sp);
|
||||
};
|
||||
|
||||
static inline struct mlxsw_sp_upper *
|
||||
mlxsw_sp_lag_get(struct mlxsw_sp *mlxsw_sp, u16 lag_id)
|
||||
{
|
||||
return &mlxsw_sp->lags[lag_id];
|
||||
}
|
||||
|
||||
struct mlxsw_sp_port_pcpu_stats {
|
||||
u64 rx_packets;
|
||||
u64 rx_bytes;
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <linux/rhashtable.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/refcount.h>
|
||||
#include <net/net_namespace.h>
|
||||
#include <net/tc_act/tc_vlan.h>
|
||||
|
||||
@ -55,7 +56,7 @@ struct mlxsw_sp_acl_ruleset {
|
||||
struct rhash_head ht_node; /* Member of acl HT */
|
||||
struct mlxsw_sp_acl_ruleset_ht_key ht_key;
|
||||
struct rhashtable rule_ht;
|
||||
unsigned int ref_count;
|
||||
refcount_t ref_count;
|
||||
unsigned int min_prio;
|
||||
unsigned int max_prio;
|
||||
unsigned long priv[];
|
||||
@ -99,7 +100,7 @@ static bool
|
||||
mlxsw_sp_acl_ruleset_is_singular(const struct mlxsw_sp_acl_ruleset *ruleset)
|
||||
{
|
||||
/* 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,
|
||||
@ -176,7 +177,7 @@ mlxsw_sp_acl_ruleset_create(struct mlxsw_sp *mlxsw_sp,
|
||||
ruleset = kzalloc(alloc_size, GFP_KERNEL);
|
||||
if (!ruleset)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
ruleset->ref_count = 1;
|
||||
refcount_set(&ruleset->ref_count, 1);
|
||||
ruleset->ht_key.block = block;
|
||||
ruleset->ht_key.chain_index = chain_index;
|
||||
ruleset->ht_key.ops = ops;
|
||||
@ -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)
|
||||
{
|
||||
ruleset->ref_count++;
|
||||
refcount_inc(&ruleset->ref_count);
|
||||
}
|
||||
|
||||
static void mlxsw_sp_acl_ruleset_ref_dec(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp_acl_ruleset *ruleset)
|
||||
{
|
||||
if (--ruleset->ref_count)
|
||||
if (!refcount_dec_and_test(&ruleset->ref_count))
|
||||
return;
|
||||
mlxsw_sp_acl_ruleset_destroy(mlxsw_sp, ruleset);
|
||||
}
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <linux/rhashtable.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/refcount.h>
|
||||
#include <net/devlink.h>
|
||||
#include <trace/events/mlxsw.h>
|
||||
|
||||
@ -155,7 +156,7 @@ struct mlxsw_sp_acl_tcam_vregion {
|
||||
struct mlxsw_sp_acl_tcam_rehash_ctx ctx;
|
||||
} rehash;
|
||||
struct mlxsw_sp *mlxsw_sp;
|
||||
unsigned int ref_count;
|
||||
refcount_t ref_count;
|
||||
};
|
||||
|
||||
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 */
|
||||
struct mlxsw_sp_acl_tcam_vgroup *vgroup;
|
||||
struct mlxsw_sp_acl_tcam_vregion *vregion;
|
||||
unsigned int ref_count;
|
||||
refcount_t ref_count;
|
||||
};
|
||||
|
||||
struct mlxsw_sp_acl_tcam_entry {
|
||||
@ -769,7 +770,7 @@ mlxsw_sp_acl_tcam_vregion_create(struct mlxsw_sp *mlxsw_sp,
|
||||
vregion->tcam = tcam;
|
||||
vregion->mlxsw_sp = mlxsw_sp;
|
||||
vregion->vgroup = vgroup;
|
||||
vregion->ref_count = 1;
|
||||
refcount_set(&vregion->ref_count, 1);
|
||||
|
||||
vregion->key_info = mlxsw_afk_key_info_get(afk, elusage);
|
||||
if (IS_ERR(vregion->key_info)) {
|
||||
@ -856,7 +857,7 @@ mlxsw_sp_acl_tcam_vregion_get(struct mlxsw_sp *mlxsw_sp,
|
||||
*/
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
}
|
||||
vregion->ref_count++;
|
||||
refcount_inc(&vregion->ref_count);
|
||||
return vregion;
|
||||
}
|
||||
|
||||
@ -871,7 +872,7 @@ static void
|
||||
mlxsw_sp_acl_tcam_vregion_put(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp_acl_tcam_vregion *vregion)
|
||||
{
|
||||
if (--vregion->ref_count)
|
||||
if (!refcount_dec_and_test(&vregion->ref_count))
|
||||
return;
|
||||
mlxsw_sp_acl_tcam_vregion_destroy(mlxsw_sp, vregion);
|
||||
}
|
||||
@ -924,7 +925,7 @@ mlxsw_sp_acl_tcam_vchunk_create(struct mlxsw_sp *mlxsw_sp,
|
||||
INIT_LIST_HEAD(&vchunk->ventry_list);
|
||||
vchunk->priority = priority;
|
||||
vchunk->vgroup = vgroup;
|
||||
vchunk->ref_count = 1;
|
||||
refcount_set(&vchunk->ref_count, 1);
|
||||
|
||||
vregion = mlxsw_sp_acl_tcam_vregion_get(mlxsw_sp, vgroup,
|
||||
priority, elusage);
|
||||
@ -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,
|
||||
elusage)))
|
||||
return ERR_PTR(-EINVAL);
|
||||
vchunk->ref_count++;
|
||||
refcount_inc(&vchunk->ref_count);
|
||||
return vchunk;
|
||||
}
|
||||
return mlxsw_sp_acl_tcam_vchunk_create(mlxsw_sp, vgroup,
|
||||
@ -1019,7 +1020,7 @@ static void
|
||||
mlxsw_sp_acl_tcam_vchunk_put(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp_acl_tcam_vchunk *vchunk)
|
||||
{
|
||||
if (--vchunk->ref_count)
|
||||
if (!refcount_dec_and_test(&vchunk->ref_count))
|
||||
return;
|
||||
mlxsw_sp_acl_tcam_vchunk_destroy(mlxsw_sp, vchunk);
|
||||
}
|
||||
|
@ -501,7 +501,7 @@ struct mlxsw_sp_rt6 {
|
||||
|
||||
struct mlxsw_sp_lpm_tree {
|
||||
u8 id; /* tree ID */
|
||||
unsigned int ref_count;
|
||||
refcount_t ref_count;
|
||||
enum mlxsw_sp_l3proto proto;
|
||||
unsigned long prefix_ref_count[MLXSW_SP_PREFIX_COUNT];
|
||||
struct mlxsw_sp_prefix_usage prefix_usage;
|
||||
@ -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++) {
|
||||
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 NULL;
|
||||
@ -654,7 +654,7 @@ mlxsw_sp_lpm_tree_create(struct mlxsw_sp *mlxsw_sp,
|
||||
sizeof(lpm_tree->prefix_usage));
|
||||
memset(&lpm_tree->prefix_ref_count, 0,
|
||||
sizeof(lpm_tree->prefix_ref_count));
|
||||
lpm_tree->ref_count = 1;
|
||||
refcount_set(&lpm_tree->ref_count, 1);
|
||||
return lpm_tree;
|
||||
|
||||
err_left_struct_set:
|
||||
@ -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++) {
|
||||
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 &&
|
||||
mlxsw_sp_prefix_usage_eq(&lpm_tree->prefix_usage,
|
||||
prefix_usage)) {
|
||||
@ -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)
|
||||
{
|
||||
lpm_tree->ref_count++;
|
||||
refcount_inc(&lpm_tree->ref_count);
|
||||
}
|
||||
|
||||
static void mlxsw_sp_lpm_tree_put(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp_lpm_tree *lpm_tree)
|
||||
{
|
||||
if (--lpm_tree->ref_count == 0)
|
||||
mlxsw_sp_lpm_tree_destroy(mlxsw_sp, lpm_tree);
|
||||
if (!refcount_dec_and_test(&lpm_tree->ref_count))
|
||||
return;
|
||||
mlxsw_sp_lpm_tree_destroy(mlxsw_sp, lpm_tree);
|
||||
}
|
||||
|
||||
#define MLXSW_SP_LPM_TREE_MIN 1 /* tree 0 is reserved */
|
||||
|
@ -61,7 +61,7 @@ struct mlxsw_sp_bridge_port {
|
||||
struct mlxsw_sp_bridge_device *bridge_device;
|
||||
struct list_head list;
|
||||
struct list_head vlans_list;
|
||||
unsigned int ref_count;
|
||||
refcount_t ref_count;
|
||||
u8 stp_state;
|
||||
unsigned long flags;
|
||||
bool mrouter;
|
||||
@ -495,7 +495,7 @@ mlxsw_sp_bridge_port_create(struct mlxsw_sp_bridge_device *bridge_device,
|
||||
BR_MCAST_FLOOD;
|
||||
INIT_LIST_HEAD(&bridge_port->vlans_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,
|
||||
NULL, NULL, NULL, false, extack);
|
||||
@ -531,7 +531,7 @@ mlxsw_sp_bridge_port_get(struct mlxsw_sp_bridge *bridge,
|
||||
|
||||
bridge_port = mlxsw_sp_bridge_port_find(bridge, brport_dev);
|
||||
if (bridge_port) {
|
||||
bridge_port->ref_count++;
|
||||
refcount_inc(&bridge_port->ref_count);
|
||||
return bridge_port;
|
||||
}
|
||||
|
||||
@ -558,7 +558,7 @@ static void mlxsw_sp_bridge_port_put(struct mlxsw_sp_bridge *bridge,
|
||||
{
|
||||
struct mlxsw_sp_bridge_device *bridge_device;
|
||||
|
||||
if (--bridge_port->ref_count != 0)
|
||||
if (!refcount_dec_and_test(&bridge_port->ref_count))
|
||||
return;
|
||||
bridge_device = bridge_port->bridge_device;
|
||||
mlxsw_sp_bridge_port_destroy(bridge_port);
|
||||
|
Loading…
x
Reference in New Issue
Block a user