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

Merge branch 'mlx5-fixes' into main



Tariq Toukan says:

====================
mlx5 fixes 2024-06-27

This patchset provides fixes from the team to the mlx5 core and EN
drivers.

The first 3 patches by Daniel replace a buggy cap field with a newly
introduced one.

Patch 4 by Chris de-couples ingress ACL creation from a specific flow,
so it's invoked by other flows if needed.

Patch 5 by Jianbo fixes a possible missing cleanup of QoS objects.

Patches 6 and 7 by Leon fixes IPsec stats logic to better reflect the
traffic.

Series generated against:
commit 02ea3120 ("octeontx2-pf: Fix coverity and klockwork issues in octeon PF driver")

V2:
Fixed wrong cited SHA in patch 6.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents a6458ab7 e562f2d4
Loading
Loading
Loading
Loading
+35 −13
Original line number Diff line number Diff line
@@ -989,7 +989,12 @@ static void mlx5e_xfrm_update_stats(struct xfrm_state *x)
	struct mlx5e_ipsec_sa_entry *sa_entry = to_ipsec_sa_entry(x);
	struct mlx5e_ipsec_rule *ipsec_rule = &sa_entry->ipsec_rule;
	struct net *net = dev_net(x->xso.dev);
	u64 trailer_packets = 0, trailer_bytes = 0;
	u64 replay_packets = 0, replay_bytes = 0;
	u64 auth_packets = 0, auth_bytes = 0;
	u64 success_packets, success_bytes;
	u64 packets, bytes, lastuse;
	size_t headers;

	lockdep_assert(lockdep_is_held(&x->lock) ||
		       lockdep_is_held(&dev_net(x->xso.real_dev)->xfrm.xfrm_cfg_mutex) ||
@@ -999,26 +1004,43 @@ static void mlx5e_xfrm_update_stats(struct xfrm_state *x)
		return;

	if (sa_entry->attrs.dir == XFRM_DEV_OFFLOAD_IN) {
		mlx5_fc_query_cached(ipsec_rule->auth.fc, &bytes, &packets, &lastuse);
		x->stats.integrity_failed += packets;
		XFRM_ADD_STATS(net, LINUX_MIB_XFRMINSTATEPROTOERROR, packets);
		mlx5_fc_query_cached(ipsec_rule->auth.fc, &auth_bytes,
				     &auth_packets, &lastuse);
		x->stats.integrity_failed += auth_packets;
		XFRM_ADD_STATS(net, LINUX_MIB_XFRMINSTATEPROTOERROR, auth_packets);

		mlx5_fc_query_cached(ipsec_rule->trailer.fc, &bytes, &packets, &lastuse);
		XFRM_ADD_STATS(net, LINUX_MIB_XFRMINHDRERROR, packets);
		mlx5_fc_query_cached(ipsec_rule->trailer.fc, &trailer_bytes,
				     &trailer_packets, &lastuse);
		XFRM_ADD_STATS(net, LINUX_MIB_XFRMINHDRERROR, trailer_packets);
	}

	if (x->xso.type != XFRM_DEV_OFFLOAD_PACKET)
		return;

	mlx5_fc_query_cached(ipsec_rule->fc, &bytes, &packets, &lastuse);
	x->curlft.packets += packets;
	x->curlft.bytes += bytes;

	if (sa_entry->attrs.dir == XFRM_DEV_OFFLOAD_IN) {
		mlx5_fc_query_cached(ipsec_rule->replay.fc, &bytes, &packets, &lastuse);
		x->stats.replay += packets;
		XFRM_ADD_STATS(net, LINUX_MIB_XFRMINSTATESEQERROR, packets);
		mlx5_fc_query_cached(ipsec_rule->replay.fc, &replay_bytes,
				     &replay_packets, &lastuse);
		x->stats.replay += replay_packets;
		XFRM_ADD_STATS(net, LINUX_MIB_XFRMINSTATESEQERROR, replay_packets);
	}

	mlx5_fc_query_cached(ipsec_rule->fc, &bytes, &packets, &lastuse);
	success_packets = packets - auth_packets - trailer_packets - replay_packets;
	x->curlft.packets += success_packets;
	/* NIC counts all bytes passed through flow steering and doesn't have
	 * an ability to count payload data size which is needed for SA.
	 *
	 * To overcome HW limitestion, let's approximate the payload size
	 * by removing always available headers.
	 */
	headers = sizeof(struct ethhdr);
	if (sa_entry->attrs.family == AF_INET)
		headers += sizeof(struct iphdr);
	else
		headers += sizeof(struct ipv6hdr);

	success_bytes = bytes - auth_bytes - trailer_bytes - replay_bytes;
	x->curlft.bytes += success_bytes - headers * success_packets;
}

