Commit 0c2e3fa9 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'mlx4-net'



Or Gerlitz says:

====================
mlx4: Fix VF MAC address change under RoCE usage

This short series provides proper handling for the case where a
VF netdevice change their MAC address under a RoCE use case. The code
it deals with was introduced in 3.15-rc1

Prior to this series the source MAC used for the VM RoCE CM
packets remains as before the MAC modification. Hence RoCE CM
packets sent by the VF will not carry the same source MAC
address as the non-CM packets.

Earlier 3.15-rc commit f24f790f "net/mlx4_core: Load the Eth driver
first" handled just one instance of the problem, but this one
provides a more generic and proper solution which covers all
cases of VF mac change.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 81c70806 9433c188
Loading
Loading
Loading
Loading
+64 −3
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@

#include <linux/mlx4/driver.h>
#include <linux/mlx4/cmd.h>
#include <linux/mlx4/qp.h>

#include "mlx4_ib.h"
#include "user.h"
@@ -1614,6 +1615,53 @@ static int mlx4_ib_inet6_event(struct notifier_block *this, unsigned long event,
}
#endif

#define MLX4_IB_INVALID_MAC	((u64)-1)
static void mlx4_ib_update_qps(struct mlx4_ib_dev *ibdev,
			       struct net_device *dev,
			       int port)
{
	u64 new_smac = 0;
	u64 release_mac = MLX4_IB_INVALID_MAC;
	struct mlx4_ib_qp *qp;

	read_lock(&dev_base_lock);
	new_smac = mlx4_mac_to_u64(dev->dev_addr);
	read_unlock(&dev_base_lock);

	mutex_lock(&ibdev->qp1_proxy_lock[port - 1]);
	qp = ibdev->qp1_proxy[port - 1];
	if (qp) {
		int new_smac_index;
		u64 old_smac = qp->pri.smac;
		struct mlx4_update_qp_params update_params;

		if (new_smac == old_smac)
			goto unlock;

		new_smac_index = mlx4_register_mac(ibdev->dev, port, new_smac);

		if (new_smac_index < 0)
			goto unlock;

		update_params.smac_index = new_smac_index;
		if (mlx4_update_qp(ibdev->dev, &qp->mqp, MLX4_UPDATE_QP_SMAC,
				   &update_params)) {
			release_mac = new_smac;
			goto unlock;
		}

		qp->pri.smac = new_smac;
		qp->pri.smac_index = new_smac_index;

		release_mac = old_smac;
	}

unlock:
	mutex_unlock(&ibdev->qp1_proxy_lock[port - 1]);
	if (release_mac != MLX4_IB_INVALID_MAC)
		mlx4_unregister_mac(ibdev->dev, port, release_mac);
}

static void mlx4_ib_get_dev_addr(struct net_device *dev,
				 struct mlx4_ib_dev *ibdev, u8 port)
{
@@ -1689,9 +1737,13 @@ static int mlx4_ib_init_gid_table(struct mlx4_ib_dev *ibdev)
	return 0;
}

static void mlx4_ib_scan_netdevs(struct mlx4_ib_dev *ibdev)
static void mlx4_ib_scan_netdevs(struct mlx4_ib_dev *ibdev,
				 struct net_device *dev,
				 unsigned long event)

{
	struct mlx4_ib_iboe *iboe;
	int update_qps_port = -1;
	int port;

	iboe = &ibdev->iboe;
@@ -1719,6 +1771,11 @@ static void mlx4_ib_scan_netdevs(struct mlx4_ib_dev *ibdev)
		}
		curr_master = iboe->masters[port - 1];

		if (dev == iboe->netdevs[port - 1] &&
		    (event == NETDEV_CHANGEADDR || event == NETDEV_REGISTER ||
		     event == NETDEV_UP || event == NETDEV_CHANGE))
			update_qps_port = port;

		if (curr_netdev) {
			port_state = (netif_running(curr_netdev) && netif_carrier_ok(curr_netdev)) ?
						IB_PORT_ACTIVE : IB_PORT_DOWN;
@@ -1752,6 +1809,9 @@ static void mlx4_ib_scan_netdevs(struct mlx4_ib_dev *ibdev)
	}

	spin_unlock(&iboe->lock);

	if (update_qps_port > 0)
		mlx4_ib_update_qps(ibdev, dev, update_qps_port);
}

