Commit c101fffc authored by David S. Miller's avatar David S. Miller
Browse files

Merge tag 'mlx5-fixes-2020-01-06' of git://git.kernel.org/pub/scm/linux/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: default avatarDavid S. Miller <davem@davemloft.net>
parents d76063c5 df55c558
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -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 {
+4 −3
Original line number Diff line number Diff line
@@ -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);

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

	return devlink_health_report(reporter, err_str, err_ctx);
}
+0 −16
Original line number Diff line number Diff line
@@ -904,22 +904,6 @@ del_rules:
	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)
{
+58 −2
Original line number Diff line number Diff line
@@ -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;
}
@@ -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,
@@ -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);

@@ -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,
@@ -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;
@@ -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);
+15 −55
Original line number Diff line number Diff line
@@ -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;
@@ -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)
@@ -1633,47 +1625,22 @@ 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;

	if (take_write)
		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);
	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;
@@ -1681,19 +1648,12 @@ lookup_fte_for_read_locked(struct mlx5_flow_group *g, const u32 *match_value)
	}

	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 *
Loading