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

Merge tag 'mlx5-updates-2021-11-16' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux



Saeed Mahameed says:

====================
mlx5-updates-2021-11-16

Updates for mlx5 driver:

1) Support ethtool cq mode
2) Static allocation of mod header object for the common case
3) TC support for when local and remote VTEPs are in the same
4) Create E-Switch QoS objects on demand to save on resources
5) Minor code improvements
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents b9241f54 85c5f7c9
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -1148,9 +1148,12 @@ void mlx5e_ethtool_get_channels(struct mlx5e_priv *priv,
int mlx5e_ethtool_set_channels(struct mlx5e_priv *priv,
			       struct ethtool_channels *ch);
int mlx5e_ethtool_get_coalesce(struct mlx5e_priv *priv,
			       struct ethtool_coalesce *coal);
			       struct ethtool_coalesce *coal,
			       struct kernel_ethtool_coalesce *kernel_coal);
int mlx5e_ethtool_set_coalesce(struct mlx5e_priv *priv,
			       struct ethtool_coalesce *coal);
			       struct ethtool_coalesce *coal,
			       struct kernel_ethtool_coalesce *kernel_coal,
			       struct netlink_ext_ack *extack);
int mlx5e_ethtool_get_link_ksettings(struct mlx5e_priv *priv,
				     struct ethtool_link_ksettings *link_ksettings);
int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv,
+58 −0
Original line number Diff line number Diff line
@@ -155,3 +155,61 @@ struct mlx5_modify_hdr *mlx5e_mod_hdr_get(struct mlx5e_mod_hdr_handle *mh)
	return mh->modify_hdr;
}

char *
mlx5e_mod_hdr_alloc(struct mlx5_core_dev *mdev, int namespace,
		    struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts)
{
	int new_num_actions, max_hw_actions;
	size_t new_sz, old_sz;
	void *ret;

	if (mod_hdr_acts->num_actions < mod_hdr_acts->max_actions)
		goto out;

	max_hw_actions = mlx5e_mod_hdr_max_actions(mdev, namespace);
	new_num_actions = min(max_hw_actions,
			      mod_hdr_acts->actions ?
			      mod_hdr_acts->max_actions * 2 : 1);
	if (mod_hdr_acts->max_actions == new_num_actions)
		return ERR_PTR(-ENOSPC);

	new_sz = MLX5_MH_ACT_SZ * new_num_actions;
	old_sz = mod_hdr_acts->max_actions * MLX5_MH_ACT_SZ;

	if (mod_hdr_acts->is_static) {
		ret = kzalloc(new_sz, GFP_KERNEL);
		if (ret) {
			memcpy(ret, mod_hdr_acts->actions, old_sz);
			mod_hdr_acts->is_static = false;
		}
	} else {
		ret = krealloc(mod_hdr_acts->actions, new_sz, GFP_KERNEL);
		if (ret)
			memset(ret + old_sz, 0, new_sz - old_sz);
	}
	if (!ret)
		return ERR_PTR(-ENOMEM);

	mod_hdr_acts->actions = ret;
	mod_hdr_acts->max_actions = new_num_actions;

out:
	return mod_hdr_acts->actions + (mod_hdr_acts->num_actions * MLX5_MH_ACT_SZ);
}

void
mlx5e_mod_hdr_dealloc(struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts)
{
	if (!mod_hdr_acts->is_static)
		kfree(mod_hdr_acts->actions);

	mod_hdr_acts->actions = NULL;
	mod_hdr_acts->num_actions = 0;
	mod_hdr_acts->max_actions = 0;
}

char *
mlx5e_mod_hdr_get_item(struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts, int pos)
{
	return mod_hdr_acts->actions + (pos * MLX5_MH_ACT_SZ);
}
+26 −0
Original line number Diff line number Diff line
@@ -7,14 +7,32 @@
#include <linux/hashtable.h>
#include <linux/mlx5/fs.h>

#define MLX5_MH_ACT_SZ MLX5_UN_SZ_BYTES(set_add_copy_action_in_auto)

struct mlx5e_mod_hdr_handle;

