Commit 6f74a55d authored by David S. Miller's avatar David S. Miller

Merge tag 'mlx5-fixes-2019-10-24' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux

Saeed Mahameed says:

====================
Mellanox, mlx5 fixes 2019-10-24

This series introduces misc fixes to mlx5 driver.

v1->v2:
 - Dropped the kTLS counter documentation patch, Tariq will fix it and
   send it later.
 - Added a new fix for link speed mode reporting.
  ('net/mlx5e: Initialize link modes bitmap on stack')

For -stable v4.14
  ('net/mlx5e: Fix handling of compressed CQEs in case of low NAPI budget')

For -stable v4.19
  ('net/mlx5e: Fix ethtool self test: link speed')

For -stable v5.2
  ('net/mlx5: Fix flow counter list auto bits struct')
  ('net/mlx5: Fix rtable reference leak')

For -stable v5.3
  ('net/mlx5e: Remove incorrect match criteria assignment line')
  ('net/mlx5e: Determine source port properly for vlan push action')
  ('net/mlx5e: Initialize link modes bitmap on stack')
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 8b73018f 926b37f7
...@@ -141,7 +141,7 @@ int mlx5e_hv_vhca_stats_create(struct mlx5e_priv *priv) ...@@ -141,7 +141,7 @@ int mlx5e_hv_vhca_stats_create(struct mlx5e_priv *priv)
"Failed to create hv vhca stats agent, err = %ld\n", "Failed to create hv vhca stats agent, err = %ld\n",
PTR_ERR(agent)); PTR_ERR(agent));
kfree(priv->stats_agent.buf); kvfree(priv->stats_agent.buf);
return IS_ERR_OR_NULL(agent); return IS_ERR_OR_NULL(agent);
} }
...@@ -157,5 +157,5 @@ void mlx5e_hv_vhca_stats_destroy(struct mlx5e_priv *priv) ...@@ -157,5 +157,5 @@ void mlx5e_hv_vhca_stats_destroy(struct mlx5e_priv *priv)
return; return;
mlx5_hv_vhca_agent_destroy(priv->stats_agent.agent); mlx5_hv_vhca_agent_destroy(priv->stats_agent.agent);
kfree(priv->stats_agent.buf); kvfree(priv->stats_agent.buf);
} }
...@@ -97,15 +97,19 @@ static int mlx5e_route_lookup_ipv4(struct mlx5e_priv *priv, ...@@ -97,15 +97,19 @@ static int mlx5e_route_lookup_ipv4(struct mlx5e_priv *priv,
if (ret) if (ret)
return ret; return ret;
if (mlx5_lag_is_multipath(mdev) && rt->rt_gw_family != AF_INET) if (mlx5_lag_is_multipath(mdev) && rt->rt_gw_family != AF_INET) {
ip_rt_put(rt);
return -ENETUNREACH; return -ENETUNREACH;
}
#else #else
return -EOPNOTSUPP; return -EOPNOTSUPP;
#endif #endif
ret = get_route_and_out_devs(priv, rt->dst.dev, route_dev, out_dev); ret = get_route_and_out_devs(priv, rt->dst.dev, route_dev, out_dev);
if (ret < 0) if (ret < 0) {
ip_rt_put(rt);
return ret; return ret;
}
if (!(*out_ttl)) if (!(*out_ttl))
*out_ttl = ip4_dst_hoplimit(&rt->dst); *out_ttl = ip4_dst_hoplimit(&rt->dst);
...@@ -149,8 +153,10 @@ static int mlx5e_route_lookup_ipv6(struct mlx5e_priv *priv, ...@@ -149,8 +153,10 @@ static int mlx5e_route_lookup_ipv6(struct mlx5e_priv *priv,
*out_ttl = ip6_dst_hoplimit(dst); *out_ttl = ip6_dst_hoplimit(dst);
ret = get_route_and_out_devs(priv, dst->dev, route_dev, out_dev); ret = get_route_and_out_devs(priv, dst->dev, route_dev, out_dev);
if (ret < 0) if (ret < 0) {
dst_release(dst);
return ret; return ret;
}
#else #else
return -EOPNOTSUPP; return -EOPNOTSUPP;
#endif #endif
......
...@@ -1021,7 +1021,7 @@ static bool ext_link_mode_requested(const unsigned long *adver) ...@@ -1021,7 +1021,7 @@ static bool ext_link_mode_requested(const unsigned long *adver)
{ {
#define MLX5E_MIN_PTYS_EXT_LINK_MODE_BIT ETHTOOL_LINK_MODE_50000baseKR_Full_BIT #define MLX5E_MIN_PTYS_EXT_LINK_MODE_BIT ETHTOOL_LINK_MODE_50000baseKR_Full_BIT
int size = __ETHTOOL_LINK_MODE_MASK_NBITS - MLX5E_MIN_PTYS_EXT_LINK_MODE_BIT; int size = __ETHTOOL_LINK_MODE_MASK_NBITS - MLX5E_MIN_PTYS_EXT_LINK_MODE_BIT;
__ETHTOOL_DECLARE_LINK_MODE_MASK(modes); __ETHTOOL_DECLARE_LINK_MODE_MASK(modes) = {0,};
bitmap_set(modes, MLX5E_MIN_PTYS_EXT_LINK_MODE_BIT, size); bitmap_set(modes, MLX5E_MIN_PTYS_EXT_LINK_MODE_BIT, size);
return bitmap_intersects(modes, adver, __ETHTOOL_LINK_MODE_MASK_NBITS); return bitmap_intersects(modes, adver, __ETHTOOL_LINK_MODE_MASK_NBITS);
......
...@@ -611,8 +611,8 @@ static void mlx5e_rep_update_flows(struct mlx5e_priv *priv, ...@@ -611,8 +611,8 @@ static void mlx5e_rep_update_flows(struct mlx5e_priv *priv,
mutex_lock(&esw->offloads.encap_tbl_lock); mutex_lock(&esw->offloads.encap_tbl_lock);
encap_connected = !!(e->flags & MLX5_ENCAP_ENTRY_VALID); encap_connected = !!(e->flags & MLX5_ENCAP_ENTRY_VALID);
if (e->compl_result || (encap_connected == neigh_connected && if (e->compl_result < 0 || (encap_connected == neigh_connected &&
ether_addr_equal(e->h_dest, ha))) ether_addr_equal(e->h_dest, ha)))
goto unlock; goto unlock;
mlx5e_take_all_encap_flows(e, &flow_list); mlx5e_take_all_encap_flows(e, &flow_list);
......
...@@ -1386,8 +1386,11 @@ int mlx5e_poll_rx_cq(struct mlx5e_cq *cq, int budget) ...@@ -1386,8 +1386,11 @@ int mlx5e_poll_rx_cq(struct mlx5e_cq *cq, int budget)
if (unlikely(!test_bit(MLX5E_RQ_STATE_ENABLED, &rq->state))) if (unlikely(!test_bit(MLX5E_RQ_STATE_ENABLED, &rq->state)))
return 0; return 0;
if (rq->cqd.left) if (rq->cqd.left) {
work_done += mlx5e_decompress_cqes_cont(rq, cqwq, 0, budget); work_done += mlx5e_decompress_cqes_cont(rq, cqwq, 0, budget);
if (rq->cqd.left || work_done >= budget)
goto out;
}
cqe = mlx5_cqwq_get_cqe(cqwq); cqe = mlx5_cqwq_get_cqe(cqwq);
if (!cqe) { if (!cqe) {
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include <linux/udp.h> #include <linux/udp.h>
#include <net/udp.h> #include <net/udp.h>
#include "en.h" #include "en.h"
#include "en/port.h"
enum { enum {
MLX5E_ST_LINK_STATE, MLX5E_ST_LINK_STATE,
...@@ -80,22 +81,12 @@ static int mlx5e_test_link_state(struct mlx5e_priv *priv) ...@@ -80,22 +81,12 @@ static int mlx5e_test_link_state(struct mlx5e_priv *priv)
static int mlx5e_test_link_speed(struct mlx5e_priv *priv) static int mlx5e_test_link_speed(struct mlx5e_priv *priv)
{ {
u32 out[MLX5_ST_SZ_DW(ptys_reg)]; u32 speed;
u32 eth_proto_oper;
int i;
if (!netif_carrier_ok(priv->netdev)) if (!netif_carrier_ok(priv->netdev))
return 1; return 1;
if (mlx5_query_port_ptys(priv->mdev, out, sizeof(out), MLX5_PTYS_EN, 1)) return mlx5e_port_linkspeed(priv->mdev, &speed);
return 1;
eth_proto_oper = MLX5_GET(ptys_reg, out, eth_proto_oper);
for (i = 0; i < MLX5E_LINK_MODES_NUMBER; i++) {
if (eth_proto_oper & MLX5E_PROT_MASK(i))
return 0;
}
return 1;
} }
struct mlx5ehdr { struct mlx5ehdr {
......
...@@ -1278,8 +1278,10 @@ static void mlx5e_tc_del_fdb_flow(struct mlx5e_priv *priv, ...@@ -1278,8 +1278,10 @@ static void mlx5e_tc_del_fdb_flow(struct mlx5e_priv *priv,
mlx5_eswitch_del_vlan_action(esw, attr); mlx5_eswitch_del_vlan_action(esw, attr);
for (out_index = 0; out_index < MLX5_MAX_FLOW_FWD_VPORTS; out_index++) for (out_index = 0; out_index < MLX5_MAX_FLOW_FWD_VPORTS; out_index++)
if (attr->dests[out_index].flags & MLX5_ESW_DEST_ENCAP) if (attr->dests[out_index].flags & MLX5_ESW_DEST_ENCAP) {
mlx5e_detach_encap(priv, flow, out_index); mlx5e_detach_encap(priv, flow, out_index);
kfree(attr->parse_attr->tun_info[out_index]);
}
kvfree(attr->parse_attr); kvfree(attr->parse_attr);
if (attr->action & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR) if (attr->action & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR)
...@@ -1559,6 +1561,7 @@ static void mlx5e_encap_dealloc(struct mlx5e_priv *priv, struct mlx5e_encap_entr ...@@ -1559,6 +1561,7 @@ static void mlx5e_encap_dealloc(struct mlx5e_priv *priv, struct mlx5e_encap_entr
mlx5_packet_reformat_dealloc(priv->mdev, e->pkt_reformat); mlx5_packet_reformat_dealloc(priv->mdev, e->pkt_reformat);
} }
kfree(e->tun_info);
kfree(e->encap_header); kfree(e->encap_header);
kfree_rcu(e, rcu); kfree_rcu(e, rcu);
} }
...@@ -2972,6 +2975,13 @@ mlx5e_encap_get(struct mlx5e_priv *priv, struct encap_key *key, ...@@ -2972,6 +2975,13 @@ mlx5e_encap_get(struct mlx5e_priv *priv, struct encap_key *key,
return NULL; return NULL;
} }
static struct ip_tunnel_info *dup_tun_info(const struct ip_tunnel_info *tun_info)
{
size_t tun_size = sizeof(*tun_info) + tun_info->options_len;
return kmemdup(tun_info, tun_size, GFP_KERNEL);
}
static int mlx5e_attach_encap(struct mlx5e_priv *priv, static int mlx5e_attach_encap(struct mlx5e_priv *priv,
struct mlx5e_tc_flow *flow, struct mlx5e_tc_flow *flow,
struct net_device *mirred_dev, struct net_device *mirred_dev,
...@@ -3028,13 +3038,15 @@ static int mlx5e_attach_encap(struct mlx5e_priv *priv, ...@@ -3028,13 +3038,15 @@ static int mlx5e_attach_encap(struct mlx5e_priv *priv,
refcount_set(&e->refcnt, 1); refcount_set(&e->refcnt, 1);
init_completion(&e->res_ready); init_completion(&e->res_ready);
tun_info = dup_tun_info(tun_info);
if (!tun_info) {
err = -ENOMEM;
goto out_err_init;
}
e->tun_info = tun_info; e->tun_info = tun_info;
err = mlx5e_tc_tun_init_encap_attr(mirred_dev, priv, e, extack); err = mlx5e_tc_tun_init_encap_attr(mirred_dev, priv, e, extack);
if (err) { if (err)
kfree(e); goto out_err_init;
e = NULL;
goto out_err;
}
INIT_LIST_HEAD(&e->flows); INIT_LIST_HEAD(&e->flows);
hash_add_rcu(esw->offloads.encap_tbl, &e->encap_hlist, hash_key); hash_add_rcu(esw->offloads.encap_tbl, &e->encap_hlist, hash_key);
...@@ -3075,6 +3087,12 @@ static int mlx5e_attach_encap(struct mlx5e_priv *priv, ...@@ -3075,6 +3087,12 @@ static int mlx5e_attach_encap(struct mlx5e_priv *priv,
if (e) if (e)
mlx5e_encap_put(priv, e); mlx5e_encap_put(priv, e);
return err; return err;
out_err_init:
mutex_unlock(&esw->offloads.encap_tbl_lock);
kfree(tun_info);
kfree(e);
return err;
} }
static int parse_tc_vlan_action(struct mlx5e_priv *priv, static int parse_tc_vlan_action(struct mlx5e_priv *priv,
...@@ -3295,7 +3313,9 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, ...@@ -3295,7 +3313,9 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv,
} else if (encap) { } else if (encap) {
parse_attr->mirred_ifindex[attr->out_count] = parse_attr->mirred_ifindex[attr->out_count] =
out_dev->ifindex; out_dev->ifindex;
parse_attr->tun_info[attr->out_count] = info; parse_attr->tun_info[attr->out_count] = dup_tun_info(info);
if (!parse_attr->tun_info[attr->out_count])
return -ENOMEM;
encap = false; encap = false;
attr->dests[attr->out_count].flags |= attr->dests[attr->out_count].flags |=
MLX5_ESW_DEST_ENCAP; MLX5_ESW_DEST_ENCAP;
......
...@@ -285,7 +285,6 @@ mlx5_eswitch_add_fwd_rule(struct mlx5_eswitch *esw, ...@@ -285,7 +285,6 @@ mlx5_eswitch_add_fwd_rule(struct mlx5_eswitch *esw,
mlx5_eswitch_set_rule_source_port(esw, spec, attr); mlx5_eswitch_set_rule_source_port(esw, spec, attr);
spec->match_criteria_enable |= MLX5_MATCH_MISC_PARAMETERS;
if (attr->outer_match_level != MLX5_MATCH_NONE) if (attr->outer_match_level != MLX5_MATCH_NONE)
spec->match_criteria_enable |= MLX5_MATCH_OUTER_HEADERS; spec->match_criteria_enable |= MLX5_MATCH_OUTER_HEADERS;
......
...@@ -177,22 +177,32 @@ mlx5_eswitch_termtbl_actions_move(struct mlx5_flow_act *src, ...@@ -177,22 +177,32 @@ mlx5_eswitch_termtbl_actions_move(struct mlx5_flow_act *src,
memset(&src->vlan[1], 0, sizeof(src->vlan[1])); memset(&src->vlan[1], 0, sizeof(src->vlan[1]));
} }
static bool mlx5_eswitch_offload_is_uplink_port(const struct mlx5_eswitch *esw,
const struct mlx5_flow_spec *spec)
{
u32 port_mask, port_value;
if (MLX5_CAP_ESW_FLOWTABLE(esw->dev, flow_source))
return spec->flow_context.flow_source == MLX5_VPORT_UPLINK;
port_mask = MLX5_GET(fte_match_param, spec->match_criteria,
misc_parameters.source_port);
port_value = MLX5_GET(fte_match_param, spec->match_value,
misc_parameters.source_port);
return (port_mask & port_value & 0xffff) == MLX5_VPORT_UPLINK;
}
bool bool
mlx5_eswitch_termtbl_required(struct mlx5_eswitch *esw, mlx5_eswitch_termtbl_required(struct mlx5_eswitch *esw,
struct mlx5_flow_act *flow_act, struct mlx5_flow_act *flow_act,
struct mlx5_flow_spec *spec) struct mlx5_flow_spec *spec)
{ {
u32 port_mask = MLX5_GET(fte_match_param, spec->match_criteria,
misc_parameters.source_port);
u32 port_value = MLX5_GET(fte_match_param, spec->match_value,
misc_parameters.source_port);
if (!MLX5_CAP_ESW_FLOWTABLE_FDB(esw->dev, termination_table)) if (!MLX5_CAP_ESW_FLOWTABLE_FDB(esw->dev, termination_table))
return false; return false;
/* push vlan on RX */ /* push vlan on RX */
return (flow_act->action & MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH) && return (flow_act->action & MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH) &&
((port_mask & port_value) == MLX5_VPORT_UPLINK); mlx5_eswitch_offload_is_uplink_port(esw, spec);
} }
struct mlx5_flow_handle * struct mlx5_flow_handle *
......
...@@ -507,7 +507,8 @@ static int mlx5_cmd_set_fte(struct mlx5_core_dev *dev, ...@@ -507,7 +507,8 @@ static int mlx5_cmd_set_fte(struct mlx5_core_dev *dev,
MLX5_SET(dest_format_struct, in_dests, MLX5_SET(dest_format_struct, in_dests,
destination_eswitch_owner_vhca_id, destination_eswitch_owner_vhca_id,
dst->dest_attr.vport.vhca_id); dst->dest_attr.vport.vhca_id);
if (extended_dest) { if (extended_dest &&
dst->dest_attr.vport.pkt_reformat) {
MLX5_SET(dest_format_struct, in_dests, MLX5_SET(dest_format_struct, in_dests,
packet_reformat, packet_reformat,
!!(dst->dest_attr.vport.flags & !!(dst->dest_attr.vport.flags &
......
...@@ -1545,9 +1545,8 @@ struct mlx5_ifc_extended_dest_format_bits { ...@@ -1545,9 +1545,8 @@ struct mlx5_ifc_extended_dest_format_bits {
}; };
union mlx5_ifc_dest_format_struct_flow_counter_list_auto_bits { union mlx5_ifc_dest_format_struct_flow_counter_list_auto_bits {
struct mlx5_ifc_dest_format_struct_bits dest_format_struct; struct mlx5_ifc_extended_dest_format_bits extended_dest_format;
struct mlx5_ifc_flow_counter_list_bits flow_counter_list; struct mlx5_ifc_flow_counter_list_bits flow_counter_list;
u8 reserved_at_0[0x40];
}; };
struct mlx5_ifc_fte_match_param_bits { struct mlx5_ifc_fte_match_param_bits {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment