Commit 76769c38 authored by David S. Miller's avatar David S. Miller
Browse files

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



Saeed Mahameed says:

====================
mlx5-updates-2020-08-03

This patchset introduces some updates to mlx5 driver.

1) Jakub converts mlx5 to use the new udp tunnel infrastructure.
   Starting with a hack to allow drivers to request a static configuration
   of the default vxlan port, and then a patch that converts mlx5.

2) Parav implements change_carrier ndo for VF eswitch representors,
   to speedup link state control of representors netdevices.

3) Alex Vesker, makes a simple update to software steering to fix an issue
   with push vlan action sequence

4) Leon removes a redundant dump stack on error flow.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents c4b83061 6c4e9bcf
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -1263,6 +1263,9 @@ Kernel response contents:
 | | | | ``ETHTOOL_A_TUNNEL_UDP_ENTRY_TYPE``   | u32    | tunnel type         |
 +-+-+-+---------------------------------------+--------+---------------------+

For UDP tunnel table empty ``ETHTOOL_A_TUNNEL_UDP_TABLE_TYPES`` indicates that
the table contains static entries, hard-coded by the NIC.

Request translation
===================

+3 −2
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@
#include <linux/mlx5/transobj.h>
#include <linux/mlx5/fs.h>
#include <linux/rhashtable.h>
#include <net/udp_tunnel.h>
#include <net/switchdev.h>
#include <net/xdp.h>
#include <linux/dim.h>
@@ -792,6 +793,7 @@ struct mlx5e_priv {
	u16                        drop_rq_q_counter;
	struct notifier_block      events_nb;

	struct udp_tunnel_nic_info nic_info;
#ifdef CONFIG_MLX5_CORE_EN_DCB
	struct mlx5e_dcbx          dcbx;
#endif
@@ -1012,6 +1014,7 @@ int mlx5e_set_dev_port_mtu(struct mlx5e_priv *priv);
int mlx5e_set_dev_port_mtu_ctx(struct mlx5e_priv *priv, void *context);
int mlx5e_change_mtu(struct net_device *netdev, int new_mtu,
		     mlx5e_fp_preactivate preactivate);
void mlx5e_vxlan_set_netdev_info(struct mlx5e_priv *priv);

/* ethtool helpers */
void mlx5e_ethtool_get_drvinfo(struct mlx5e_priv *priv,
@@ -1080,8 +1083,6 @@ void mlx5e_build_rss_params(struct mlx5e_rss_params *rss_params,
void mlx5e_rx_dim_work(struct work_struct *work);
void mlx5e_tx_dim_work(struct work_struct *work);

void mlx5e_add_vxlan_port(struct net_device *netdev, struct udp_tunnel_info *ti);
void mlx5e_del_vxlan_port(struct net_device *netdev, struct udp_tunnel_info *ti);
netdev_features_t mlx5e_features_check(struct sk_buff *skb,
				       struct net_device *netdev,
				       netdev_features_t features);
+38 −83
Original line number Diff line number Diff line
@@ -4191,83 +4191,6 @@ int mlx5e_get_vf_stats(struct net_device *dev,
}
#endif

struct mlx5e_vxlan_work {
	struct work_struct	work;
	struct mlx5e_priv	*priv;
	u16			port;
};

static void mlx5e_vxlan_add_work(struct work_struct *work)
{
	struct mlx5e_vxlan_work *vxlan_work =
		container_of(work, struct mlx5e_vxlan_work, work);
	struct mlx5e_priv *priv = vxlan_work->priv;
	u16 port = vxlan_work->port;

	mutex_lock(&priv->state_lock);
	mlx5_vxlan_add_port(priv->mdev->vxlan, port);
	mutex_unlock(&priv->state_lock);

	kfree(vxlan_work);
}

static void mlx5e_vxlan_del_work(struct work_struct *work)
{
	struct mlx5e_vxlan_work *vxlan_work =
		container_of(work, struct mlx5e_vxlan_work, work);
	struct mlx5e_priv *priv         = vxlan_work->priv;
	u16 port = vxlan_work->port;

	mutex_lock(&priv->state_lock);
	mlx5_vxlan_del_port(priv->mdev->vxlan, port);
	mutex_unlock(&priv->state_lock);
	kfree(vxlan_work);
}

static void mlx5e_vxlan_queue_work(struct mlx5e_priv *priv, u16 port, int add)
{
	struct mlx5e_vxlan_work *vxlan_work;

	vxlan_work = kmalloc(sizeof(*vxlan_work), GFP_ATOMIC);
	if (!vxlan_work)
		return;

	if (add)
		INIT_WORK(&vxlan_work->work, mlx5e_vxlan_add_work);
	else
		INIT_WORK(&vxlan_work->work, mlx5e_vxlan_del_work);

	vxlan_work->priv = priv;
	vxlan_work->port = port;
	queue_work(priv->wq, &vxlan_work->work);
}

void mlx5e_add_vxlan_port(struct net_device *netdev, struct udp_tunnel_info *ti)
{
	struct mlx5e_priv *priv = netdev_priv(netdev);

	if (ti->type != UDP_TUNNEL_TYPE_VXLAN)
		return;

	if (!mlx5_vxlan_allowed(priv->mdev->vxlan))
		return;

	mlx5e_vxlan_queue_work(priv, be16_to_cpu(ti->port), 1);
}

void mlx5e_del_vxlan_port(struct net_device *netdev, struct udp_tunnel_info *ti)
{
	struct mlx5e_priv *priv = netdev_priv(netdev);

	if (ti->type != UDP_TUNNEL_TYPE_VXLAN)
		return;

	if (!mlx5_vxlan_allowed(priv->mdev->vxlan))
		return;

	mlx5e_vxlan_queue_work(priv, be16_to_cpu(ti->port), 0);
}

static netdev_features_t mlx5e_tunnel_features_check(struct mlx5e_priv *priv,
						     struct sk_buff *skb,
						     netdev_features_t features)
@@ -4597,8 +4520,8 @@ const struct net_device_ops mlx5e_netdev_ops = {
	.ndo_change_mtu          = mlx5e_change_nic_mtu,
	.ndo_do_ioctl            = mlx5e_ioctl,
	.ndo_set_tx_maxrate      = mlx5e_set_tx_maxrate,
	.ndo_udp_tunnel_add      = mlx5e_add_vxlan_port,
	.ndo_udp_tunnel_del      = mlx5e_del_vxlan_port,
	.ndo_udp_tunnel_add      = udp_tunnel_nic_add_port,
	.ndo_udp_tunnel_del      = udp_tunnel_nic_del_port,
	.ndo_features_check      = mlx5e_features_check,
	.ndo_tx_timeout          = mlx5e_tx_timeout,
	.ndo_bpf		 = mlx5e_xdp,
@@ -4869,6 +4792,39 @@ static void mlx5e_set_netdev_dev_addr(struct net_device *netdev)
	}
}

static int mlx5e_vxlan_set_port(struct net_device *netdev, unsigned int table,
				unsigned int entry, struct udp_tunnel_info *ti)
{
	struct mlx5e_priv *priv = netdev_priv(netdev);

	return mlx5_vxlan_add_port(priv->mdev->vxlan, ntohs(ti->port));
}

static int mlx5e_vxlan_unset_port(struct net_device *netdev, unsigned int table,
				  unsigned int entry, struct udp_tunnel_info *ti)
{
	struct mlx5e_priv *priv = netdev_priv(netdev);

	return mlx5_vxlan_del_port(priv->mdev->vxlan, ntohs(ti->port));
}

void mlx5e_vxlan_set_netdev_info(struct mlx5e_priv *priv)
{
	if (!mlx5_vxlan_allowed(priv->mdev->vxlan))
		return;

	priv->nic_info.set_port = mlx5e_vxlan_set_port;
	priv->nic_info.unset_port = mlx5e_vxlan_unset_port;
	priv->nic_info.flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP |
				UDP_TUNNEL_NIC_INFO_STATIC_IANA_VXLAN;
	priv->nic_info.tables[0].tunnel_types = UDP_TUNNEL_TYPE_VXLAN;
	/* Don't count the space hard-coded to the IANA port */
	priv->nic_info.tables[0].n_entries =
		mlx5_vxlan_max_udp_ports(priv->mdev) - 1;

	priv->netdev->udp_tunnel_nic_info = &priv->nic_info;
}

static void mlx5e_build_nic_netdev(struct net_device *netdev)
{
	struct mlx5e_priv *priv = netdev_priv(netdev);
@@ -4912,6 +4868,8 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev)
	netdev->hw_features      |= NETIF_F_HW_VLAN_CTAG_FILTER;
	netdev->hw_features      |= NETIF_F_HW_VLAN_STAG_TX;

	mlx5e_vxlan_set_netdev_info(priv);

	if (mlx5_vxlan_allowed(mdev->vxlan) || mlx5_geneve_tx_allowed(mdev) ||
	    mlx5e_any_tunnel_proto_supported(mdev)) {
		netdev->hw_enc_features |= NETIF_F_HW_CSUM;
@@ -5217,8 +5175,7 @@ static void mlx5e_nic_enable(struct mlx5e_priv *priv)
	rtnl_lock();
	if (netif_running(netdev))
		mlx5e_open(netdev);
	if (mlx5_vxlan_allowed(priv->mdev->vxlan))
		udp_tunnel_get_rx_info(netdev);
	udp_tunnel_nic_reset_ntf(priv->netdev);
	netif_device_attach(netdev);
	rtnl_unlock();
}
@@ -5233,8 +5190,6 @@ static void mlx5e_nic_disable(struct mlx5e_priv *priv)
	rtnl_lock();
	if (netif_running(priv->netdev))
		mlx5e_close(priv->netdev);
	if (mlx5_vxlan_allowed(priv->mdev->vxlan))
		udp_tunnel_drop_rx_info(priv->netdev);
	netif_device_detach(priv->netdev);
	rtnl_unlock();

+27 −2
Original line number Diff line number Diff line
@@ -611,6 +611,29 @@ static struct devlink_port *mlx5e_rep_get_devlink_port(struct net_device *dev)
	return &rpriv->dl_port;
}

static int mlx5e_rep_change_carrier(struct net_device *dev, bool new_carrier)
{
	struct mlx5e_priv *priv = netdev_priv(dev);
	struct mlx5e_rep_priv *rpriv = priv->ppriv;
	struct mlx5_eswitch_rep *rep = rpriv->rep;
	int err;

	if (new_carrier) {
		err = mlx5_modify_vport_admin_state(priv->mdev, MLX5_VPORT_STATE_OP_MOD_ESW_VPORT,
						    rep->vport, 1, MLX5_VPORT_ADMIN_STATE_UP);
		if (err)
			return err;
		netif_carrier_on(dev);
	} else {
		err = mlx5_modify_vport_admin_state(priv->mdev, MLX5_VPORT_STATE_OP_MOD_ESW_VPORT,
						    rep->vport, 1, MLX5_VPORT_ADMIN_STATE_DOWN);
		if (err)
			return err;
		netif_carrier_off(dev);
	}
	return 0;
}

static const struct net_device_ops mlx5e_netdev_ops_rep = {
	.ndo_open                = mlx5e_rep_open,
	.ndo_stop                = mlx5e_rep_close,
@@ -621,6 +644,7 @@ static const struct net_device_ops mlx5e_netdev_ops_rep = {
	.ndo_has_offload_stats	 = mlx5e_rep_has_offload_stats,
	.ndo_get_offload_stats	 = mlx5e_rep_get_offload_stats,
	.ndo_change_mtu          = mlx5e_rep_change_mtu,
	.ndo_change_carrier      = mlx5e_rep_change_carrier,
};

static const struct net_device_ops mlx5e_netdev_ops_uplink_rep = {
@@ -634,8 +658,8 @@ static const struct net_device_ops mlx5e_netdev_ops_uplink_rep = {
	.ndo_has_offload_stats	 = mlx5e_rep_has_offload_stats,
	.ndo_get_offload_stats	 = mlx5e_rep_get_offload_stats,
	.ndo_change_mtu          = mlx5e_uplink_rep_change_mtu,
	.ndo_udp_tunnel_add      = mlx5e_add_vxlan_port,
	.ndo_udp_tunnel_del      = mlx5e_del_vxlan_port,
	.ndo_udp_tunnel_add      = udp_tunnel_nic_add_port,
	.ndo_udp_tunnel_del      = udp_tunnel_nic_del_port,
	.ndo_features_check      = mlx5e_features_check,
	.ndo_set_vf_mac          = mlx5e_set_vf_mac,
	.ndo_set_vf_rate         = mlx5e_set_vf_rate,
@@ -706,6 +730,7 @@ static void mlx5e_build_rep_netdev(struct net_device *netdev)
		/* we want a persistent mac for the uplink rep */
		mlx5_query_mac_address(mdev, netdev->dev_addr);
		netdev->ethtool_ops = &mlx5e_uplink_rep_ethtool_ops;
		mlx5e_vxlan_set_netdev_info(priv);
		mlx5e_dcbnl_build_rep_netdev(netdev);
	} else {
		netdev->netdev_ops = &mlx5e_netdev_ops_rep;
+3 −6
Original line number Diff line number Diff line
@@ -846,18 +846,15 @@ static int connect_fts_in_prio(struct mlx5_core_dev *dev,
{
	struct mlx5_flow_root_namespace *root = find_root(&prio->node);
	struct mlx5_flow_table *iter;
	int i = 0;
	int err;

	fs_for_each_ft(iter, prio) {
		i++;
		err = root->cmds->modify_flow_table(root, iter, ft);
		if (err) {
			mlx5_core_warn(dev, "Failed to modify flow table %d\n",
				       iter->id);
			mlx5_core_err(dev,
				      "Failed to modify flow table id %d, type %d, err %d\n",
				      iter->id, iter->type, err);
			/* The driver is out of sync with the FW */
			if (i > 1)
				WARN_ON(true);
			return err;
		}
	}
Loading