struct mlx5e_tc_mod_hdr_acts {
	int num_actions;
	int max_actions;
	bool is_static;
	void *actions;
};

#define DECLARE_MOD_HDR_ACTS_ACTIONS(name, len) \
	u8 name[len][MLX5_MH_ACT_SZ] = {}

#define DECLARE_MOD_HDR_ACTS(name, acts_arr) \
	struct mlx5e_tc_mod_hdr_acts name = { \
		.max_actions = ARRAY_SIZE(acts_arr), \
		.is_static = true, \
		.actions = acts_arr, \
	}

char *mlx5e_mod_hdr_alloc(struct mlx5_core_dev *mdev, int namespace,
			  struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts);
void mlx5e_mod_hdr_dealloc(struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts);
char *mlx5e_mod_hdr_get_item(struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts, int pos);

struct mlx5e_mod_hdr_handle *
mlx5e_mod_hdr_attach(struct mlx5_core_dev *mdev,
		     struct mod_hdr_tbl *tbl,
@@ -28,4 +46,12 @@ struct mlx5_modify_hdr *mlx5e_mod_hdr_get(struct mlx5e_mod_hdr_handle *mh);
void mlx5e_mod_hdr_tbl_init(struct mod_hdr_tbl *tbl);
void mlx5e_mod_hdr_tbl_destroy(struct mod_hdr_tbl *tbl);

static inline int mlx5e_mod_hdr_max_actions(struct mlx5_core_dev *mdev, int namespace)
{
	if (namespace == MLX5_FLOW_NAMESPACE_FDB) /* FDB offloading */
		return MLX5_CAP_ESW_FLOWTABLE_FDB(mdev, max_modify_header_actions);
	else /* namespace is MLX5_FLOW_NAMESPACE_KERNEL - NIC offloading */
		return MLX5_CAP_FLOWTABLE_NIC_RX(mdev, max_modify_header_actions);
}

#endif /* __MLX5E_EN_MOD_HDR_H__ */
+3 −2
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@
#include <net/psample.h>
#include "en/mapping.h"
#include "en/tc/post_act.h"
#include "en/mod_hdr.h"
#include "sample.h"
#include "eswitch.h"
#include "en_tc.h"
@@ -255,12 +256,12 @@ sample_modify_hdr_get(struct mlx5_core_dev *mdev, u32 obj_id,
		goto err_modify_hdr;
	}

	dealloc_mod_hdr_actions(&mod_acts);
	mlx5e_mod_hdr_dealloc(&mod_acts);
	return modify_hdr;

err_modify_hdr:
err_post_act:
	dealloc_mod_hdr_actions(&mod_acts);
	mlx5e_mod_hdr_dealloc(&mod_acts);
err_set_regc0:
	return ERR_PTR(err);
}
+18 −21
Original line number Diff line number Diff line
@@ -36,6 +36,12 @@
#define MLX5_CT_LABELS_BITS (mlx5e_tc_attr_to_reg_mappings[LABELS_TO_REG].mlen)
#define MLX5_CT_LABELS_MASK GENMASK(MLX5_CT_LABELS_BITS - 1, 0)

/* Statically allocate modify actions for
 * ipv6 and port nat (5) + tuple fields (4) + nic mode zone restore (1) = 10.
 * This will be increased dynamically if needed (for the ipv6 snat + dnat).
 */
#define MLX5_CT_MIN_MOD_ACTS 10

#define ct_dbg(fmt, args...)\
	netdev_dbg(ct_priv->netdev, "ct_debug: " fmt "\n", ##args)

@@ -609,22 +615,15 @@ mlx5_tc_ct_entry_create_nat(struct mlx5_tc_ct_priv *ct_priv,
	struct flow_action *flow_action = &flow_rule->action;
	struct mlx5_core_dev *mdev = ct_priv->dev;
	struct flow_action_entry *act;
	size_t action_size;
	char *modact;
	int err, i;

	action_size = MLX5_UN_SZ_BYTES(set_add_copy_action_in_auto);

	flow_action_for_each(i, act, flow_action) {
		switch (act->id) {
		case FLOW_ACTION_MANGLE: {
			err = alloc_mod_hdr_actions(mdev, ct_priv->ns_type,
						    mod_acts);
			if (err)
				return err;

			modact = mod_acts->actions +
				 mod_acts->num_actions * action_size;
			modact = mlx5e_mod_hdr_alloc(mdev, ct_priv->ns_type, mod_acts);
			if (IS_ERR(modact))
				return PTR_ERR(modact);

			err = mlx5_tc_ct_parse_mangle_to_mod_act(act, modact);
			if (err)
@@ -652,7 +651,8 @@ mlx5_tc_ct_entry_create_mod_hdr(struct mlx5_tc_ct_priv *ct_priv,
				struct mlx5e_mod_hdr_handle **mh,
				u8 zone_restore_id, bool nat)
{
	struct mlx5e_tc_mod_hdr_acts mod_acts = {};
	DECLARE_MOD_HDR_ACTS_ACTIONS(actions_arr, MLX5_CT_MIN_MOD_ACTS);
	DECLARE_MOD_HDR_ACTS(mod_acts, actions_arr);
	struct flow_action_entry *meta;
	u16 ct_state = 0;
	int err;
@@ -706,11 +706,11 @@ mlx5_tc_ct_entry_create_mod_hdr(struct mlx5_tc_ct_priv *ct_priv,
		attr->modify_hdr = mlx5e_mod_hdr_get(*mh);
	}

	dealloc_mod_hdr_actions(&mod_acts);
	mlx5e_mod_hdr_dealloc(&mod_acts);
	return 0;

err_mapping:
	dealloc_mod_hdr_actions(&mod_acts);
	mlx5e_mod_hdr_dealloc(&mod_acts);
	mlx5_put_label_mapping(ct_priv, attr->ct_attr.ct_labels_id);
	return err;
}
@@ -907,12 +907,9 @@ mlx5_tc_ct_shared_counter_get(struct mlx5_tc_ct_priv *ct_priv,
	struct mlx5_ct_tuple rev_tuple = entry->tuple;
	struct mlx5_ct_counter *shared_counter;
	struct mlx5_ct_entry *rev_entry;
	__be16 tmp_port;

	/* get the reversed tuple */
	tmp_port = rev_tuple.port.src;
	rev_tuple.port.src = rev_tuple.port.dst;
	rev_tuple.port.dst = tmp_port;
	swap(rev_tuple.port.src, rev_tuple.port.dst);

	if (rev_tuple.addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS) {
		__be32 tmp_addr = rev_tuple.ip.src_v4;
@@ -1445,7 +1442,7 @@ static int tc_ct_pre_ct_add_rules(struct mlx5_ct_ft *ct_ft,
	}
	pre_ct->miss_rule = rule;

	dealloc_mod_hdr_actions(&pre_mod_acts);
	mlx5e_mod_hdr_dealloc(&pre_mod_acts);
	kvfree(spec);
	return 0;

@@ -1454,7 +1451,7 @@ static int tc_ct_pre_ct_add_rules(struct mlx5_ct_ft *ct_ft,
err_flow_rule:
	mlx5_modify_header_dealloc(dev, pre_ct->modify_hdr);
err_mapping:
	dealloc_mod_hdr_actions(&pre_mod_acts);
	mlx5e_mod_hdr_dealloc(&pre_mod_acts);
	kvfree(spec);
	return err;
}
@@ -1850,14 +1847,14 @@ __mlx5_tc_ct_flow_offload(struct mlx5_tc_ct_priv *ct_priv,
	}

	attr->ct_attr.ct_flow = ct_flow;
	dealloc_mod_hdr_actions(&pre_mod_acts);
	mlx5e_mod_hdr_dealloc(&pre_mod_acts);

	return ct_flow->pre_ct_rule;

err_insert_orig:
	mlx5_modify_header_dealloc(priv->mdev, pre_ct_attr->modify_hdr);
err_mapping:
	dealloc_mod_hdr_actions(&pre_mod_acts);
	mlx5e_mod_hdr_dealloc(&pre_mod_acts);
	mlx5_chains_put_chain_mapping(ct_priv->chains, ct_flow->chain_mapping);
err_get_chain:
	kfree(ct_flow->pre_ct_attr);
Loading