Commit 5ef17179 authored by Jason Gunthorpe's avatar Jason Gunthorpe
Browse files

Merge mlx5-next into rdma.git for-next



Synchronize the shared mlx5 branch with net:
 - From Jiri: fixe a deadlock in mlx5_ib's netdev notifier unregister.
 - From Mark and Patrisious: add IPsec RoCEv2 support.
 - From Or: Rely on firmware to get special mkeys

* branch mlx5-next:
  RDMA/mlx5: Use query_special_contexts for mkeys
  net/mlx5e: Use query_special_contexts for mkeys
  net/mlx5: Change define name for 0x100 lkey value
  net/mlx5: Expose bits for querying special mkeys
  net/mlx5: Configure IPsec steering for egress RoCEv2 traffic
  net/mlx5: Configure IPsec steering for ingress RoCEv2 traffic
  net/mlx5: Add IPSec priorities in RDMA namespaces
  net/mlx5: Implement new destination type TABLE_TYPE
  net/mlx5: Introduce new destination type TABLE_TYPE
  RDMA/mlx5: Track netdev to avoid deadlock during netdev notifier unregister
  net/mlx5e: Propagate an internal event in case uplink netdev changes
  net/mlx5e: Fix trap event handling

Signed-off-by: default avatarJason Gunthorpe <jgg@nvidia.com>
parents a77a5238 594cac11
Loading
Loading
Loading
Loading
+26 −19
Original line number Diff line number Diff line
@@ -5,34 +5,41 @@

#include "cmd.h"

int mlx5_cmd_dump_fill_mkey(struct mlx5_core_dev *dev, u32 *mkey)
int mlx5r_cmd_query_special_mkeys(struct mlx5_ib_dev *dev)
{
	u32 out[MLX5_ST_SZ_DW(query_special_contexts_out)] = {};
	u32 in[MLX5_ST_SZ_DW(query_special_contexts_in)] = {};
	bool is_terminate, is_dump, is_null;
	int err;

	MLX5_SET(query_special_contexts_in, in, opcode,
		 MLX5_CMD_OP_QUERY_SPECIAL_CONTEXTS);
	err = mlx5_cmd_exec_inout(dev, query_special_contexts, in, out);
	if (!err)
		*mkey = MLX5_GET(query_special_contexts_out, out,
				 dump_fill_mkey);
	return err;
}
	is_terminate = MLX5_CAP_GEN(dev->mdev, terminate_scatter_list_mkey);
	is_dump = MLX5_CAP_GEN(dev->mdev, dump_fill_mkey);
	is_null = MLX5_CAP_GEN(dev->mdev, null_mkey);

int mlx5_cmd_null_mkey(struct mlx5_core_dev *dev, u32 *null_mkey)
{
	u32 out[MLX5_ST_SZ_DW(query_special_contexts_out)] = {};
	u32 in[MLX5_ST_SZ_DW(query_special_contexts_in)] = {};
	int err;
	dev->mkeys.terminate_scatter_list_mkey = MLX5_TERMINATE_SCATTER_LIST_LKEY;
	if (!is_terminate && !is_dump && !is_null)
		return 0;

	MLX5_SET(query_special_contexts_in, in, opcode,
		 MLX5_CMD_OP_QUERY_SPECIAL_CONTEXTS);
	err = mlx5_cmd_exec_inout(dev, query_special_contexts, in, out);
	if (!err)
		*null_mkey = MLX5_GET(query_special_contexts_out, out,
				      null_mkey);
	err = mlx5_cmd_exec_inout(dev->mdev, query_special_contexts, in, out);
	if (err)
		return err;

	if (is_dump)
		dev->mkeys.dump_fill_mkey = MLX5_GET(query_special_contexts_out,
						     out, dump_fill_mkey);

	if (is_null)
		dev->mkeys.null_mkey = cpu_to_be32(
			MLX5_GET(query_special_contexts_out, out, null_mkey));

	if (is_terminate)
		dev->mkeys.terminate_scatter_list_mkey =
			cpu_to_be32(MLX5_GET(query_special_contexts_out, out,
					     terminate_scatter_list_mkey));

	return 0;
}