static int mlx5e_xfrm_validate_policy(struct mlx5_core_dev *mdev,
+5 −0
Original line number Diff line number Diff line
@@ -5868,6 +5868,11 @@ void mlx5e_priv_cleanup(struct mlx5e_priv *priv)
		kfree(priv->htb_qos_sq_stats[i]);
	kvfree(priv->htb_qos_sq_stats);

	if (priv->mqprio_rl) {
		mlx5e_mqprio_rl_cleanup(priv->mqprio_rl);
		mlx5e_mqprio_rl_free(priv->mqprio_rl);
	}

	memset(priv, 0, sizeof(*priv));
}

+1 −3
Original line number Diff line number Diff line
@@ -1197,9 +1197,7 @@ static int get_num_eqs(struct mlx5_core_dev *dev)
	if (!mlx5_core_is_eth_enabled(dev) && mlx5_eth_supported(dev))
		return 1;

	max_dev_eqs = MLX5_CAP_GEN(dev, max_num_eqs) ?
		      MLX5_CAP_GEN(dev, max_num_eqs) :
		      1 << MLX5_CAP_GEN(dev, log_max_eq);
	max_dev_eqs = mlx5_max_eq_cap_get(dev);

	num_eqs = min_t(int, mlx5_irq_table_get_num_comp(eq_table->irq_table),
			max_dev_eqs - MLX5_MAX_ASYNC_EQS);
+29 −8
Original line number Diff line number Diff line
@@ -6,6 +6,9 @@
#include "helper.h"
#include "ofld.h"

static int
acl_ingress_ofld_setup(struct mlx5_eswitch *esw, struct mlx5_vport *vport);

static bool
esw_acl_ingress_prio_tag_enabled(struct mlx5_eswitch *esw,
				 const struct mlx5_vport *vport)
@@ -123,18 +126,31 @@ static int esw_acl_ingress_src_port_drop_create(struct mlx5_eswitch *esw,
{
	struct mlx5_flow_act flow_act = {};
	struct mlx5_flow_handle *flow_rule;
	bool created = false;
	int err = 0;

	if (!vport->ingress.acl) {
		err = acl_ingress_ofld_setup(esw, vport);
		if (err)
			return err;
		created = true;
	}

	flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP;
	flow_act.fg = vport->ingress.offloads.drop_grp;
	flow_rule = mlx5_add_flow_rules(vport->ingress.acl, NULL, &flow_act, NULL, 0);
	if (IS_ERR(flow_rule)) {
		err = PTR_ERR(flow_rule);
		goto out;
		goto err_out;
	}

	vport->ingress.offloads.drop_rule = flow_rule;
out:

	return 0;
err_out:
	/* Only destroy ingress acl created in this function. */
	if (created)
		esw_acl_ingress_ofld_cleanup(esw, vport);
	return err;
}

@@ -299,16 +315,12 @@ static void esw_acl_ingress_ofld_groups_destroy(struct mlx5_vport *vport)
	}
}

int esw_acl_ingress_ofld_setup(struct mlx5_eswitch *esw,
			       struct mlx5_vport *vport)
