mirror of
https://github.com/torvalds/linux.git
synced 2026-05-28 09:04:39 +02:00
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 02ea312055 ("octeontx2-pf: Fix coverity and klockwork issues in octeon PF driver")
V2:
Fixed wrong cited SHA in patch 6.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
109e2f5b98
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
||||
|
|
|
|||
|
|
@ -383,4 +383,14 @@ static inline int mlx5_vport_to_func_id(const struct mlx5_core_dev *dev, u16 vpo
|
|||
: vport;
|
||||
}
|
||||
|
||||
static inline int mlx5_max_eq_cap_get(const struct mlx5_core_dev *dev)
|
||||
{
|
||||
if (MLX5_CAP_GEN_2(dev, max_num_eqs_24b))
|
||||
return MLX5_CAP_GEN_2(dev, max_num_eqs_24b);
|
||||
|
||||
if (MLX5_CAP_GEN(dev, max_num_eqs))
|
||||
return MLX5_CAP_GEN(dev, max_num_eqs);
|
||||
|
||||
return 1 << MLX5_CAP_GEN(dev, log_max_eq);
|
||||
}
|
||||
#endif /* __MLX5_CORE_H__ */
|
||||
|
|
|
|||
|
|
@ -711,9 +711,7 @@ int mlx5_irq_table_get_num_comp(struct mlx5_irq_table *table)
|
|||
|
||||
int mlx5_irq_table_create(struct mlx5_core_dev *dev)
|
||||
{
|
||||
int num_eqs = MLX5_CAP_GEN(dev, max_num_eqs) ?
|
||||
MLX5_CAP_GEN(dev, max_num_eqs) :
|
||||
1 << MLX5_CAP_GEN(dev, log_max_eq);
|
||||
int num_eqs = mlx5_max_eq_cap_get(dev);
|
||||
int total_vec;
|
||||
int pcif_vec;
|
||||
int req_vec;
|
||||
|
|
|
|||
|
|
@ -2029,7 +2029,11 @@ struct mlx5_ifc_cmd_hca_cap_2_bits {
|
|||
u8 pcc_ifa2[0x1];
|
||||
u8 reserved_at_3f1[0xf];
|
||||
|
||||
u8 reserved_at_400[0x400];
|
||||
u8 reserved_at_400[0x40];
|
||||
|
||||
u8 reserved_at_440[0x8];
|
||||
u8 max_num_eqs_24b[0x18];
|
||||
u8 reserved_at_460[0x3a0];
|
||||
};
|
||||
|
||||
enum mlx5_ifc_flow_destination_type {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user