int mlx5_cmd_query_cong_params(struct mlx5_core_dev *dev, int cong_point,
+1 −2
Original line number Diff line number Diff line
@@ -37,8 +37,7 @@
#include <linux/kernel.h>
#include <linux/mlx5/driver.h>

int mlx5_cmd_dump_fill_mkey(struct mlx5_core_dev *dev, u32 *mkey);
int mlx5_cmd_null_mkey(struct mlx5_core_dev *dev, u32 *null_mkey);
int mlx5r_cmd_query_special_mkeys(struct mlx5_ib_dev *dev);
int mlx5_cmd_query_cong_params(struct mlx5_core_dev *dev, int cong_point,
			       void *out);
int mlx5_cmd_dealloc_pd(struct mlx5_core_dev *dev, u32 pdn, u16 uid);
+59 −29
Original line number Diff line number Diff line
@@ -1756,13 +1756,9 @@ static int set_ucontext_resp(struct ib_ucontext *uctx,
	struct mlx5_ib_dev *dev = to_mdev(ibdev);
	struct mlx5_ib_ucontext *context = to_mucontext(uctx);
	struct mlx5_bfreg_info *bfregi = &context->bfregi;
	int err;

	if (MLX5_CAP_GEN(dev->mdev, dump_fill_mkey)) {
		err = mlx5_cmd_dump_fill_mkey(dev->mdev,
					      &resp->dump_fill_mkey);
		if (err)
			return err;
		resp->dump_fill_mkey = dev->mkeys.dump_fill_mkey;
		resp->comp_mask |=
			MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_DUMP_FILL_MKEY;
	}
@@ -3012,26 +3008,63 @@ static void mlx5_eth_lag_cleanup(struct mlx5_ib_dev *dev)
	}
}

static int mlx5_add_netdev_notifier(struct mlx5_ib_dev *dev, u32 port_num)
static void mlx5_netdev_notifier_register(struct mlx5_roce *roce,
					  struct net_device *netdev)
{
	int err;

	dev->port[port_num].roce.nb.notifier_call = mlx5_netdev_event;
	err = register_netdevice_notifier(&dev->port[port_num].roce.nb);
	if (err) {
		dev->port[port_num].roce.nb.notifier_call = NULL;
		return err;
	if (roce->tracking_netdev)
		return;
	roce->tracking_netdev = netdev;
	roce->nb.notifier_call = mlx5_netdev_event;
	err = register_netdevice_notifier_dev_net(netdev, &roce->nb, &roce->nn);
	WARN_ON(err);
}

