Skip to contentSkip to conversation

libmlx4: fix possible inline size

PATCH Superseded Eli Cohen 1 participant 1 message Sep 16, 2010 InfiniBand

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore

Eli Cohen

author
#0 lore raw

PATCH 1/1 libmlx4: fix possible inline size

The current driver checks required inline size by making sure it does not exceed 1024. This is wrong since the whole WQE is limited to 1008 bytes. Moreover, a more careful claculation is required to avoid cases where the application requests inline support in a certain size that when used later could cause connections to stall due to bad WQEs. This patch takes into account the size of the WQE, the segements used to create a WQE and the overhead incured by the inline segments themselves.

---
 src/verbs.c |   51 ++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 46 insertions(+), 5 deletions(-)
src/verbs.c +46 -5
index 1ac1362..69f5c63 100644
@@ -384,6 +384,51 @@ int mlx4_destroy_srq(struct ibv_srq *srq)
 	return 0;
 }
 
+static int verify_sizes(struct ibv_qp_init_attr *attr)
+{
+	int size;
+	int nsegs;
+
+	if (attr->cap.max_send_wr     > 65536 ||
+	    attr->cap.max_recv_wr     > 65536 ||
+	    attr->cap.max_send_sge    > 64    ||
+	    attr->cap.max_recv_sge    > 64)
+		return -1;
+
+	/*
+	 * basic numbers needed to understand the calculation
+	 * 1008 is max size of a WQE.
+	 * 64 is a cache line
+	 * 4 bytes for inline header
+	 */
+	if (attr->cap.max_inline_data) {
+		switch (attr->qp_type) {
+		case IBV_QPT_UD:
+			size = 1008 - sizeof(struct mlx4_wqe_ctrl_seg) -
+				sizeof(struct mlx4_wqe_datagram_seg);
+			nsegs = (attr->cap.max_inline_data + 59) / 60;
+			break;
+
+		case IBV_QPT_RC:
+		case IBV_QPT_UC:
+		case IBV_QPT_XRC:
+			size = 1008 - sizeof(struct mlx4_wqe_ctrl_seg) -
+				sizeof(struct mlx4_wqe_raddr_seg) - 4;
+			nsegs = (attr->cap.max_inline_data - 28 + 59) / 60;
+			break;
+
+		default:
+			return 0;
+		}
+
+		size -= nsegs * 4;
+		if (attr->cap.max_inline_data > size)
+			return -1;
+	}
+
+	return 0;
+}
+
 struct ibv_qp *mlx4_create_qp(struct ibv_pd *pd, struct ibv_qp_init_attr *attr)
 {
 	struct mlx4_create_qp     cmd;
@@ -392,11 +437,7 @@ struct ibv_qp *mlx4_create_qp(struct ibv_pd *pd, struct ibv_qp_init_attr *attr)
 	int			  ret;
 
 	/* Sanity check QP size before proceeding */
-	if (attr->cap.max_send_wr     > 65536 ||
-	    attr->cap.max_recv_wr     > 65536 ||
-	    attr->cap.max_send_sge    > 64    ||
-	    attr->cap.max_recv_sge    > 64    ||
-	    attr->cap.max_inline_data > 1024)
+	if (verify_sizes(attr))
 		return NULL;
 
 	qp = malloc(sizeof *qp);
Signature · 6 lines
1.7.2.2

--
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