static int mlx4_ib_netdev_event(struct notifier_block *this,
@@ -1764,7 +1824,7 @@ static int mlx4_ib_netdev_event(struct notifier_block *this,
		return NOTIFY_DONE;

	ibdev = container_of(this, struct mlx4_ib_dev, iboe.nb);
	mlx4_ib_scan_netdevs(ibdev);
	mlx4_ib_scan_netdevs(ibdev, dev, event);

	return NOTIFY_DONE;
}
@@ -2043,6 +2103,7 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
		goto err_map;

	for (i = 0; i < ibdev->num_ports; ++i) {
		mutex_init(&ibdev->qp1_proxy_lock[i]);
		if (mlx4_ib_port_link_layer(&ibdev->ib_dev, i + 1) ==
						IB_LINK_LAYER_ETHERNET) {
			err = mlx4_counter_alloc(ibdev->dev, &ibdev->counters[i]);
@@ -2126,7 +2187,7 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
		for (i = 1 ; i <= ibdev->num_ports ; ++i)
			reset_gid_table(ibdev, i);
		rtnl_lock();
		mlx4_ib_scan_netdevs(ibdev);
		mlx4_ib_scan_netdevs(ibdev, NULL, 0);
		rtnl_unlock();
		mlx4_ib_init_gid_table(ibdev);
	}
+3 −0
Original line number Diff line number Diff line
@@ -522,6 +522,9 @@ struct mlx4_ib_dev {
	int steer_qpn_count;
	int steer_qpn_base;
	int steering_support;
	struct mlx4_ib_qp      *qp1_proxy[MLX4_MAX_PORTS];
	/* lock when destroying qp1_proxy and getting netdev events */
	struct mutex		qp1_proxy_lock[MLX4_MAX_PORTS];
};

struct ib_event_work {
+8 −0
Original line number Diff line number Diff line
@@ -1132,6 +1132,12 @@ int mlx4_ib_destroy_qp(struct ib_qp *qp)
	if (is_qp0(dev, mqp))
		mlx4_CLOSE_PORT(dev->dev, mqp->port);

	if (dev->qp1_proxy[mqp->port - 1] == mqp) {
		mutex_lock(&dev->qp1_proxy_lock[mqp->port - 1]);
		dev->qp1_proxy[mqp->port - 1] = NULL;
		mutex_unlock(&dev->qp1_proxy_lock[mqp->port - 1]);
	}

	pd = get_pd(mqp);
	destroy_qp_common(dev, mqp, !!pd->ibpd.uobject);

@@ -1646,6 +1652,8 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
				err = handle_eth_ud_smac_index(dev, qp, (u8 *)attr->smac, context);
				if (err)
					return -EINVAL;
				if (qp->mlx4_ib_qp_type == MLX4_IB_QPT_PROXY_GSI)
					dev->qp1_proxy[qp->port - 1] = qp;
			}
		}
	}
+2 −2
Original line number Diff line number Diff line
@@ -1253,12 +1253,12 @@ static struct mlx4_cmd_info cmd_info[] = {
	},
	{
		.opcode = MLX4_CMD_UPDATE_QP,
		.has_inbox = false,
		.has_inbox = true,
		.has_outbox = false,
		.out_is_imm = false,
		.encode_slave_id = false,
		.verify = NULL,
		.wrapper = mlx4_CMD_EPERM_wrapper
		.wrapper = mlx4_UPDATE_QP_wrapper
	},
	{
		.opcode = MLX4_CMD_GET_OP_REQ,
+6 −0
Original line number Diff line number Diff line
@@ -1195,6 +1195,12 @@ int mlx4_QP_ATTACH_wrapper(struct mlx4_dev *dev, int slave,
			   struct mlx4_cmd_mailbox *outbox,
			   struct mlx4_cmd_info *cmd);

int mlx4_UPDATE_QP_wrapper(struct mlx4_dev *dev, int slave,
			   struct mlx4_vhcr *vhcr,
			   struct mlx4_cmd_mailbox *inbox,
			   struct mlx4_cmd_mailbox *outbox,
			   struct mlx4_cmd_info *cmd);

int mlx4_PROMISC_wrapper(struct mlx4_dev *dev, int slave,
			 struct mlx4_vhcr *vhcr,
			 struct mlx4_cmd_mailbox *inbox,
Loading