	return 0;
static void mlx5_netdev_notifier_unregister(struct mlx5_roce *roce)
{
	if (!roce->tracking_netdev)
		return;
	unregister_netdevice_notifier_dev_net(roce->tracking_netdev, &roce->nb,
					      &roce->nn);
	roce->tracking_netdev = NULL;
}

static int mlx5e_mdev_notifier_event(struct notifier_block *nb,
				     unsigned long event, void *data)
{
	struct mlx5_roce *roce = container_of(nb, struct mlx5_roce, mdev_nb);
	struct net_device *netdev = data;

	switch (event) {
	case MLX5_DRIVER_EVENT_UPLINK_NETDEV:
		if (netdev)
			mlx5_netdev_notifier_register(roce, netdev);
		else
			mlx5_netdev_notifier_unregister(roce);
		break;
	default:
		return NOTIFY_DONE;
	}

static void mlx5_remove_netdev_notifier(struct mlx5_ib_dev *dev, u32 port_num)
	return NOTIFY_OK;
}

static void mlx5_mdev_netdev_track(struct mlx5_ib_dev *dev, u32 port_num)
{
	if (dev->port[port_num].roce.nb.notifier_call) {
		unregister_netdevice_notifier(&dev->port[port_num].roce.nb);
		dev->port[port_num].roce.nb.notifier_call = NULL;
	struct mlx5_roce *roce = &dev->port[port_num].roce;

	roce->mdev_nb.notifier_call = mlx5e_mdev_notifier_event;
	mlx5_blocking_notifier_register(dev->mdev, &roce->mdev_nb);
	mlx5_core_uplink_netdev_event_replay(dev->mdev);
}

static void mlx5_mdev_netdev_untrack(struct mlx5_ib_dev *dev, u32 port_num)
{
	struct mlx5_roce *roce = &dev->port[port_num].roce;

	mlx5_blocking_notifier_unregister(dev->mdev, &roce->mdev_nb);
	mlx5_netdev_notifier_unregister(roce);
}

static int mlx5_enable_eth(struct mlx5_ib_dev *dev)
@@ -3138,7 +3171,7 @@ static void mlx5_ib_unbind_slave_port(struct mlx5_ib_dev *ibdev,
	if (mpi->mdev_events.notifier_call)
		mlx5_notifier_unregister(mpi->mdev, &mpi->mdev_events);
	mpi->mdev_events.notifier_call = NULL;
	mlx5_remove_netdev_notifier(ibdev, port_num);
	mlx5_mdev_netdev_untrack(ibdev, port_num);
	spin_lock(&port->mp.mpi_lock);

	comps = mpi->mdev_refcnt;
@@ -3196,12 +3229,7 @@ static bool mlx5_ib_bind_slave_port(struct mlx5_ib_dev *ibdev,
	if (err)
		goto unbind;

	err = mlx5_add_netdev_notifier(ibdev, port_num);
	if (err) {
		mlx5_ib_err(ibdev, "failed adding netdev notifier for port %u\n",
			    port_num + 1);
		goto unbind;
	}
	mlx5_mdev_netdev_track(ibdev, port_num);

	mpi->mdev_events.notifier_call = mlx5_ib_event_slave_port;
	mlx5_notifier_register(mpi->mdev, &mpi->mdev_events);
@@ -3634,6 +3662,10 @@ static int mlx5_ib_stage_init_init(struct mlx5_ib_dev *dev)
		dev->port[i].roce.last_port_state = IB_PORT_DOWN;
	}

	err = mlx5r_cmd_query_special_mkeys(dev);
	if (err)
		return err;

	err = mlx5_ib_init_multiport_master(dev);
	if (err)
		return err;
@@ -3909,9 +3941,7 @@ static int mlx5_ib_roce_init(struct mlx5_ib_dev *dev)
		port_num = mlx5_core_native_port_num(dev->mdev) - 1;

		/* Register only for native ports */
		err = mlx5_add_netdev_notifier(dev, port_num);
		if (err)
			return err;
		mlx5_mdev_netdev_track(dev, port_num);

		err = mlx5_enable_eth(dev);
		if (err)
@@ -3920,7 +3950,7 @@ static int mlx5_ib_roce_init(struct mlx5_ib_dev *dev)

	return 0;
cleanup:
	mlx5_remove_netdev_notifier(dev, port_num);
	mlx5_mdev_netdev_untrack(dev, port_num);
	return err;
}

@@ -3938,7 +3968,7 @@ static void mlx5_ib_roce_cleanup(struct mlx5_ib_dev *dev)
		mlx5_disable_eth(dev);

		port_num = mlx5_core_native_port_num(dev->mdev) - 1;
		mlx5_remove_netdev_notifier(dev, port_num);
		mlx5_mdev_netdev_untrack(dev, port_num);
	}
}

