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)
"Failed to create hv vhca stats agent, err = %ld\n",
PTR_ERR(agent));
kfree(priv->stats_agent.buf);
kvfree(priv->stats_agent.buf);
return IS_ERR_OR_NULL(agent);
}
......@@ -157,5 +157,5 @@ void mlx5e_hv_vhca_stats_destroy(struct mlx5e_priv *priv)
return;
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,
if (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;
}
#else
return -EOPNOTSUPP;
#endif
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;
}
if (!(*out_ttl))
*out_ttl = ip4_dst_hoplimit(&rt->dst);
......@@ -149,8 +153,10 @@ static int mlx5e_route_lookup_ipv6(struct mlx5e_priv *priv,
*out_ttl = ip6_dst_hoplimit(dst);
ret = get_route_and_out_devs(priv, dst->dev, route_dev, out_dev);
if (ret < 0)
if (ret < 0) {
dst_release(dst);
return ret;
}
#else
return -EOPNOTSUPP;
#endif
......
......@@ -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
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);
return bitmap_intersects(modes, adver, __ETHTOOL_LINK_MODE_MASK_NBITS);
......
......@@ -611,8 +611,8 @@ static void mlx5e_rep_update_flows(struct mlx5e_priv *priv,
mutex_lock(&esw->offloads.encap_tbl_lock);
encap_connected = !!(e->flags & MLX5_ENCAP_ENTRY_VALID);
if (e->compl_result || (encap_connected == neigh_connected &&
ether_addr_equal(e->h_dest, ha)))
if (e->compl_result < 0 || (encap_connected == neigh_connected &&
ether_addr_equal(e->h_dest, ha)))
goto unlock;
mlx5e_take_all_encap_flows(e, &flow_list);
......
......@@ -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)))
return 0;
if (rq->cqd.left)
if (rq->cqd.left) {
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);
if (!cqe) {
......
......@@ -35,6 +35,7 @@
#include <linux/udp.h>
#include <net/udp.h>
#include "en.h"
#include "en/port.h"
enum {
MLX5E_ST_LINK_STATE,
......@@ -80,22 +81,12 @@ static int mlx5e_test_link_state(struct mlx5e_priv *priv)
static int mlx5e_test_link_speed(struct mlx5e_priv *priv)
{
u32 out[MLX5_ST_SZ_DW(ptys_reg)];
u32 eth_proto_oper;
int i;
u32 speed;
if (!netif_carrier_ok(priv->netdev))
return 1;
if (mlx5_query_port_ptys(priv->mdev, out, sizeof(out), MLX5_PTYS_EN, 1))
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;
return mlx5e_port_linkspeed(priv->mdev, &speed);
}
struct mlx5ehdr {
......
......@@ -1278,8 +1278,10 @@ static void mlx5e_tc_del_fdb_flow(struct mlx5e_priv *priv,
mlx5_eswitch_del_vlan_action(esw, attr);
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);
kfree(attr->parse_attr->tun_info[out_index]);
}
kvfree(attr->parse_attr);
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
mlx5_packet_reformat_dealloc(priv->mdev, e->pkt_reformat);
}
kfree(e->tun_info);
kfree(e->encap_header);
kfree_rcu(e, rcu);
}
......@@ -2972,6 +2975,13 @@ mlx5e_encap_get(struct mlx5e_priv *priv, struct encap_key *key,
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,
struct mlx5e_tc_flow *flow,
struct net_device *mirred_dev,
......@@ -3028,13 +3038,15 @@ static int mlx5e_attach_encap(struct mlx5e_priv *priv,
refcount_set(&e->refcnt, 1);
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;
err = mlx5e_tc_tun_init_encap_attr(mirred_dev, priv, e, extack);
if (err) {
kfree(e);
e = NULL;
goto out_err;
}
if (err)
goto out_err_init;
INIT_LIST_HEAD(&e->flows);
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,
if (e)
mlx5e_encap_put(priv, e);
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,
......@@ -3295,7 +3313,9 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv,
} else if (encap) {
parse_attr->mirred_ifindex[attr->out_count] =
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;
attr->dests[attr->out_count].flags |=
MLX5_ESW_DEST_ENCAP;
......
......@@ -285,7 +285,6 @@ mlx5_eswitch_add_fwd_rule(struct mlx5_eswitch *esw,
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)
spec->match_criteria_enable |= MLX5_MATCH_OUTER_HEADERS;
......
......@@ -177,22 +177,32 @@ mlx5_eswitch_termtbl_actions_move(struct mlx5_flow_act *src,
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
mlx5_eswitch_termtbl_required(struct mlx5_eswitch *esw,
struct mlx5_flow_act *flow_act,
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))
return false;
/* push vlan on RX */
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 *
......
......@@ -507,7 +507,8 @@ static int mlx5_cmd_set_fte(struct mlx5_core_dev *dev,
MLX5_SET(dest_format_struct, in_dests,
destination_eswitch_owner_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,
packet_reformat,
!!(dst->dest_attr.vport.flags &
......
......@@ -1545,9 +1545,8 @@ struct mlx5_ifc_extended_dest_format_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;
u8 reserved_at_0[0x40];
};
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