Skip to content

Commit

Permalink
Merge tag 'mlx5-fixes-2020-01-06' of git://git.kernel.org/pub/scm/lin…
Browse files Browse the repository at this point in the history
…ux/kernel/git/saeed/linux

Saeed Mahameed says:

====================
Mellanox, mlx5 fixes 2020-01-06

This series introduces some fixes to mlx5 driver.

Please pull and let me know if there is any problem.

For -stable v5.3
 ('net/mlx5: Move devlink registration before interfaces load')

For -stable v5.4
 ('net/mlx5e: Fix hairpin RSS table size')
 ('net/mlx5: DR, Init lists that are used in rule's member')
 ('net/mlx5e: Always print health reporter message to dmesg')
 ('net/mlx5: DR, No need for atomic refcount for internal SW steering resources')
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Jan 7, 2020
2 parents d76063c + df55c55 commit c101fff
Show file tree
Hide file tree
Showing 10 changed files with 119 additions and 96 deletions.
16 changes: 16 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/en/fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,22 @@ enum {
#endif
};

#define MLX5E_TTC_NUM_GROUPS 3
#define MLX5E_TTC_GROUP1_SIZE (BIT(3) + MLX5E_NUM_TUNNEL_TT)
#define MLX5E_TTC_GROUP2_SIZE BIT(1)
#define MLX5E_TTC_GROUP3_SIZE BIT(0)
#define MLX5E_TTC_TABLE_SIZE (MLX5E_TTC_GROUP1_SIZE +\
MLX5E_TTC_GROUP2_SIZE +\
MLX5E_TTC_GROUP3_SIZE)

#define MLX5E_INNER_TTC_NUM_GROUPS 3
#define MLX5E_INNER_TTC_GROUP1_SIZE BIT(3)
#define MLX5E_INNER_TTC_GROUP2_SIZE BIT(1)
#define MLX5E_INNER_TTC_GROUP3_SIZE BIT(0)
#define MLX5E_INNER_TTC_TABLE_SIZE (MLX5E_INNER_TTC_GROUP1_SIZE +\
MLX5E_INNER_TTC_GROUP2_SIZE +\
MLX5E_INNER_TTC_GROUP3_SIZE)

#ifdef CONFIG_MLX5_EN_RXNFC

struct mlx5e_ethtool_table {
Expand Down
7 changes: 4 additions & 3 deletions drivers/net/ethernet/mellanox/mlx5/core/en/health.c
Original file line number Diff line number Diff line change
Expand Up @@ -197,9 +197,10 @@ int mlx5e_health_report(struct mlx5e_priv *priv,
struct devlink_health_reporter *reporter, char *err_str,
struct mlx5e_err_ctx *err_ctx)
{
if (!reporter) {
netdev_err(priv->netdev, err_str);
netdev_err(priv->netdev, err_str);

if (!reporter)
return err_ctx->recover(&err_ctx->ctx);
}

return devlink_health_report(reporter, err_str, err_ctx);
}
16 changes: 0 additions & 16 deletions drivers/net/ethernet/mellanox/mlx5/core/en_fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -904,22 +904,6 @@ static int mlx5e_generate_ttc_table_rules(struct mlx5e_priv *priv,
return err;
}

#define MLX5E_TTC_NUM_GROUPS 3
#define MLX5E_TTC_GROUP1_SIZE (BIT(3) + MLX5E_NUM_TUNNEL_TT)
#define MLX5E_TTC_GROUP2_SIZE BIT(1)
#define MLX5E_TTC_GROUP3_SIZE BIT(0)
#define MLX5E_TTC_TABLE_SIZE (MLX5E_TTC_GROUP1_SIZE +\
MLX5E_TTC_GROUP2_SIZE +\
MLX5E_TTC_GROUP3_SIZE)

#define MLX5E_INNER_TTC_NUM_GROUPS 3
#define MLX5E_INNER_TTC_GROUP1_SIZE BIT(3)
#define MLX5E_INNER_TTC_GROUP2_SIZE BIT(1)
#define MLX5E_INNER_TTC_GROUP3_SIZE BIT(0)
#define MLX5E_INNER_TTC_TABLE_SIZE (MLX5E_INNER_TTC_GROUP1_SIZE +\
MLX5E_INNER_TTC_GROUP2_SIZE +\
MLX5E_INNER_TTC_GROUP3_SIZE)

static int mlx5e_create_ttc_table_groups(struct mlx5e_ttc_table *ttc,
bool use_ipv)
{
Expand Down
60 changes: 58 additions & 2 deletions drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,7 @@ static void mlx5e_hairpin_set_ttc_params(struct mlx5e_hairpin *hp,
for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++)
ttc_params->indir_tirn[tt] = hp->indir_tirn[tt];

ft_attr->max_fte = MLX5E_NUM_TT;
ft_attr->max_fte = MLX5E_TTC_TABLE_SIZE;
ft_attr->level = MLX5E_TC_TTC_FT_LEVEL;
ft_attr->prio = MLX5E_TC_PRIO;
}
Expand Down Expand Up @@ -2999,6 +2999,25 @@ static struct ip_tunnel_info *dup_tun_info(const struct ip_tunnel_info *tun_info
return kmemdup(tun_info, tun_size, GFP_KERNEL);
}

static bool is_duplicated_encap_entry(struct mlx5e_priv *priv,
struct mlx5e_tc_flow *flow,
int out_index,
struct mlx5e_encap_entry *e,
struct netlink_ext_ack *extack)
{
int i;

for (i = 0; i < out_index; i++) {
if (flow->encaps[i].e != e)
continue;
NL_SET_ERR_MSG_MOD(extack, "can't duplicate encap action");
netdev_err(priv->netdev, "can't duplicate encap action\n");
return true;
}

return false;
}

static int mlx5e_attach_encap(struct mlx5e_priv *priv,
struct mlx5e_tc_flow *flow,
struct net_device *mirred_dev,
Expand Down Expand Up @@ -3034,6 +3053,12 @@ static int mlx5e_attach_encap(struct mlx5e_priv *priv,

/* must verify if encap is valid or not */
if (e) {
/* Check that entry was not already attached to this flow */
if (is_duplicated_encap_entry(priv, flow, out_index, e, extack)) {
err = -EOPNOTSUPP;
goto out_err;
}

mutex_unlock(&esw->offloads.encap_tbl_lock);
wait_for_completion(&e->res_ready);

Expand Down Expand Up @@ -3220,6 +3245,26 @@ bool mlx5e_is_valid_eswitch_fwd_dev(struct mlx5e_priv *priv,
same_hw_devs(priv, netdev_priv(out_dev));
}

static bool is_duplicated_output_device(struct net_device *dev,
struct net_device *out_dev,
int *ifindexes, int if_count,
struct netlink_ext_ack *extack)
{
int i;

for (i = 0; i < if_count; i++) {
if (ifindexes[i] == out_dev->ifindex) {
NL_SET_ERR_MSG_MOD(extack,
"can't duplicate output to same device");
netdev_err(dev, "can't duplicate output to same device: %s\n",
out_dev->name);
return true;
}
}

return false;
}

static int parse_tc_fdb_actions(struct mlx5e_priv *priv,
struct flow_action *flow_action,
struct mlx5e_tc_flow *flow,
Expand All @@ -3231,11 +3276,12 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv,
struct mlx5e_tc_flow_parse_attr *parse_attr = attr->parse_attr;
struct mlx5e_rep_priv *rpriv = priv->ppriv;
const struct ip_tunnel_info *info = NULL;
int ifindexes[MLX5_MAX_FLOW_FWD_VPORTS];
bool ft_flow = mlx5e_is_ft_flow(flow);
const struct flow_action_entry *act;
int err, i, if_count = 0;
bool encap = false;
u32 action = 0;
int err, i;

if (!flow_action_has_entries(flow_action))
return -EINVAL;
Expand Down Expand Up @@ -3312,6 +3358,16 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv,
struct net_device *uplink_dev = mlx5_eswitch_uplink_get_proto_dev(esw, REP_ETH);
struct net_device *uplink_upper;

if (is_duplicated_output_device(priv->netdev,
out_dev,
ifindexes,
if_count,
extack))
return -EOPNOTSUPP;

ifindexes[if_count] = out_dev->ifindex;
if_count++;

rcu_read_lock();
uplink_upper =
netdev_master_upper_dev_get_rcu(uplink_dev);
Expand Down
70 changes: 15 additions & 55 deletions drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -531,16 +531,9 @@ static void del_hw_fte(struct fs_node *node)
}
}

static void del_sw_fte_rcu(struct rcu_head *head)
{
struct fs_fte *fte = container_of(head, struct fs_fte, rcu);
struct mlx5_flow_steering *steering = get_steering(&fte->node);

kmem_cache_free(steering->ftes_cache, fte);
}

static void del_sw_fte(struct fs_node *node)
{
struct mlx5_flow_steering *steering = get_steering(node);
struct mlx5_flow_group *fg;
struct fs_fte *fte;
int err;
Expand All @@ -553,8 +546,7 @@ static void del_sw_fte(struct fs_node *node)
rhash_fte);
WARN_ON(err);
ida_simple_remove(&fg->fte_allocator, fte->index - fg->start_index);

call_rcu(&fte->rcu, del_sw_fte_rcu);
kmem_cache_free(steering->ftes_cache, fte);
}

static void del_hw_flow_group(struct fs_node *node)
Expand Down Expand Up @@ -1633,67 +1625,35 @@ static u64 matched_fgs_get_version(struct list_head *match_head)
}