static int
acl_ingress_ofld_setup(struct mlx5_eswitch *esw, struct mlx5_vport *vport)
{
	int num_ftes = 0;
	int err;

	if (!mlx5_eswitch_vport_match_metadata_enabled(esw) &&
	    !esw_acl_ingress_prio_tag_enabled(esw, vport))
		return 0;

	esw_acl_ingress_allow_rule_destroy(vport);

	if (mlx5_eswitch_vport_match_metadata_enabled(esw))
@@ -347,6 +359,15 @@ int esw_acl_ingress_ofld_setup(struct mlx5_eswitch *esw,
	return err;
}

int esw_acl_ingress_ofld_setup(struct mlx5_eswitch *esw, struct mlx5_vport *vport)
{
	if (!mlx5_eswitch_vport_match_metadata_enabled(esw) &&
	    !esw_acl_ingress_prio_tag_enabled(esw, vport))
		return 0;

	return acl_ingress_ofld_setup(esw, vport);
}

void esw_acl_ingress_ofld_cleanup(struct mlx5_eswitch *esw,
				  struct mlx5_vport *vport)
{
+17 −5
Original line number Diff line number Diff line
@@ -4600,20 +4600,26 @@ mlx5_devlink_port_fn_max_io_eqs_get(struct devlink_port *port, u32 *max_io_eqs,
		return -EOPNOTSUPP;
	}

	if (!MLX5_CAP_GEN_2(esw->dev, max_num_eqs_24b)) {
		NL_SET_ERR_MSG_MOD(extack,
				   "Device doesn't support getting the max number of EQs");
		return -EOPNOTSUPP;
	}

	query_ctx = kzalloc(query_out_sz, GFP_KERNEL);
	if (!query_ctx)
		return -ENOMEM;

	mutex_lock(&esw->state_lock);
	err = mlx5_vport_get_other_func_cap(esw->dev, vport_num, query_ctx,
					    MLX5_CAP_GENERAL);
					    MLX5_CAP_GENERAL_2);
	if (err) {
		NL_SET_ERR_MSG_MOD(extack, "Failed getting HCA caps");
		goto out;
	}

	hca_caps = MLX5_ADDR_OF(query_hca_cap_out, query_ctx, capability);
	max_eqs = MLX5_GET(cmd_hca_cap, hca_caps, max_num_eqs);
	max_eqs = MLX5_GET(cmd_hca_cap_2, hca_caps, max_num_eqs_24b);
	if (max_eqs < MLX5_ESW_MAX_CTRL_EQS)
		*max_io_eqs = 0;
	else
@@ -4644,6 +4650,12 @@ mlx5_devlink_port_fn_max_io_eqs_set(struct devlink_port *port, u32 max_io_eqs,
		return -EOPNOTSUPP;
	}

	if (!MLX5_CAP_GEN_2(esw->dev, max_num_eqs_24b)) {
		NL_SET_ERR_MSG_MOD(extack,
				   "Device doesn't support changing the max number of EQs");
		return -EOPNOTSUPP;
	}

	if (check_add_overflow(max_io_eqs, MLX5_ESW_MAX_CTRL_EQS, &max_eqs)) {
		NL_SET_ERR_MSG_MOD(extack, "Supplied value out of range");
		return -EINVAL;
@@ -4655,17 +4667,17 @@ mlx5_devlink_port_fn_max_io_eqs_set(struct devlink_port *port, u32 max_io_eqs,

	mutex_lock(&esw->state_lock);
	err = mlx5_vport_get_other_func_cap(esw->dev, vport_num, query_ctx,
					    MLX5_CAP_GENERAL);
					    MLX5_CAP_GENERAL_2);
	if (err) {
		NL_SET_ERR_MSG_MOD(extack, "Failed getting HCA caps");
		goto out;
	}

	hca_caps = MLX5_ADDR_OF(query_hca_cap_out, query_ctx, capability);
	MLX5_SET(cmd_hca_cap, hca_caps, max_num_eqs, max_eqs);
	MLX5_SET(cmd_hca_cap_2, hca_caps, max_num_eqs_24b, max_eqs);

	err = mlx5_vport_set_other_func_cap(esw->dev, hca_caps, vport_num,
					    MLX5_SET_HCA_CAP_OP_MOD_GENERAL_DEVICE);
					    MLX5_SET_HCA_CAP_OP_MOD_GENERAL_DEVICE2);
	if (err)
		NL_SET_ERR_MSG_MOD(extack, "Failed setting HCA caps");

Loading