Commit ee661a4a authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge tag 'mlx5-fixes-2020-11-03' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux

Saeed Mahameed says:

====================
mlx5 fixes 2020-11-03

v1->v2:
 - Fix fixes line tag in patch #1
 - Toss ktls refcount leak fix, Maxim will look further into the root
   cause.
 - Toss eswitch chain 0 prio patch, until we determine if it is needed
   for -rc and net.

* tag 'mlx5-fixes-2020-11-03' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux:
  net/mlx5e: Fix incorrect access of RCU-protected xdp_prog
  net/mlx5e: Fix VXLAN synchronization after function reload
  net/mlx5: E-switch, Avoid extack error log for disabled vport
  net/mlx5: Fix deletion of duplicate rules
  net/mlx5e: Use spin_lock_bh for async_icosq_lock
  net/mlx5e: Protect encap route dev from concurrent release
  net/mlx5e: Fix modify header actions memory leak
====================

Link: https://lore.kernel.org/r/20201105202129.23644-1-saeedm@nvidia.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 847f0a2b 1a50cf9a
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -107,12 +107,16 @@ void mlx5e_rep_update_flows(struct mlx5e_priv *priv,
		mlx5e_tc_encap_flows_del(priv, e, &flow_list);

	if (neigh_connected && !(e->flags & MLX5_ENCAP_ENTRY_VALID)) {
		struct net_device *route_dev;

		ether_addr_copy(e->h_dest, ha);
		ether_addr_copy(eth->h_dest, ha);
		/* Update the encap source mac, in case that we delete
		 * the flows when encap source mac changed.
		 */
		ether_addr_copy(eth->h_source, e->route_dev->dev_addr);
		route_dev = __dev_get_by_index(dev_net(priv->netdev), e->route_dev_ifindex);
		if (route_dev)
			ether_addr_copy(eth->h_source, route_dev->dev_addr);

		mlx5e_tc_encap_flows_add(priv, e, &flow_list);
	}
+46 −26
Original line number Diff line number Diff line
@@ -77,7 +77,7 @@ static int get_route_and_out_devs(struct mlx5e_priv *priv,
	return 0;
}

static int mlx5e_route_lookup_ipv4(struct mlx5e_priv *priv,
static int mlx5e_route_lookup_ipv4_get(struct mlx5e_priv *priv,
				       struct net_device *mirred_dev,
				       struct net_device **out_dev,
				       struct net_device **route_dev,
@@ -117,18 +117,28 @@ static int mlx5e_route_lookup_ipv4(struct mlx5e_priv *priv,
		ip_rt_put(rt);
		return ret;
	}
	dev_hold(*route_dev);

	if (!(*out_ttl))
		*out_ttl = ip4_dst_hoplimit(&rt->dst);
	n = dst_neigh_lookup(&rt->dst, &fl4->daddr);
	ip_rt_put(rt);
	if (!n)
	if (!n) {
		dev_put(*route_dev);
		return -ENOMEM;
	}

	*out_n = n;
	return 0;
}

static void mlx5e_route_lookup_ipv4_put(struct net_device *route_dev,
					struct neighbour *n)
{
	neigh_release(n);
	dev_put(route_dev);
}

static const char *mlx5e_netdev_kind(struct net_device *dev)
{
	if (dev->rtnl_link_ops)
@@ -193,7 +203,7 @@ int mlx5e_tc_tun_create_header_ipv4(struct mlx5e_priv *priv,
	fl4.saddr = tun_key->u.ipv4.src;
	ttl = tun_key->ttl;

	err = mlx5e_route_lookup_ipv4(priv, mirred_dev, &out_dev, &route_dev,
	err = mlx5e_route_lookup_ipv4_get(priv, mirred_dev, &out_dev, &route_dev,
					  &fl4, &n, &ttl);
	if (err)
		return err;
@@ -223,7 +233,7 @@ int mlx5e_tc_tun_create_header_ipv4(struct mlx5e_priv *priv,
	e->m_neigh.family = n->ops->family;
	memcpy(&e->m_neigh.dst_ip, n->primary_key, n->tbl->key_len);
	e->out_dev = out_dev;
	e->route_dev = route_dev;
	e->route_dev_ifindex = route_dev->ifindex;

	/* It's important to add the neigh to the hash table before checking
	 * the neigh validity state. So if we'll get a notification, in case the
@@ -278,7 +288,7 @@ int mlx5e_tc_tun_create_header_ipv4(struct mlx5e_priv *priv,

	e->flags |= MLX5_ENCAP_ENTRY_VALID;
	mlx5e_rep_queue_neigh_stats_work(netdev_priv(out_dev));
	neigh_release(n);
	mlx5e_route_lookup_ipv4_put(route_dev, n);
	return err;

destroy_neigh_entry:
@@ -286,12 +296,12 @@ int mlx5e_tc_tun_create_header_ipv4(struct mlx5e_priv *priv,
free_encap:
	kfree(encap_header);
release_neigh:
	neigh_release(n);
	mlx5e_route_lookup_ipv4_put(route_dev, n);
	return err;
}

#if IS_ENABLED(CONFIG_INET) && IS_ENABLED(CONFIG_IPV6)
static int mlx5e_route_lookup_ipv6(struct mlx5e_priv *priv,
static int mlx5e_route_lookup_ipv6_get(struct mlx5e_priv *priv,
				       struct net_device *mirred_dev,
				       struct net_device **out_dev,
				       struct net_device **route_dev,
@@ -318,15 +328,25 @@ static int mlx5e_route_lookup_ipv6(struct mlx5e_priv *priv,
		return ret;
	}

	dev_hold(*route_dev);
	n = dst_neigh_lookup(dst, &fl6->daddr);
	dst_release(dst);
	if (!n)
	if (!n) {
		dev_put(*route_dev);
		return -ENOMEM;
	}

	*out_n = n;
	return 0;
}

static void mlx5e_route_lookup_ipv6_put(struct net_device *route_dev,
					struct neighbour *n)
{
	neigh_release(n);
	dev_put(route_dev);
}

int mlx5e_tc_tun_create_header_ipv6(struct mlx5e_priv *priv,
				    struct net_device *mirred_dev,
				    struct mlx5e_encap_entry *e)
@@ -348,7 +368,7 @@ int mlx5e_tc_tun_create_header_ipv6(struct mlx5e_priv *priv,
	fl6.daddr = tun_key->u.ipv6.dst;
	fl6.saddr = tun_key->u.ipv6.src;

	err = mlx5e_route_lookup_ipv6(priv, mirred_dev, &out_dev, &route_dev,
	err = mlx5e_route_lookup_ipv6_get(priv, mirred_dev, &out_dev, &route_dev,
					  &fl6, &n, &ttl);
	if (err)
		return err;
@@ -378,7 +398,7 @@ int mlx5e_tc_tun_create_header_ipv6(struct mlx5e_priv *priv,
	e->m_neigh.family = n->ops->family;
	memcpy(&e->m_neigh.dst_ip, n->primary_key, n->tbl->key_len);
	e->out_dev = out_dev;
	e->route_dev = route_dev;
	e->route_dev_ifindex = route_dev->ifindex;

	/* It's importent to add the neigh to the hash table before checking
	 * the neigh validity state. So if we'll get a notification, in case the
@@ -433,7 +453,7 @@ int mlx5e_tc_tun_create_header_ipv6(struct mlx5e_priv *priv,

	e->flags |= MLX5_ENCAP_ENTRY_VALID;
	mlx5e_rep_queue_neigh_stats_work(netdev_priv(out_dev));
	neigh_release(n);
	mlx5e_route_lookup_ipv6_put(route_dev, n);
	return err;

destroy_neigh_entry:
@@ -441,7 +461,7 @@ int mlx5e_tc_tun_create_header_ipv6(struct mlx5e_priv *priv,
free_encap:
	kfree(encap_header);
release_neigh:
	neigh_release(n);
	mlx5e_route_lookup_ipv6_put(route_dev, n);
	return err;
}
#endif
+2 −2
Original line number Diff line number Diff line
@@ -122,9 +122,9 @@ void mlx5e_activate_xsk(struct mlx5e_channel *c)
	set_bit(MLX5E_RQ_STATE_ENABLED, &c->xskrq.state);
	/* TX queue is created active. */

	spin_lock(&c->async_icosq_lock);
	spin_lock_bh(&c->async_icosq_lock);
	mlx5e_trigger_irq(&c->async_icosq);
	spin_unlock(&c->async_icosq_lock);
	spin_unlock_bh(&c->async_icosq_lock);
}

void mlx5e_deactivate_xsk(struct mlx5e_channel *c)
+2 −2
Original line number Diff line number Diff line
@@ -36,9 +36,9 @@ int mlx5e_xsk_wakeup(struct net_device *dev, u32 qid, u32 flags)
		if (test_and_set_bit(MLX5E_SQ_STATE_PENDING_XSK_TX, &c->async_icosq.state))
			return 0;

		spin_lock(&c->async_icosq_lock);
		spin_lock_bh(&c->async_icosq_lock);
		mlx5e_trigger_irq(&c->async_icosq);
		spin_unlock(&c->async_icosq_lock);
		spin_unlock_bh(&c->async_icosq_lock);
	}

	return 0;
+7 −7
Original line number Diff line number Diff line
@@ -188,7 +188,7 @@ static int post_rx_param_wqes(struct mlx5e_channel *c,

	err = 0;
	sq = &c->async_icosq;
	spin_lock(&c->async_icosq_lock);
	spin_lock_bh(&c->async_icosq_lock);

	cseg = post_static_params(sq, priv_rx);
	if (IS_ERR(cseg))
@@ -199,7 +199,7 @@ static int post_rx_param_wqes(struct mlx5e_channel *c,

	mlx5e_notify_hw(&sq->wq, sq->pc, sq->uar_map, cseg);
unlock:
	spin_unlock(&c->async_icosq_lock);
	spin_unlock_bh(&c->async_icosq_lock);

	return err;

@@ -265,10 +265,10 @@ resync_post_get_progress_params(struct mlx5e_icosq *sq,

	BUILD_BUG_ON(MLX5E_KTLS_GET_PROGRESS_WQEBBS != 1);

	spin_lock(&sq->channel->async_icosq_lock);
	spin_lock_bh(&sq->channel->async_icosq_lock);

	if (unlikely(!mlx5e_wqc_has_room_for(&sq->wq, sq->cc, sq->pc, 1))) {
		spin_unlock(&sq->channel->async_icosq_lock);
		spin_unlock_bh(&sq->channel->async_icosq_lock);
		err = -ENOSPC;
		goto err_dma_unmap;
	}
@@ -299,7 +299,7 @@ resync_post_get_progress_params(struct mlx5e_icosq *sq,
	icosq_fill_wi(sq, pi, &wi);
	sq->pc++;
	mlx5e_notify_hw(&sq->wq, sq->pc, sq->uar_map, cseg);
	spin_unlock(&sq->channel->async_icosq_lock);
	spin_unlock_bh(&sq->channel->async_icosq_lock);

	return 0;

@@ -360,7 +360,7 @@ static int resync_handle_seq_match(struct mlx5e_ktls_offload_context_rx *priv_rx
	err = 0;

	sq = &c->async_icosq;
	spin_lock(&c->async_icosq_lock);
	spin_lock_bh(&c->async_icosq_lock);

	cseg = post_static_params(sq, priv_rx);
	if (IS_ERR(cseg)) {
@@ -372,7 +372,7 @@ static int resync_handle_seq_match(struct mlx5e_ktls_offload_context_rx *priv_rx
	mlx5e_notify_hw(&sq->wq, sq->pc, sq->uar_map, cseg);
	priv_rx->stats->tls_resync_res_ok++;
unlock:
	spin_unlock(&c->async_icosq_lock);
	spin_unlock_bh(&c->async_icosq_lock);

	return err;
}
Loading