static struct fs_fte *
lookup_fte_for_write_locked(struct mlx5_flow_group *g, const u32 *match_value)
lookup_fte_locked(struct mlx5_flow_group *g,
const u32 *match_value,
bool take_write)
{
struct fs_fte *fte_tmp;

nested_down_write_ref_node(&g->node, FS_LOCK_PARENT);

fte_tmp = rhashtable_lookup_fast(&g->ftes_hash, match_value, rhash_fte);
if (!fte_tmp || !tree_get_node(&fte_tmp->node)) {
fte_tmp = NULL;
goto out;
}

if (!fte_tmp->node.active) {
tree_put_node(&fte_tmp->node, false);
fte_tmp = NULL;
goto out;
}
nested_down_write_ref_node(&fte_tmp->node, FS_LOCK_CHILD);

out:
up_write_ref_node(&g->node, false);
return fte_tmp;
}

static struct fs_fte *
lookup_fte_for_read_locked(struct mlx5_flow_group *g, const u32 *match_value)
{
struct fs_fte *fte_tmp;

if (!tree_get_node(&g->node))
return NULL;

rcu_read_lock();
fte_tmp = rhashtable_lookup(&g->ftes_hash, match_value, rhash_fte);
if (take_write)
nested_down_write_ref_node(&g->node, FS_LOCK_PARENT);
else
nested_down_read_ref_node(&g->node, FS_LOCK_PARENT);
fte_tmp = rhashtable_lookup_fast(&g->ftes_hash, match_value,
rhash_fte);
if (!fte_tmp || !tree_get_node(&fte_tmp->node)) {
rcu_read_unlock();
fte_tmp = NULL;
goto out;
}
rcu_read_unlock();

if (!fte_tmp->node.active) {
tree_put_node(&fte_tmp->node, false);
fte_tmp = NULL;
goto out;
}

nested_down_write_ref_node(&fte_tmp->node, FS_LOCK_CHILD);

out:
tree_put_node(&g->node, false);
return fte_tmp;
}

static struct fs_fte *
lookup_fte_locked(struct mlx5_flow_group *g, const u32 *match_value, bool write)
{
if (write)
return lookup_fte_for_write_locked(g, match_value);
if (take_write)
up_write_ref_node(&g->node, false);
else
return lookup_fte_for_read_locked(g, match_value);
up_read_ref_node(&g->node);
return fte_tmp;
}

static struct mlx5_flow_handle *
Expand Down
1 change: 0 additions & 1 deletion drivers/net/ethernet/mellanox/mlx5/core/fs_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,6 @@ struct fs_fte {
enum fs_fte_status status;
struct mlx5_fc *counter;
struct rhash_head hash;
struct rcu_head rcu;
int modify_mask;
};

Expand Down
16 changes: 9 additions & 7 deletions drivers/net/ethernet/mellanox/mlx5/core/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1193,6 +1193,12 @@ int mlx5_load_one(struct mlx5_core_dev *dev, bool boot)
if (err)
goto err_load;

if (boot) {
err = mlx5_devlink_register(priv_to_devlink(dev), dev->device);
if (err)
goto err_devlink_reg;
}

if (mlx5_device_registered(dev)) {
mlx5_attach_device(dev);
} else {
Expand All @@ -1210,6 +1216,9 @@ int mlx5_load_one(struct mlx5_core_dev *dev, bool boot)
return err;

err_reg_dev:
if (boot)
mlx5_devlink_unregister(priv_to_devlink(dev));
err_devlink_reg:
mlx5_unload(dev);
err_load:
if (boot)
Expand Down Expand Up @@ -1347,20 +1356,13 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *id)

request_module_nowait(MLX5_IB_MOD);

err = mlx5_devlink_register(devlink, &pdev->dev);
if (err)
goto clean_load;

err = mlx5_crdump_enable(dev);
if (err)
dev_err(&pdev->dev, "mlx5_crdump_enable failed with error code %d\n", err);

pci_save_state(pdev);
return 0;

clean_load:
mlx5_unload_one(dev, true);

err_load_one:
mlx5_pci_close(dev);
pci_init_err:
Expand Down
5 changes: 4 additions & 1 deletion drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -638,6 +638,9 @@ static int dr_rule_add_member(struct mlx5dr_rule_rx_tx *nic_rule,
if (!rule_mem)
return -ENOMEM;

INIT_LIST_HEAD(&rule_mem->list);
INIT_LIST_HEAD(&rule_mem->use_ste_list);

rule_mem->ste = ste;
list_add_tail(&rule_mem->list, &nic_rule->rule_members_list);

Expand Down
10 changes: 5 additions & 5 deletions drivers/net/ethernet/mellanox/mlx5/core/steering/dr_ste.c
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,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);
Expand Down Expand Up @@ -565,7 +565,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 */
Expand Down Expand Up @@ -689,14 +689,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);
Expand All @@ -713,7 +713,7 @@ struct mlx5dr_ste_htbl *mlx5dr_ste_htbl_alloc(struct mlx5dr_icm_pool *pool,

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);
Expand Down
Loading

0 comments on commit c101fff

Please sign in to comment.