|
@@ -65,6 +65,7 @@ static const u32 mlx5_ib_opcode[] = {
|
|
|
[IB_WR_SEND_WITH_INV] = MLX5_OPCODE_SEND_INVAL,
|
|
|
[IB_WR_LOCAL_INV] = MLX5_OPCODE_UMR,
|
|
|
[IB_WR_FAST_REG_MR] = MLX5_OPCODE_UMR,
|
|
|
+ [IB_WR_REG_MR] = MLX5_OPCODE_UMR,
|
|
|
[IB_WR_MASKED_ATOMIC_CMP_AND_SWP] = MLX5_OPCODE_ATOMIC_MASKED_CS,
|
|
|
[IB_WR_MASKED_ATOMIC_FETCH_AND_ADD] = MLX5_OPCODE_ATOMIC_MASKED_FA,
|
|
|
[MLX5_IB_WR_UMR] = MLX5_OPCODE_UMR,
|
|
@@ -1896,6 +1897,17 @@ static __be64 sig_mkey_mask(void)
|
|
|
return cpu_to_be64(result);
|
|
|
}
|
|
|
|
|
|
+static void set_reg_umr_seg(struct mlx5_wqe_umr_ctrl_seg *umr,
|
|
|
+ struct mlx5_ib_mr *mr)
|
|
|
+{
|
|
|
+ int ndescs = mr->ndescs;
|
|
|
+
|
|
|
+ memset(umr, 0, sizeof(*umr));
|
|
|
+ umr->flags = MLX5_UMR_CHECK_NOT_FREE;
|
|
|
+ umr->klm_octowords = get_klm_octo(ndescs);
|
|
|
+ umr->mkey_mask = frwr_mkey_mask();
|
|
|
+}
|
|
|
+
|
|
|
static void set_frwr_umr_segment(struct mlx5_wqe_umr_ctrl_seg *umr,
|
|
|
struct ib_send_wr *wr, int li)
|
|
|
{
|
|
@@ -1987,6 +1999,22 @@ static u8 get_umr_flags(int acc)
|
|
|
MLX5_PERM_LOCAL_READ | MLX5_PERM_UMR_EN;
|
|
|
}
|
|
|
|
|
|
+static void set_reg_mkey_seg(struct mlx5_mkey_seg *seg,
|
|
|
+ struct mlx5_ib_mr *mr,
|
|
|
+ u32 key, int access)
|
|
|
+{
|
|
|
+ int ndescs = ALIGN(mr->ndescs, 8) >> 1;
|
|
|
+
|
|
|
+ memset(seg, 0, sizeof(*seg));
|
|
|
+ seg->flags = get_umr_flags(access) | MLX5_ACCESS_MODE_MTT;
|
|
|
+ seg->qpn_mkey7_0 = cpu_to_be32((key & 0xff) | 0xffffff00);
|
|
|
+ seg->flags_pd = cpu_to_be32(MLX5_MKEY_REMOTE_INVAL);
|
|
|
+ seg->start_addr = cpu_to_be64(mr->ibmr.iova);
|
|
|
+ seg->len = cpu_to_be64(mr->ibmr.length);
|
|
|
+ seg->xlt_oct_size = cpu_to_be32(ndescs);
|
|
|
+ seg->log2_page_size = ilog2(mr->ibmr.page_size);
|
|
|
+}
|
|
|
+
|
|
|
static void set_mkey_segment(struct mlx5_mkey_seg *seg, struct ib_send_wr *wr,
|
|
|
int li, int *writ)
|
|
|
{
|
|
@@ -2028,6 +2056,17 @@ static void set_reg_mkey_segment(struct mlx5_mkey_seg *seg, struct ib_send_wr *w
|
|
|
mlx5_mkey_variant(umrwr->mkey));
|
|
|
}
|
|
|
|
|
|
+static void set_reg_data_seg(struct mlx5_wqe_data_seg *dseg,
|
|
|
+ struct mlx5_ib_mr *mr,
|
|
|
+ struct mlx5_ib_pd *pd)
|
|
|
+{
|
|
|
+ int bcount = mr->desc_size * mr->ndescs;
|
|
|
+
|
|
|
+ dseg->addr = cpu_to_be64(mr->desc_map);
|
|
|
+ dseg->byte_count = cpu_to_be32(ALIGN(bcount, 64));
|
|
|
+ dseg->lkey = cpu_to_be32(pd->ibpd.local_dma_lkey);
|
|
|
+}
|
|
|
+
|
|
|
static void set_frwr_pages(struct mlx5_wqe_data_seg *dseg,
|
|
|
struct ib_send_wr *wr,
|
|
|
struct mlx5_core_dev *mdev,
|
|
@@ -2433,6 +2472,38 @@ static int set_psv_wr(struct ib_sig_domain *domain,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static int set_reg_wr(struct mlx5_ib_qp *qp,
|
|
|
+ struct ib_reg_wr *wr,
|
|
|
+ void **seg, int *size)
|
|
|
+{
|
|
|
+ struct mlx5_ib_mr *mr = to_mmr(wr->mr);
|
|
|
+ struct mlx5_ib_pd *pd = to_mpd(qp->ibqp.pd);
|
|
|
+
|
|
|
+ if (unlikely(wr->wr.send_flags & IB_SEND_INLINE)) {
|
|
|
+ mlx5_ib_warn(to_mdev(qp->ibqp.device),
|
|
|
+ "Invalid IB_SEND_INLINE send flag\n");
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ set_reg_umr_seg(*seg, mr);
|
|
|
+ *seg += sizeof(struct mlx5_wqe_umr_ctrl_seg);
|
|
|
+ *size += sizeof(struct mlx5_wqe_umr_ctrl_seg) / 16;
|
|
|
+ if (unlikely((*seg == qp->sq.qend)))
|
|
|
+ *seg = mlx5_get_send_wqe(qp, 0);
|
|
|
+
|
|
|
+ set_reg_mkey_seg(*seg, mr, wr->key, wr->access);
|
|
|
+ *seg += sizeof(struct mlx5_mkey_seg);
|
|
|
+ *size += sizeof(struct mlx5_mkey_seg) / 16;
|
|
|
+ if (unlikely((*seg == qp->sq.qend)))
|
|
|
+ *seg = mlx5_get_send_wqe(qp, 0);
|
|
|
+
|
|
|
+ set_reg_data_seg(*seg, mr, pd);
|
|
|
+ *seg += sizeof(struct mlx5_wqe_data_seg);
|
|
|
+ *size += (sizeof(struct mlx5_wqe_data_seg) / 16);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
static int set_frwr_li_wr(void **seg, struct ib_send_wr *wr, int *size,
|
|
|
struct mlx5_core_dev *mdev, struct mlx5_ib_pd *pd, struct mlx5_ib_qp *qp)
|
|
|
{
|
|
@@ -2675,6 +2746,18 @@ int mlx5_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
|
|
|
num_sge = 0;
|
|
|
break;
|
|
|
|
|
|
+ case IB_WR_REG_MR:
|
|
|
+ next_fence = MLX5_FENCE_MODE_INITIATOR_SMALL;
|
|
|
+ qp->sq.wr_data[idx] = IB_WR_REG_MR;
|
|
|
+ ctrl->imm = cpu_to_be32(reg_wr(wr)->key);
|
|
|
+ err = set_reg_wr(qp, reg_wr(wr), &seg, &size);
|
|
|
+ if (err) {
|
|
|
+ *bad_wr = wr;
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+ num_sge = 0;
|
|
|
+ break;
|
|
|
+
|
|
|
case IB_WR_REG_SIG_MR:
|
|
|
qp->sq.wr_data[idx] = IB_WR_REG_SIG_MR;
|
|
|
mr = to_mmr(sig_handover_wr(wr)->sig_mr);
|