Skip to contentSkip to conversation

Add DC transport support to mlx5

PATCH In review Leon Romanovsky 4 participants 13 messages Dec 26, 2017 – Jan 2, 2018 4 messages not in the archive

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

cover Add DC transport support to mlx5

Quoted 1 line

From Moni:

Following the discussion [1] on the mailing list regarding "Custom/proprietary QP type support", the following patchset implements the direct connected QP types functionality over posted RFC.

The dynamically connected (DC) transport service provides a datagram-like model that allows a DC QP to target multiple remote processes in multiple remote nodes.

As far as reachability is concerned, the DC model is somewhat similar to the unreliable datagram (UD) model in the sense that each WR submitted to the DC SQ carries the information that identifies the remote destination.

The new QP type - IB_QPT_DRIVER is introduced to represent all type of QPs that are driver specific, like the proposed DC QP. Such minimal change to the IB/core allows reuse of existing verbs functions to control those new QPs with already existing functions.

[1] https://www.spinics.net/lists/linux-rdma/msg57598.html

The patches are available in the git repository at:
git.kernel.org/pub/scm/linux/kernel/git/leon/linux-rdma.git tags/rdma-next-2017-12-26

Thanks
---------------------------------------

Moni Shoua (6):
net/mlx5: Add DCT command interface net/mlx5: Enable DC transport
IB/core: Introduce driver QP type
IB/mlx5: Handle type IB_QPT_DRIVER when creating a QP IB/mlx5: Add support for DC Initiator QP IB/mlx5: Add support for DC target QP

 drivers/infiniband/hw/mlx5/main.c              |  27 +-
 drivers/infiniband/hw/mlx5/mlx5_ib.h           |  11 +
 drivers/infiniband/hw/mlx5/qp.c                | 365 ++++++++++++++++++++++++-
 drivers/net/ethernet/mellanox/mlx5/core/eq.c   |   9 +-
 drivers/net/ethernet/mellanox/mlx5/core/main.c |   3 +
 drivers/net/ethernet/mellanox/mlx5/core/qp.c   | 128 ++++++++-
 include/linux/mlx5/device.h                    |   9 +
 include/linux/mlx5/driver.h                    |   8 +
 include/linux/mlx5/qp.h                        |  12 +
 include/rdma/ib_verbs.h                        |   1 +
 include/uapi/rdma/mlx5-abi.h                   |  12 +-
 11 files changed, 563 insertions(+), 22 deletions(-)

--
2.15.1

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

A message that is not in the archive (sent off-list or not yet received): 20171226091634.2352-1-leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org

#2 lore raw

PATCH 1/6 net/mlx5: Add DCT command interface

From: Moni Shoua <monis-VPRAkNaXOzVWk0Htik3J/[email protected]>

Add a missing command interface to work with a DCT. It includes: creating, destroying and get events for.

---
 drivers/net/ethernet/mellanox/mlx5/core/eq.c |   9 +-
 drivers/net/ethernet/mellanox/mlx5/core/qp.c | 128 ++++++++++++++++++++++++---
 include/linux/mlx5/device.h                  |   9 ++
 include/linux/mlx5/driver.h                  |   8 ++
 include/linux/mlx5/qp.h                      |  12 +++
 5 files changed, 153 insertions(+), 13 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/eq.c +8 -1
index 60771865c99c..7d3d503fa675 100644
@@ -417,7 +417,11 @@ static irqreturn_t mlx5_eq_int(int irq, void *eq_ptr)
 			cqn = be32_to_cpu(eqe->data.comp.cqn) & 0xffffff;
 			mlx5_cq_completion(dev, cqn);
 			break;
-
+		case MLX5_EVENT_TYPE_DCT_DRAINED:
+			rsn = be32_to_cpu(eqe->data.dct.dctn) & 0xffffff;
+			rsn |= (MLX5_RES_DCT << MLX5_USER_INDEX_LEN);
+			mlx5_rsc_event(dev, rsn, eqe->type);
+			break;
 		case MLX5_EVENT_TYPE_PATH_MIG:
 		case MLX5_EVENT_TYPE_COMM_EST:
 		case MLX5_EVENT_TYPE_SQ_DRAINED:
@@ -715,6 +719,9 @@ int mlx5_start_eqs(struct mlx5_core_dev *dev)
 
 	if (MLX5_CAP_GEN(dev, fpga))
 		async_event_mask |= (1ull << MLX5_EVENT_TYPE_FPGA_ERROR);