+11 −1
Original line number Diff line number Diff line
@@ -843,6 +843,9 @@ struct mlx5_roce {
	rwlock_t		netdev_lock;
	struct net_device	*netdev;
	struct notifier_block	nb;
	struct netdev_net_notifier nn;
	struct notifier_block	mdev_nb;
	struct net_device	*tracking_netdev;
	atomic_t		tx_port_affinity;
	enum ib_port_state last_port_state;
	struct mlx5_ib_dev	*dev;
@@ -1062,6 +1065,13 @@ struct mlx5_port_caps {
	u8 ext_port_cap;
};


struct mlx5_special_mkeys {
	u32 dump_fill_mkey;
	__be32 null_mkey;
	__be32 terminate_scatter_list_mkey;
};

struct mlx5_ib_dev {
	struct ib_device		ib_dev;
	struct mlx5_core_dev		*mdev;
@@ -1092,7 +1102,6 @@ struct mlx5_ib_dev {

	struct xarray		odp_mkeys;

	u32			null_mkey;
	struct mlx5_ib_flow_db	*flow_db;
	/* protect resources needed as part of reset flow */
	spinlock_t		reset_flow_resource_lock;
@@ -1121,6 +1130,7 @@ struct mlx5_ib_dev {
	struct mlx5_port_caps port_caps[MLX5_MAX_PORTS];
	u16 pkey_table_len;
	u8 lag_ports;
	struct mlx5_special_mkeys mkeys;
};

static inline struct mlx5_ib_cq *to_mibcq(struct mlx5_core_cq *mcq)
+9 −18
Original line number Diff line number Diff line
@@ -104,7 +104,7 @@ static void populate_klm(struct mlx5_klm *pklm, size_t idx, size_t nentries,
	if (flags & MLX5_IB_UPD_XLT_ZAP) {
		for (; pklm != end; pklm++, idx++) {
			pklm->bcount = cpu_to_be32(MLX5_IMR_MTT_SIZE);
			pklm->key = cpu_to_be32(mr_to_mdev(imr)->null_mkey);
			pklm->key = mr_to_mdev(imr)->mkeys.null_mkey;
			pklm->va = 0;
		}
		return;
@@ -137,7 +137,7 @@ static void populate_klm(struct mlx5_klm *pklm, size_t idx, size_t nentries,
			pklm->key = cpu_to_be32(mtt->ibmr.lkey);
			pklm->va = cpu_to_be64(idx * MLX5_IMR_MTT_SIZE);
		} else {
			pklm->key = cpu_to_be32(mr_to_mdev(imr)->null_mkey);
			pklm->key = mr_to_mdev(imr)->mkeys.null_mkey;
			pklm->va = 0;
		}
	}
@@ -986,7 +986,7 @@ static int pagefault_data_segments(struct mlx5_ib_dev *dev,
{
	int ret = 0, npages = 0;
	u64 io_virt;
	u32 key;
	__be32 key;
	u32 byte_count;
	size_t bcnt;
	int inline_segment;
@@ -1000,7 +1000,7 @@ static int pagefault_data_segments(struct mlx5_ib_dev *dev,
		struct mlx5_wqe_data_seg *dseg = wqe;

		io_virt = be64_to_cpu(dseg->addr);
		key = be32_to_cpu(dseg->lkey);
		key = dseg->lkey;
		byte_count = be32_to_cpu(dseg->byte_count);
		inline_segment = !!(byte_count &  MLX5_INLINE_SEG);
		bcnt	       = byte_count & ~MLX5_INLINE_SEG;
@@ -1014,7 +1014,8 @@ static int pagefault_data_segments(struct mlx5_ib_dev *dev,
		}

		/* receive WQE end of sg list. */
		if (receive_queue && bcnt == 0 && key == MLX5_INVALID_LKEY &&
		if (receive_queue && bcnt == 0 &&
		    key == dev->mkeys.terminate_scatter_list_mkey &&
		    io_virt == 0)
			break;

@@ -1034,7 +1035,7 @@ static int pagefault_data_segments(struct mlx5_ib_dev *dev,
			continue;
		}

		ret = pagefault_single_data_segment(dev, NULL, key,
		ret = pagefault_single_data_segment(dev, NULL, be32_to_cpu(key),
						    io_virt, bcnt,
						    &pfault->bytes_committed,
						    bytes_mapped);
@@ -1611,25 +1612,15 @@ static const struct ib_device_ops mlx5_ib_dev_odp_ops = {

int mlx5_ib_odp_init_one(struct mlx5_ib_dev *dev)
{
	int ret = 0;

	internal_fill_odp_caps(dev);

	if (!(dev->odp_caps.general_caps & IB_ODP_SUPPORT))
		return ret;
		return 0;

	ib_set_device_ops(&dev->ib_dev, &mlx5_ib_dev_odp_ops);

	if (dev->odp_caps.general_caps & IB_ODP_SUPPORT_IMPLICIT) {
		ret = mlx5_cmd_null_mkey(dev->mdev, &dev->null_mkey);
		if (ret) {
			mlx5_ib_err(dev, "Error getting null_mkey %d\n", ret);
			return ret;
		}
	}

	mutex_init(&dev->odp_eq_mutex);
	return ret;
	return 0;
}

void mlx5_ib_odp_cleanup_one(struct mlx5_ib_dev *dev)
Loading