Signed-off-by: Eran Ben Elisha <[email protected]>
Reviewed-by: Majd Dibbiny <[email protected]>
---
Hi Eli,
Added here support for atomic standard operations.
Kernel part of query_device was sent to the mailing list also.
Obviously, it will functionality work only with kernel patches applied.
Thanks,
Eran
src/mlx5.c | 8 ++++++++
src/mlx5.h | 2 ++
src/qp.c | 50 +++++++++++++++++++++++++++++++++++++++++++++-----
src/verbs.c | 2 ++
4 files changed, 57 insertions(+), 5 deletions(-)
diff --git a/src/mlx5.c b/src/mlx5.c
index e44898a..078ac8a 100644
--- a/src/mlx5.c
+++ b/src/mlx5.c
@@ -472,6 +472,8 @@ static int mlx5_init_context(struct verbs_device *vdev,
off_t offset;
struct mlx5_device *mdev;
struct verbs_context *v_ctx;
+ struct ibv_device_attr attr;
+ int err;
mdev = to_mdev(&vdev->device);
v_ctx = verbs_get_ctx(ctx);
@@ -585,6 +587,12 @@ static int mlx5_init_context(struct verbs_device *vdev,
verbs_set_ctx_op(v_ctx, get_srq_num, mlx5_get_srq_num);
verbs_set_ctx_op(v_ctx, query_device_ex, mlx5_query_device_ex);
+ err = mlx5_query_device(ctx, &attr);
+ if (err)
+ goto err_free_bf;
+
+ context->atomic_cap = attr.atomic_cap;
+
return 0;
err_free_bf:
diff --git a/src/mlx5.h b/src/mlx5.h
index 9181ec5..704a922 100644
--- a/src/mlx5.h
+++ b/src/mlx5.h
@@ -282,6 +282,7 @@ struct mlx5_context {
char hostname[40];
struct mlx5_spinlock hugetlb_lock;
struct list_head hugetlb_list;
+ enum ibv_atomic_cap atomic_cap;
};
struct mlx5_bitmap {
@@ -405,6 +406,7 @@ struct mlx5_qp {
uint32_t *db;
struct mlx5_wq rq;
int wq_sig;
+ int atomics_enabled;
};
struct mlx5_av {
diff --git a/src/qp.c b/src/qp.c
index 67ded0d..841788c 100644
--- a/src/qp.c
+++ b/src/qp.c
@@ -180,6 +180,20 @@ static inline void set_raddr_seg(struct mlx5_wqe_raddr_seg
*rseg,
rseg->reserved = 0;
}
+static void set_atomic_seg(struct mlx5_wqe_atomic_seg *aseg,
+ enum ibv_wr_opcode opcode,
+ uint64_t swap,
+ uint64_t compare_add)
+{
+ if (opcode == IBV_WR_ATOMIC_CMP_AND_SWP) {
+ aseg->swap_add = htonll(swap);
+ aseg->compare = htonll(compare_add);
+ } else {
+ aseg->swap_add = htonll(compare_add);
+ aseg->compare = 0;
+ }
+}
+
static void set_datagram_seg(struct mlx5_wqe_datagram_seg *dseg,
struct ibv_send_wr *wr)
{
@@ -336,6 +350,7 @@ int mlx5_post_send(struct ibv_qp *ibqp, struct ibv_send_wr
*wr,
void *qend = qp->sq.qend;
uint32_t mlx5_opcode;
struct mlx5_wqe_xrc_seg *xrc;
+ int atom_arg = 0;
#ifdef MLX5_DEBUG
FILE *fp = to_mctx(ibqp->context)->dbg_fp;
#endif
@@ -405,10 +420,25 @@ int mlx5_post_send(struct ibv_qp *ibqp, struct
ibv_send_wr *wr,
case IBV_WR_ATOMIC_CMP_AND_SWP:
case IBV_WR_ATOMIC_FETCH_AND_ADD:
- fprintf(stderr, "atomic operations are not
supported yet\n");
- err = ENOSYS;
- *bad_wr = wr;
- goto out;
+ if (unlikely(!qp->atomics_enabled)) {
+ mlx5_dbg(fp, MLX5_DBG_QP_SEND, "atomic
operations are not supported\n");
+ err = ENOSYS;
+ *bad_wr = wr;
+ goto out;
+ }
+ set_raddr_seg(seg, wr->wr.atomic.remote_addr,
+ wr->wr.atomic.rkey);
+ seg += sizeof(struct mlx5_wqe_raddr_seg);
+
+ set_atomic_seg(seg, wr->opcode,
+ wr->wr.atomic.swap,
+ wr->wr.atomic.compare_add);
+ seg += sizeof(struct mlx5_wqe_atomic_seg);
+
+ size += (sizeof(struct mlx5_wqe_raddr_seg) +
+ sizeof(struct mlx5_wqe_atomic_seg)) / 16;
+ atom_arg = 8;
+ break;
default:
break;
@@ -462,7 +492,17 @@ int mlx5_post_send(struct ibv_qp *ibqp, struct ibv_send_wr
*wr,
dpseg = seg;
}
if (likely(wr->sg_list[i].length)) {
- set_data_ptr_seg(dpseg, wr->sg_list +
i);
+ struct ibv_sge sge;
+ struct ibv_sge *psge;
+
+ if (unlikely(atom_arg)) {
+ sge = wr->sg_list[i];
+ sge.length = atom_arg;
+ psge = &sge;
+ } else {
+ psge = wr->sg_list + i;
+ }
+ set_data_ptr_seg(dpseg, psge);
++dpseg;
size += sizeof(struct
mlx5_wqe_data_seg) / 16;
}
diff --git a/src/verbs.c b/src/verbs.c
index 8cbdd68..f96790b 100644
--- a/src/verbs.c
+++ b/src/verbs.c
@@ -1001,6 +1001,8 @@ struct ibv_qp *create_qp(struct ibv_context *context,
qp->db[MLX5_RCV_DBR] = 0;
qp->db[MLX5_SND_DBR] = 0;
+ if (ctx->atomic_cap == IBV_ATOMIC_HCA)
+ qp->atomics_enabled = 1;
pthread_mutex_lock(&ctx->qp_table_mutex);
--
1.8.3.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