+	if (MLX5_CAP_GEN_MAX(dev, dct))
+		async_event_mask |= (1ull << MLX5_EVENT_TYPE_DCT_DRAINED);
+
 
 	err = mlx5_create_map_eq(dev, &table->cmd_eq, MLX5_EQ_VEC_CMD,
 				 MLX5_NUM_CMD_EQE, 1ull << MLX5_EVENT_TYPE_CMD,
drivers/net/ethernet/mellanox/mlx5/core/qp.c +116 -12

218 lines not on this page · raw message

include/linux/mlx5/device.h +9 -0
index 2ff9f48ebec3..e5258ee4e38b 100644
@@ -291,6 +291,7 @@ enum {
 	MLX5_EVENT_QUEUE_TYPE_QP = 0,
 	MLX5_EVENT_QUEUE_TYPE_RQ = 1,
 	MLX5_EVENT_QUEUE_TYPE_SQ = 2,
+	MLX5_EVENT_QUEUE_TYPE_DCT = 6,
 };
 
 enum mlx5_event {
@@ -326,6 +327,8 @@ enum mlx5_event {
 	MLX5_EVENT_TYPE_PAGE_FAULT	   = 0xc,
 	MLX5_EVENT_TYPE_NIC_VPORT_CHANGE   = 0xd,
 
+	MLX5_EVENT_TYPE_DCT_DRAINED        = 0x1c,
+
 	MLX5_EVENT_TYPE_FPGA_ERROR         = 0x20,
 };
 
@@ -618,6 +621,11 @@ struct mlx5_eqe_pps {
 	u8		rsvd2[12];
 } __packed;
 
+struct mlx5_eqe_dct {
+	__be32  reserved[6];
+	__be32  dctn;
+};
+
 union ev_data {
 	__be32				raw[7];
 	struct mlx5_eqe_cmd		cmd;
@@ -633,6 +641,7 @@ union ev_data {
 	struct mlx5_eqe_vport_change	vport_change;
 	struct mlx5_eqe_port_module	port_module;
 	struct mlx5_eqe_pps		pps;
+	struct mlx5_eqe_dct             dct;
 } __packed;
 
 struct mlx5_eqe {
include/linux/mlx5/driver.h +8 -0
index 4d1ed35fdbb4..b5eb5c55dcaf 100644
@@ -154,6 +154,13 @@ enum mlx5_dcbx_oper_mode {
 	MLX5E_DCBX_PARAM_VER_OPER_AUTO  = 0x3,
 };
 
+enum mlx5_dct_atomic_mode {
+	MLX5_ATOMIC_MODE_DCT_OFF        = 20,
+	MLX5_ATOMIC_MODE_DCT_NONE       = 0 << MLX5_ATOMIC_MODE_DCT_OFF,
+	MLX5_ATOMIC_MODE_DCT_IB_COMP    = 1 << MLX5_ATOMIC_MODE_DCT_OFF,
+	MLX5_ATOMIC_MODE_DCT_CX         = 2 << MLX5_ATOMIC_MODE_DCT_OFF,
+};
+
 enum {
 	MLX5_ATOMIC_OPS_CMP_SWAP	= 1 << 0,
 	MLX5_ATOMIC_OPS_FETCH_ADD	= 1 << 1,
@@ -432,6 +439,7 @@ enum mlx5_res_type {
 	MLX5_RES_SRQ	= 3,
 	MLX5_RES_XSRQ	= 4,
 	MLX5_RES_XRQ	= 5,
+	MLX5_RES_DCT	= MLX5_EVENT_QUEUE_TYPE_DCT,
 };
 
 struct mlx5_core_rsc_common {
include/linux/mlx5/qp.h +12 -0
index 62af7512dabb..4778d41085d4 100644
@@ -473,6 +473,11 @@ struct mlx5_core_qp {
 	int			pid;
 };
 
+struct mlx5_core_dct {
+	struct mlx5_core_qp	mqp;
+	struct completion	drained;
+};
+
 struct mlx5_qp_path {
 	u8			fl_free_ar;
 	u8			rsvd3;
@@ -549,6 +554,9 @@ static inline struct mlx5_core_mkey *__mlx5_mr_lookup(struct mlx5_core_dev *dev,
 	return radix_tree_lookup(&dev->priv.mkey_table.tree, key);
 }
 
+int mlx5_core_create_dct(struct mlx5_core_dev *dev,
+			 struct mlx5_core_dct *qp,
+			 u32 *in, int inlen);
 int mlx5_core_create_qp(struct mlx5_core_dev *dev,
 			struct mlx5_core_qp *qp,
 			u32 *in,
@@ -558,8 +566,12 @@ int mlx5_core_qp_modify(struct mlx5_core_dev *dev, u16 opcode,
 			struct mlx5_core_qp *qp);
 int mlx5_core_destroy_qp(struct mlx5_core_dev *dev,
 			 struct mlx5_core_qp *qp);
+int mlx5_core_destroy_dct(struct mlx5_core_dev *dev,
+			  struct mlx5_core_dct *dct);
 int mlx5_core_qp_query(struct mlx5_core_dev *dev, struct mlx5_core_qp *qp,
 		       u32 *out, int outlen);
+int mlx5_core_dct_query(struct mlx5_core_dev *dev, struct mlx5_core_dct *dct,
+			u32 *out, int outlen);
 
 int mlx5_core_set_delay_drop(struct mlx5_core_dev *dev,
 			     u32 timeout_usec);
Signature · 6 lines
2.15.1

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

A message that is not in the archive (sent off-list or not yet received): 20171226091634.2352-2-leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org

#4 lore raw

Re: [PATCH rdma-next 1/6] net/mlx5: Add DCT command interface

Quoted 4 lines · Leon Romanovsky

From: Moni Shoua <monis-VPRAkNaXOzVWk0Htik3J/[email protected]>

Add a missing command interface to work with a DCT. It includes: creating, destroying and get events for.

put the create/destroy_qprqsq_common thing into a pre patch

Or.
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

A message that is not in the archive (sent off-list or not yet received): CAJ3xEMhwLaBVU9re99cOe8cgRDcGPfJ=SWf4zYH6v8s_rrKNEg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org

#6 lore raw

Re: [PATCH rdma-next 1/6] net/mlx5: Add DCT command interface

Quoted 1 line

put the create/destroy_qprqsq_common thing into a pre patch

I don't think that just changing a name for a function justifies a separate patch especially if the reason is the use of it in the rest of the patch
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

A message that is not in the archive (sent off-list or not yet received): CAG9sBKOT3bGrpLb+cfzYuXofoAE_sDHLewy=fkFmnCVea_k2-w-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org

#8 lore raw

Re: [PATCH rdma-next 1/6] net/mlx5: Add DCT command interface

Quoted 5 lines · Moni Shoua
Quoted 1 line

put the create/destroy_qprqsq_common thing into a pre patch

I don't think that just changing a name for a function justifies a separate patch especially if the reason is the use of it in the rest of the patch

if you just changed the name, that makes sense
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#9 lore raw

Re: [PATCH rdma-next 1/6] net/mlx5: Add DCT command interface

In reply to a message not in the archive

drivers/net/ethernet/mellanox/mlx5/core/qp.c static void destroy_qprqsq_common(struct mlx5_core_dev *dev, · line 206

Quoted 9 lines · Leon Romanovsky
drivers/net/ethernet/mellanox/mlx5/core/qp.c +9 -0
+int mlx5_core_create_dct(struct mlx5_core_dev *dev,
+                        struct mlx5_core_dct *dct,
+                        u32 *in, int inlen)
+{
+       struct mlx5_core_qp *qp = &dct->mqp;
+       u32 out[MLX5_ST_SZ_DW(create_dct_out)]   = {0};
+       u32 din[MLX5_ST_SZ_DW(destroy_dct_in)]   = {0};
+       u32 dout[MLX5_ST_SZ_DW(destroy_dct_out)] = {0};
+       int err;

hey it's EOY now... can we do better with respect to reverse xmas tree here?

Quoted 37 lines
drivers/net/ethernet/mellanox/mlx5/core/qp.c +25 -1
+
+       init_completion(&dct->drained);
+       MLX5_SET(create_dct_in, in, opcode, MLX5_CMD_OP_CREATE_DCT);
+
+       err = mlx5_cmd_exec(dev, in, inlen, &out, sizeof(out));
+       if (err) {
+               mlx5_core_warn(dev, "create DCT failed, ret %d\n", err);
+               return err;
+       }
+
+       qp->qpn = MLX5_GET(create_dct_out, out, dctn);
+       err = create_resource_common(dev, qp, MLX5_RES_DCT);
+       if (err)
+               goto err_cmd;
+
+       return 0;
+err_cmd:
+       MLX5_SET(destroy_dct_in, din, opcode, MLX5_CMD_OP_DESTROY_DCT);
+       MLX5_SET(destroy_dct_in, din, dctn, qp->qpn);
+       mlx5_cmd_exec(dev, (void *)&in, sizeof(din), (void *)&out, sizeof(dout));
+       return err;
+}
+EXPORT_SYMBOL_GPL(mlx5_core_create_dct);
+
 int mlx5_core_create_qp(struct mlx5_core_dev *dev,
                        struct mlx5_core_qp *qp,
                        u32 *in, int inlen)
@@ -197,7 +246,7 @@ int mlx5_core_create_qp(struct mlx5_core_dev *dev,
        qp->qpn = MLX5_GET(create_qp_out, out, qpn);
        mlx5_core_dbg(dev, "qpn = 0x%x\n", qp->qpn);
 
-       err = create_qprqsq_common(dev, qp, MLX5_RES_QP);
+       err = create_resource_common(dev, qp, MLX5_RES_QP);
        if (err)
                goto err_cmd;
 

drivers/net/ethernet/mellanox/mlx5/core/qp.c int mlx5_core_create_qp(struct mlx5_core_dev *dev, · line 277

Quoted 9 lines
drivers/net/ethernet/mellanox/mlx5/core/qp.c +6 -0
@@ -220,6 +269,47 @@ int mlx5_core_create_qp(struct mlx5_core_dev *dev,
 }
 EXPORT_SYMBOL_GPL(mlx5_core_create_qp);
 
+static int mlx5_core_drain_dct(struct mlx5_core_dev *dev,
+                              struct mlx5_core_dct *dct)
+{
+       struct mlx5_core_qp *qp = &dct->mqp;
+       u32 out[MLX5_ST_SZ_DW(drain_dct_out)] = {0};
+       u32 in[MLX5_ST_SZ_DW(drain_dct_in)]   = {0};

same comment

Quoted 4 lines
drivers/net/ethernet/mellanox/mlx5/core/qp.c +4 -0
+
+       MLX5_SET(drain_dct_in, in, opcode, MLX5_CMD_OP_DRAIN_DCT);
+       MLX5_SET(drain_dct_in, in, dctn, qp->qpn);
+       return mlx5_cmd_exec(dev, (void *)&in, sizeof(in),

drivers/net/ethernet/mellanox/mlx5/core/qp.c int mlx5_core_create_qp(struct mlx5_core_dev *dev, · line 291

Quoted 10 lines
drivers/net/ethernet/mellanox/mlx5/core/qp.c +10 -0
+                            (void *)&out, sizeof(out));
+}
+
+int mlx5_core_destroy_dct(struct mlx5_core_dev *dev,
+                         struct mlx5_core_dct *dct)
+{
+       struct mlx5_core_qp *qp = &dct->mqp;
+       u32 out[MLX5_ST_SZ_DW(destroy_dct_out)] = {0};
+       u32 in[MLX5_ST_SZ_DW(destroy_dct_in)]   = {0};
+       int err;

same comment
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#10 lore raw

Re: [PATCH rdma-next 1/6] net/mlx5: Add DCT command interface

In reply to a message not in the archive
Quoted 20 lines · Leon Romanovsky

From: Moni Shoua <monis-VPRAkNaXOzVWk0Htik3J/[email protected]>

Add a missing command interface to work with a DCT. It includes: creating, destroying and get events for.

---
 drivers/net/ethernet/mellanox/mlx5/core/eq.c |   9 +-
 drivers/net/ethernet/mellanox/mlx5/core/qp.c | 128 ++++++++++++++++++++++++---
 include/linux/mlx5/device.h                  |   9 ++
 include/linux/mlx5/driver.h                  |   8 ++
 include/linux/mlx5/qp.h                      |  12 +++
 5 files changed, 153 insertions(+), 13 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/eq.c +0 -0
index 60771865c99c..7d3d503fa675 100644

drivers/net/ethernet/mellanox/mlx5/core/eq.c

Quoted 8 lines
drivers/net/ethernet/mellanox/mlx5/core/eq.c +7 -0
 
+static u64 dct_allowed_event_types(void)
+{
+	u64 mask;
+
+	mask = BIT(MLX5_EVENT_TYPE_DCT_DRAINED);
+
+	return mask;

We don't really need this "mask" variable, right?

drivers/net/ethernet/mellanox/mlx5/core/eq.c

Quoted 2 lines
drivers/net/ethernet/mellanox/mlx5/core/eq.c +2 -0
+}
+

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#11 lore raw

Re: [PATCH rdma-next 1/6] net/mlx5: Add DCT command interface

Quoted 22 lines · Yuval Shaia
Quoted 21 lines · Leon Romanovsky

From: Moni Shoua <monis-VPRAkNaXOzVWk0Htik3J/[email protected]>

Add a missing command interface to work with a DCT. It includes: creating, destroying and get events for.

---
 drivers/net/ethernet/mellanox/mlx5/core/eq.c |   9 +-
 drivers/net/ethernet/mellanox/mlx5/core/qp.c | 128 ++++++++++++++++++++++++---
 include/linux/mlx5/device.h                  |   9 ++
 include/linux/mlx5/driver.h                  |   8 ++
 include/linux/mlx5/qp.h                      |  12 +++
 5 files changed, 153 insertions(+), 13 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/eq.c +0 -0
index 60771865c99c..7d3d503fa675 100644
Quoted 9 lines

drivers/net/ethernet/mellanox/mlx5/core/eq.c

Quoted 7 lines
drivers/net/ethernet/mellanox/mlx5/core/eq.c +7 -0
+static u64 dct_allowed_event_types(void)
+{
+	u64 mask;
+
+	mask = BIT(MLX5_EVENT_TYPE_DCT_DRAINED);
+
+	return mask;

We don't really need this "mask" variable, right?

I removed it in v1 and it won't be in v2 too.

Thanks

Quoted 3 lines
Quoted 3 lines
drivers/net/ethernet/mellanox/mlx5/core/eq.c +2 -0
+}
+
#12 lore raw

PATCH 2/6 net/mlx5: Enable DC transport

In reply to a message not in the archive

From: Moni Shoua <monis-VPRAkNaXOzVWk0Htik3J/[email protected]>

Enable DC transport in the firmware to enable using its functionality.

---
 drivers/net/ethernet/mellanox/mlx5/core/main.c | 3 +++
 1 file changed, 3 insertions(+)
drivers/net/ethernet/mellanox/mlx5/core/main.c +3 -0
index 77c9f7e42a99..75774f0fb579 100644
@@ -560,6 +560,9 @@ static int handle_hca_cap(struct mlx5_core_dev *dev)
 			 num_vhca_ports,
 			 MLX5_CAP_GEN_MAX(dev, num_vhca_ports));
 
+	if (MLX5_CAP_GEN_MAX(dev, dct))
+		MLX5_SET(cmd_hca_cap, set_hca_cap, dct, 1);
+
 	err = set_caps(dev, set_ctx, set_sz,
 		       MLX5_SET_HCA_CAP_OP_MOD_GENERAL_DEVICE);
 
Signature · 6 lines
2.15.1

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#13 lore raw

PATCH 3/6 IB/core: Introduce driver QP type

In reply to a message not in the archive

From: Moni Shoua <monis-VPRAkNaXOzVWk0Htik3J/[email protected]>

Vendors can implement type of QPs that are not described in the InfiniBand specification. To still be able to use the IB/core layer services (e.g. user object management) without tainting this layer with driver proprietary logic, a new QP type is added - IB_QPT_DRIVER. This will be a general QP type that the core layer doesn't know about its true nature. When a command like create_qp() is passed to a hardware driver the extra data that is required is taken from the driver channel.
Downstream patches from this series will use that QP type in the mlx5 driver.

---
 include/rdma/ib_verbs.h | 1 +
 1 file changed, 1 insertion(+)
include/rdma/ib_verbs.h +1 -0
index 64032f4c8d5a..41d4f59cac5e 100644
@@ -1083,6 +1083,7 @@ enum ib_qp_type {
 	IB_QPT_XRC_INI = 9,
 	IB_QPT_XRC_TGT,
 	IB_QPT_MAX,
+	IB_QPT_DRIVER = 0xFF,
 	/* Reserve a range for qp types internal to the low level driver.
 	 * These qp types will not be visible at the IB core layer, so the
 	 * IB_QPT_MAX usages should not be affected in the core layer
Signature · 6 lines
2.15.1

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#14 lore raw

PATCH 4/6 IB/mlx5: Handle type IB_QPT_DRIVER when creating a QP

In reply to a message not in the archive

From: Moni Shoua <monis-VPRAkNaXOzVWk0Htik3J/[email protected]>

The QP type IB_QPT_DRIVER doesn't describe the transport or the service that the QP provides but those are known only to the hardware driver. The extra data that tells more about the QP is in the driver channel.
Take the real QP type from the driver channel and modify the QP initial attributes before continuing with create_qp(). Also, define the layout of the data structure that comes in the driver channel. Downstream patches from this series will add support for both DCI and DCT driver QPs.

---
 drivers/infiniband/hw/mlx5/mlx5_ib.h |  3 ++
 drivers/infiniband/hw/mlx5/qp.c      | 57 +++++++++++++++++++++++++++++++++++-
 include/uapi/rdma/mlx5-abi.h         |  7 ++++-
 3 files changed, 65 insertions(+), 2 deletions(-)
drivers/infiniband/hw/mlx5/mlx5_ib.h +3 -0
index 88b89ed15d1c..66e9c2190f2d 100644
@@ -202,6 +202,8 @@ struct mlx5_ib_flow_db {
  * creates the actual hardware QP.
  */
 #define MLX5_IB_QPT_HW_GSI	IB_QPT_RESERVED2
+#define MLX5_IB_QPT_DCI		IB_QPT_RESERVED3
+#define MLX5_IB_QPT_DCT		IB_QPT_RESERVED4
 #define MLX5_IB_WR_UMR		IB_WR_RESERVED1
 
 #define MLX5_IB_UMR_OCTOWORD	       16
@@ -406,6 +408,7 @@ struct mlx5_ib_qp {
 	u32			rate_limit;
 	u32                     underlay_qpn;
 	bool			tunnel_offload_en;
+	u32			driver_qp_type;
 };
 
 struct mlx5_ib_cq_buf {
drivers/infiniband/hw/mlx5/qp.c +56 -1

88 lines not on this page · raw message

include/uapi/rdma/mlx5-abi.h +6 -1
index 0f7e45680ce5..83bde975d3f9 100644
@@ -42,6 +42,8 @@ enum {
 	MLX5_QP_FLAG_SCATTER_CQE	= 1 << 1,
 	MLX5_QP_FLAG_TUNNEL_OFFLOADS	= 1 << 2,
 	MLX5_QP_FLAG_BFREG_INDEX	= 1 << 3,
+	MLX5_QP_FLAG_TYPE_DCT		= 1 << 4,
+	MLX5_QP_FLAG_TYPE_DCI		= 1 << 5,
 };
 
 enum {
@@ -284,7 +286,10 @@ struct mlx5_ib_create_qp {
 	__u32	flags;
 	__u32	uidx;
 	__u32	bfreg_index;
-	__u64	sq_buf_addr;
+	union {
+		__u64	sq_buf_addr;
+		__u64	access_key;
+	};
 };
 
 /* RX Hash function flags */
Signature · 6 lines
2.15.1

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#15 lore raw

PATCH 5/6 IB/mlx5: Add support for DC Initiator QP

In reply to a message not in the archive

From: Moni Shoua <monis-VPRAkNaXOzVWk0Htik3J/[email protected]>

DC Initiator (DCI) QP is represented like any other QP in the hardware. However, like any other transport QP there are attributes and settings that are special to DCI QP and needs specific attention and care. Make necessary changes to configure DCI QP.

---
 drivers/infiniband/hw/mlx5/qp.c | 77 ++++++++++++++++++++++++++++++++++++++---
 1 file changed, 72 insertions(+), 5 deletions(-)
drivers/infiniband/hw/mlx5/qp.c +72 -5
index f1a2b1ade804..87613c8edac1 100644
@@ -613,6 +613,7 @@ static int to_mlx5_st(enum ib_qp_type type)
 	case IB_QPT_XRC_TGT:		return MLX5_QP_ST_XRC;
 	case IB_QPT_SMI:		return MLX5_QP_ST_QP0;
 	case MLX5_IB_QPT_HW_GSI:	return MLX5_QP_ST_QP1;
+	case MLX5_IB_QPT_DCI:		return MLX5_QP_ST_DCI;
 	case IB_QPT_RAW_IPV6:		return MLX5_QP_ST_RAW_IPV6;
 	case IB_QPT_RAW_PACKET:
 	case IB_QPT_RAW_ETHERTYPE:	return MLX5_QP_ST_RAW_ETHERTYPE;
@@ -1044,6 +1045,7 @@ static void destroy_qp_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp)
 static u32 get_rx_type(struct mlx5_ib_qp *qp, struct ib_qp_init_attr *attr)
 {
 	if (attr->srq || (attr->qp_type == IB_QPT_XRC_TGT) ||
+	    (attr->qp_type == MLX5_IB_QPT_DCI) ||
 	    (attr->qp_type == IB_QPT_XRC_INI))
 		return MLX5_SRQ_RQ;
 	else if (!qp->has_rq)
@@ -2203,6 +2205,14 @@ struct ib_qp *mlx5_ib_create_qp(struct ib_pd *pd,
 		err = validate_driver_qp(dev, init_attr, &ucmd, udata);
 		if (err)
 			return ERR_PTR(err);
+
+		if (init_attr->qp_type == MLX5_IB_QPT_DCI) {
+			if (init_attr->cap.max_recv_wr ||
+			    init_attr->cap.max_recv_sge) {
+				mlx5_ib_dbg(dev, "DCI QP requires zero size receive queue\n");
+				return ERR_PTR(-EINVAL);
+			}
+		}
 	}
 
 	switch (init_attr->qp_type) {
@@ -2226,6 +2236,7 @@ struct ib_qp *mlx5_ib_create_qp(struct ib_pd *pd,
 	case IB_QPT_SMI:
 	case MLX5_IB_QPT_HW_GSI:
 	case MLX5_IB_QPT_REG_UMR:
+	case MLX5_IB_QPT_DCI:
 		qp = kzalloc(sizeof(*qp), GFP_KERNEL);
 		if (!qp)
 			return ERR_PTR(-ENOMEM);
@@ -2847,7 +2858,8 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
 	if (!context)
 		return -ENOMEM;
 
-	err = to_mlx5_st(ibqp->qp_type);
+	err = to_mlx5_st(ibqp->qp_type == IB_QPT_DRIVER ?
+			 qp->driver_qp_type : ibqp->qp_type);
 	if (err < 0) {
 		mlx5_ib_dbg(dev, "unsupported qp type %d\n", ibqp->qp_type);
 		goto out;
@@ -3007,7 +3019,8 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
 
 	mlx5_cur = to_mlx5_state(cur_state);
 	mlx5_new = to_mlx5_state(new_state);
-	mlx5_st = to_mlx5_st(ibqp->qp_type);
+	mlx5_st = to_mlx5_st(ibqp->qp_type == IB_QPT_DRIVER ?
+			     qp->driver_qp_type : ibqp->qp_type);
 	if (mlx5_st < 0)
 		goto out;
 
@@ -3079,6 +3092,50 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
 	return err;
 }
 
+static inline bool is_valid_mask(int mask, int req, int opt)
+{
+	if ((mask & req) != req)
+		return false;
+
+	if (mask & ~(req | opt))
+		return false;
+
+	return true;
+}
+
+/* check valid transition for driver QP types
+ * for now the only QP type that this function supports is DCI
+ */
+static bool mlx5_ib_modify_qp_is_ok(enum ib_qp_state cur_state, enum ib_qp_state new_state,
+				    enum ib_qp_attr_mask attr_mask)
+{
+	int req = IB_QP_STATE;
+	int opt = 0;
+
+	if (cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT) {
+		req |= IB_QP_PKEY_INDEX | IB_QP_PORT;
+		return is_valid_mask(attr_mask, req, opt);
+	} else if (cur_state == IB_QPS_INIT && new_state == IB_QPS_INIT) {
+		opt = IB_QP_PKEY_INDEX | IB_QP_PORT;
+		return is_valid_mask(attr_mask, req, opt);
+	} else if (cur_state == IB_QPS_INIT && new_state == IB_QPS_RTR) {
+		req |= IB_QP_PATH_MTU;
+		opt = IB_QP_PKEY_INDEX;
+		return is_valid_mask(attr_mask, req, opt);
+	} else if (cur_state == IB_QPS_RTR && new_state == IB_QPS_RTS) {
+		req |= IB_QP_TIMEOUT | IB_QP_RETRY_CNT | IB_QP_RNR_RETRY |
+		       IB_QP_MAX_QP_RD_ATOMIC | IB_QP_SQ_PSN;
+		opt = IB_QP_MIN_RNR_TIMER;
+		return is_valid_mask(attr_mask, req, opt);
+	} else if (cur_state == IB_QPS_RTS && new_state == IB_QPS_RTS) {
+		opt = IB_QP_MIN_RNR_TIMER;
+		return is_valid_mask(attr_mask, req, opt);
+	} else if (cur_state != IB_QPS_RESET && new_state == IB_QPS_ERR) {
+		return is_valid_mask(attr_mask, req, opt);
+	}
+	return false;
+}
+
 int mlx5_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
 		      int attr_mask, struct ib_udata *udata)
 {
@@ -3096,8 +3153,12 @@ int mlx5_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
 	if (unlikely(ibqp->qp_type == IB_QPT_GSI))
 		return mlx5_ib_gsi_modify_qp(ibqp, attr, attr_mask);
 
-	qp_type = (unlikely(ibqp->qp_type == MLX5_IB_QPT_HW_GSI)) ?
-		IB_QPT_GSI : ibqp->qp_type;
+	if (ibqp->qp_type == IB_QPT_DRIVER)
+		qp_type = qp->driver_qp_type;
+	else
+		qp_type = (unlikely(ibqp->qp_type == MLX5_IB_QPT_HW_GSI)) ?
+			IB_QPT_GSI : ibqp->qp_type;
+
 
 	mutex_lock(&qp->mutex);
 
@@ -3116,10 +3177,16 @@ int mlx5_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
 			goto out;
 		}
 	} else if (qp_type != MLX5_IB_QPT_REG_UMR &&
-	    !ib_modify_qp_is_ok(cur_state, new_state, qp_type, attr_mask, ll)) {
+		   qp_type != MLX5_IB_QPT_DCI &&
+		   !ib_modify_qp_is_ok(cur_state, new_state, qp_type, attr_mask, ll)) {
 		mlx5_ib_dbg(dev, "invalid QP state transition from %d to %d, qp_type %d, attr_mask 0x%x\n",
 			    cur_state, new_state, ibqp->qp_type, attr_mask);
 		goto out;
+	} else if (qp_type == MLX5_IB_QPT_DCI &&
+		   !mlx5_ib_modify_qp_is_ok(cur_state, new_state, attr_mask)) {
+		mlx5_ib_dbg(dev, "invalid QP state transition from %d to %d, qp_type %d, attr_mask 0x%x\n",
+			    cur_state, new_state, qp_type, attr_mask);
+		goto out;
 	}
 
 	if ((attr_mask & IB_QP_PORT) &&
Signature · 6 lines
2.15.1

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#16 lore raw

PATCH 6/6 IB/mlx5: Add support for DC target QP

In reply to a message not in the archive

From: Moni Shoua <monis-VPRAkNaXOzVWk0Htik3J/[email protected]>

A DC Target (DCT) QP is represented in the hardware as a unique object. This object is created by CREATE_DCT command and destroyed by DESTROY_DCT command. However, in the driver we describe it as a QP. The hardware command that creates a DCT needs parameters that the verb create_qp() does not provide. Those remaining parameters are provided with the call to the verb modify_qp(). Therefore we delay the actual creation of a DCT in the hardware until the stage of modify_qp() to RTR.
A support for query_qp() was added as well. It uses QUERY_DCT command to retrieve the applicable fields.

---
 drivers/infiniband/hw/mlx5/main.c    |  27 +++-
 drivers/infiniband/hw/mlx5/mlx5_ib.h |   8 ++
 drivers/infiniband/hw/mlx5/qp.c      | 231 +++++++++++++++++++++++++++++++++++
 include/uapi/rdma/mlx5-abi.h         |   5 +
 4 files changed, 269 insertions(+), 2 deletions(-)
drivers/infiniband/hw/mlx5/main.c +25 -2
index 9c737cc65503..5d596bff798b 100644
@@ -561,11 +561,11 @@ static int mlx5_get_vport_access_method(struct ib_device *ibdev)
 }
 
 static void get_atomic_caps(struct mlx5_ib_dev *dev,
+			    u8 atomic_size_qp,
 			    struct ib_device_attr *props)
 {
 	u8 tmp;
 	u8 atomic_operations = MLX5_CAP_ATOMIC(dev->mdev, atomic_operations);
-	u8 atomic_size_qp = MLX5_CAP_ATOMIC(dev->mdev, atomic_size_qp);
 	u8 atomic_req_8B_endianness_mode =
 		MLX5_CAP_ATOMIC(dev->mdev, atomic_req_8B_endianness_mode);
 
@@ -582,6 +582,29 @@ static void get_atomic_caps(struct mlx5_ib_dev *dev,
 	}
 }
 
+static void get_atomic_caps_qp(struct mlx5_ib_dev *dev,
+			       struct ib_device_attr *props)
+{
+	u8 atomic_size_qp = MLX5_CAP_ATOMIC(dev->mdev, atomic_size_qp);
+
+	get_atomic_caps(dev, atomic_size_qp, props);
+}
+
+static void get_atomic_caps_dc(struct mlx5_ib_dev *dev,
+			       struct ib_device_attr *props)
+{
+	u8 atomic_size_qp = MLX5_CAP_ATOMIC(dev->mdev, atomic_size_dc);
+
+	get_atomic_caps(dev, atomic_size_qp, props);
+}
+
+bool mlx5_ib_dc_atomic_is_supported(struct mlx5_ib_dev *dev)
+{
+	struct ib_device_attr props = {};
+
+	get_atomic_caps_dc(dev, &props);
+	return (props.atomic_cap == IB_ATOMIC_HCA) ? true : false;
+}
 static int mlx5_query_system_image_guid(struct ib_device *ibdev,
 					__be64 *sys_image_guid)
 {
@@ -873,7 +896,7 @@ static int mlx5_ib_query_device(struct ib_device *ibdev,
 	props->max_srq_sge	   = max_rq_sg - 1;
 	props->max_fast_reg_page_list_len =
 		1 << MLX5_CAP_GEN(mdev, log_max_klm_list_size);
-	get_atomic_caps(dev, props);
+	get_atomic_caps_qp(dev, props);
 	props->masked_atomic_cap   = IB_ATOMIC_NONE;
 	props->max_mcast_grp	   = 1 << MLX5_CAP_GEN(mdev, log_max_mcg);
 	props->max_mcast_qp_attach = MLX5_CAP_GEN(mdev, max_qp_mcg);
drivers/infiniband/hw/mlx5/mlx5_ib.h +8 -0
index 66e9c2190f2d..81de3c1f5e97 100644
@@ -364,12 +364,18 @@ struct mlx5_bf {
 	struct mlx5_sq_bfreg   *bfreg;
 };
 
+struct mlx5_ib_dct {
+	struct mlx5_core_dct	mdct;
+	u32			*in;
+};
+
 struct mlx5_ib_qp {
 	struct ib_qp		ibqp;
 	union {
 		struct mlx5_ib_qp_trans trans_qp;
 		struct mlx5_ib_raw_packet_qp raw_packet_qp;
 		struct mlx5_ib_rss_qp rss_qp;
+		struct mlx5_ib_dct dct;
 	};
 	struct mlx5_buf		buf;
 
@@ -1022,6 +1028,8 @@ struct ib_rwq_ind_table *mlx5_ib_create_rwq_ind_table(struct ib_device *device,
 						      struct ib_rwq_ind_table_init_attr *init_attr,
 						      struct ib_udata *udata);
 int mlx5_ib_destroy_rwq_ind_table(struct ib_rwq_ind_table *wq_ind_table);
+bool mlx5_ib_dc_atomic_is_supported(struct mlx5_ib_dev *dev);
+
 
 #ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING
 void mlx5_ib_internal_fill_odp_caps(struct mlx5_ib_dev *dev);
drivers/infiniband/hw/mlx5/qp.c +231 -0

279 lines not on this page · raw message

include/uapi/rdma/mlx5-abi.h +5 -0
index 83bde975d3f9..f6d319dfc7bf 100644
@@ -362,6 +362,11 @@ struct mlx5_ib_create_ah_resp {
 	__u8	reserved[6];
 };
 
+struct mlx5_ib_modify_qp_resp {
+	__u32	response_length;
+	__u32	dctn;
+};
+
 struct mlx5_ib_create_wq_resp {
 	__u32	response_length;
 	__u32	reserved;
Signature · 6 lines
2.15.1

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html