Commit 2833c977 authored by Jason Gunthorpe's avatar Jason Gunthorpe
Browse files

Merge branch 'mlx5_realtime_ts' into rdma.git for-next



Aharon Landau says:

====================
In case device supports only real-time timestamp, the kernel will fail to
create QP despite rdma-core requested such timestamp type.

It is because device returns free-running timestamp, and the conversion
from free-running to real-time is performed in the user space.

This series fixes it, by returning real-time timestamp.
====================

* mlx5_realtime_ts:
  RDMA/mlx5: Support real-time timestamp directly from the device
  RDMA/mlx5: Refactor get_ts_format functions to simplify code

Signed-off-by: default avatarJason Gunthorpe <jgg@nvidia.com>
parents fdcebbc2 33652951
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -725,7 +725,8 @@ static int create_cq_user(struct mlx5_ib_dev *dev, struct ib_udata *udata,
		return -EFAULT;

	if ((ucmd.flags & ~(MLX5_IB_CREATE_CQ_FLAGS_CQE_128B_PAD |
			    MLX5_IB_CREATE_CQ_FLAGS_UAR_PAGE_INDEX)))
			    MLX5_IB_CREATE_CQ_FLAGS_UAR_PAGE_INDEX |
			    MLX5_IB_CREATE_CQ_FLAGS_REAL_TIME_TS)))
		return -EINVAL;

	if ((ucmd.cqe_size != 64 && ucmd.cqe_size != 128) ||
@@ -826,6 +827,9 @@ static int create_cq_user(struct mlx5_ib_dev *dev, struct ib_udata *udata,
		cq->private_flags |= MLX5_IB_CQ_PR_FLAGS_CQE_128_PAD;
	}

	if (ucmd.flags & MLX5_IB_CREATE_CQ_FLAGS_REAL_TIME_TS)
		cq->private_flags |= MLX5_IB_CQ_PR_FLAGS_REAL_TIME_TS;

	MLX5_SET(create_cq_in, *cqb, uid, context->devx_uid);
	return 0;

+6 −0
Original line number Diff line number Diff line
@@ -1816,6 +1816,12 @@ static int set_ucontext_resp(struct ib_ucontext *uctx,
	if (MLX5_CAP_GEN(dev->mdev, ece_support))
		resp->comp_mask |= MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_ECE;

	if (rt_supported(MLX5_CAP_GEN(dev->mdev, sq_ts_format)) &&
	    rt_supported(MLX5_CAP_GEN(dev->mdev, rq_ts_format)) &&
	    rt_supported(MLX5_CAP_ROCE(dev->mdev, qp_ts_format)))
		resp->comp_mask |=
			MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_REAL_TIME_TS;

	resp->num_dyn_bfregs = bfregi->num_dyn_bfregs;

	if (MLX5_CAP_GEN(dev->mdev, drain_sigerr))
+7 −0
Original line number Diff line number Diff line
@@ -549,6 +549,7 @@ static inline const struct mlx5_umr_wr *umr_wr(const struct ib_send_wr *wr)

enum mlx5_ib_cq_pr_flags {
	MLX5_IB_CQ_PR_FLAGS_CQE_128_PAD	= 1 << 0,
	MLX5_IB_CQ_PR_FLAGS_REAL_TIME_TS = 1 << 1,
};

struct mlx5_ib_cq {
@@ -1611,4 +1612,10 @@ static inline bool mlx5_ib_lag_should_assign_affinity(struct mlx5_ib_dev *dev)
		(MLX5_CAP_GEN(dev->mdev, num_lag_ports) > 1 &&
		 MLX5_CAP_GEN(dev->mdev, lag_tx_port_affinity));
}

static inline bool rt_supported(int ts_cap)
{
	return ts_cap == MLX5_TIMESTAMP_FORMAT_CAP_REAL_TIME ||
	       ts_cap == MLX5_TIMESTAMP_FORMAT_CAP_FREE_RUNNING_AND_REAL_TIME;
}
#endif /* MLX5_IB_H */
+56 −46
Original line number Diff line number Diff line
@@ -1173,69 +1173,79 @@ static void destroy_flow_rule_vport_sq(struct mlx5_ib_sq *sq)
	sq->flow_rule = NULL;
}

static int get_rq_ts_format(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *send_cq)
static bool fr_supported(int ts_cap)
{
	bool fr_supported =
		MLX5_CAP_GEN(dev->mdev, rq_ts_format) ==
			MLX5_RQ_TIMESTAMP_FORMAT_CAP_FREE_RUNNING ||
		MLX5_CAP_GEN(dev->mdev, rq_ts_format) ==
			MLX5_RQ_TIMESTAMP_FORMAT_CAP_FREE_RUNNING_AND_REAL_TIME;
	return ts_cap == MLX5_TIMESTAMP_FORMAT_CAP_FREE_RUNNING ||
	       ts_cap == MLX5_TIMESTAMP_FORMAT_CAP_FREE_RUNNING_AND_REAL_TIME;
}

	if (send_cq->create_flags & IB_UVERBS_CQ_FLAGS_TIMESTAMP_COMPLETION) {
		if (!fr_supported) {
			mlx5_ib_dbg(dev, "Free running TS format is not supported\n");
static int get_ts_format(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *cq,
			 bool fr_sup, bool rt_sup)
{
	if (cq->private_flags & MLX5_IB_CQ_PR_FLAGS_REAL_TIME_TS) {
		if (!rt_sup) {
			mlx5_ib_dbg(dev,
				    "Real time TS format is not supported\n");
			return -EOPNOTSUPP;
		}
		return MLX5_TIMESTAMP_FORMAT_REAL_TIME;
	}
	if (cq->create_flags & IB_UVERBS_CQ_FLAGS_TIMESTAMP_COMPLETION) {
		if (!fr_sup) {
			mlx5_ib_dbg(dev,
				    "Free running TS format is not supported\n");
			return -EOPNOTSUPP;
		}
		return MLX5_RQC_TIMESTAMP_FORMAT_FREE_RUNNING;
		return MLX5_TIMESTAMP_FORMAT_FREE_RUNNING;
	}
	return fr_supported ? MLX5_RQC_TIMESTAMP_FORMAT_FREE_RUNNING :
			      MLX5_RQC_TIMESTAMP_FORMAT_DEFAULT;
	return fr_sup ? MLX5_TIMESTAMP_FORMAT_FREE_RUNNING :
			MLX5_TIMESTAMP_FORMAT_DEFAULT;
}

static int get_sq_ts_format(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *send_cq)
static int get_rq_ts_format(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *recv_cq)
{
	bool fr_supported =
		MLX5_CAP_GEN(dev->mdev, sq_ts_format) ==
			MLX5_SQ_TIMESTAMP_FORMAT_CAP_FREE_RUNNING ||
		MLX5_CAP_GEN(dev->mdev, sq_ts_format) ==
			MLX5_SQ_TIMESTAMP_FORMAT_CAP_FREE_RUNNING_AND_REAL_TIME;
	u8 ts_cap = MLX5_CAP_GEN(dev->mdev, rq_ts_format);

	if (send_cq->create_flags & IB_UVERBS_CQ_FLAGS_TIMESTAMP_COMPLETION) {
		if (!fr_supported) {
			mlx5_ib_dbg(dev, "Free running TS format is not supported\n");
			return -EOPNOTSUPP;
		}
		return MLX5_SQC_TIMESTAMP_FORMAT_FREE_RUNNING;
	return get_ts_format(dev, recv_cq, fr_supported(ts_cap),
			     rt_supported(ts_cap));
}
	return fr_supported ? MLX5_SQC_TIMESTAMP_FORMAT_FREE_RUNNING :
			      MLX5_SQC_TIMESTAMP_FORMAT_DEFAULT;

static int get_sq_ts_format(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *send_cq)
{
	u8 ts_cap = MLX5_CAP_GEN(dev->mdev, sq_ts_format);

	return get_ts_format(dev, send_cq, fr_supported(ts_cap),
			     rt_supported(ts_cap));
}

static int get_qp_ts_format(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *send_cq,
			    struct mlx5_ib_cq *recv_cq)
{
	bool fr_supported =
		MLX5_CAP_ROCE(dev->mdev, qp_ts_format) ==
			MLX5_QP_TIMESTAMP_FORMAT_CAP_FREE_RUNNING ||
		MLX5_CAP_ROCE(dev->mdev, qp_ts_format) ==
			MLX5_QP_TIMESTAMP_FORMAT_CAP_FREE_RUNNING_AND_REAL_TIME;
	int ts_format = fr_supported ? MLX5_QPC_TIMESTAMP_FORMAT_FREE_RUNNING :
				       MLX5_QPC_TIMESTAMP_FORMAT_DEFAULT;

	if (recv_cq &&
	    recv_cq->create_flags & IB_UVERBS_CQ_FLAGS_TIMESTAMP_COMPLETION)
		ts_format = MLX5_QPC_TIMESTAMP_FORMAT_FREE_RUNNING;

	if (send_cq &&
	    send_cq->create_flags & IB_UVERBS_CQ_FLAGS_TIMESTAMP_COMPLETION)
		ts_format = MLX5_QPC_TIMESTAMP_FORMAT_FREE_RUNNING;

	if (ts_format == MLX5_QPC_TIMESTAMP_FORMAT_FREE_RUNNING &&
	    !fr_supported) {
		mlx5_ib_dbg(dev, "Free running TS format is not supported\n");
	u8 ts_cap = MLX5_CAP_ROCE(dev->mdev, qp_ts_format);
	bool fr_sup = fr_supported(ts_cap);
	bool rt_sup = rt_supported(ts_cap);
	u8 default_ts = fr_sup ? MLX5_TIMESTAMP_FORMAT_FREE_RUNNING :
				 MLX5_TIMESTAMP_FORMAT_DEFAULT;
	int send_ts_format =
		send_cq ? get_ts_format(dev, send_cq, fr_sup, rt_sup) :
			  default_ts;
	int recv_ts_format =
		recv_cq ? get_ts_format(dev, recv_cq, fr_sup, rt_sup) :
			  default_ts;

	if (send_ts_format < 0 || recv_ts_format < 0)
		return -EOPNOTSUPP;

	if (send_ts_format != MLX5_TIMESTAMP_FORMAT_DEFAULT &&
	    recv_ts_format != MLX5_TIMESTAMP_FORMAT_DEFAULT &&
	    send_ts_format != recv_ts_format) {
		mlx5_ib_dbg(
			dev,
			"The send ts_format does not match the receive ts_format\n");
		return -EOPNOTSUPP;
	}
	return ts_format;

	return send_ts_format == default_ts ? recv_ts_format : send_ts_format;
}

static int create_raw_packet_qp_sq(struct mlx5_ib_dev *dev,
+4 −4
Original line number Diff line number Diff line
@@ -644,8 +644,8 @@ int mlx5e_create_rq(struct mlx5e_rq *rq, struct mlx5e_rq_param *param)
		return -ENOMEM;

	ts_format = mlx5_is_real_time_rq(mdev) ?
		    MLX5_RQC_TIMESTAMP_FORMAT_REAL_TIME :
		    MLX5_RQC_TIMESTAMP_FORMAT_FREE_RUNNING;
			    MLX5_TIMESTAMP_FORMAT_REAL_TIME :
			    MLX5_TIMESTAMP_FORMAT_FREE_RUNNING;
	rqc = MLX5_ADDR_OF(create_rq_in, in, ctx);
	wq  = MLX5_ADDR_OF(rqc, rqc, wq);

@@ -1188,8 +1188,8 @@ static int mlx5e_create_sq(struct mlx5_core_dev *mdev,
		return -ENOMEM;

	ts_format = mlx5_is_real_time_sq(mdev) ?
		    MLX5_SQC_TIMESTAMP_FORMAT_REAL_TIME :
		    MLX5_SQC_TIMESTAMP_FORMAT_FREE_RUNNING;
			    MLX5_TIMESTAMP_FORMAT_REAL_TIME :
			    MLX5_TIMESTAMP_FORMAT_FREE_RUNNING;
	sqc = MLX5_ADDR_OF(create_sq_in, in, ctx);
	wq = MLX5_ADDR_OF(sqc, sqc, wq);

Loading