[ofa-general] [PATCH] libmlx4: Re-calculate number of inline segments
Vincent Rizza
vinnie at sgi.com
Sun Oct 19 21:16:40 PDT 2008
From: Brett Grandbois <brettg at sgi.com>
Supplying an ibv_qp_cap.max_inline_data value of 460 for mlx4_create_qp
was getting back ENOMEM when the max should have been 928. Tracked the bug
to the inline segment calculation. Here's the fix.
Signed-off-by: Vincent Rizza <vinnie at sgi.com>
Signed-off-by: Brett Grandbois <brettg at sgi.com>
Signed-off-by: Greg Banks <gnb at sgi.com>
Signed-off-by: Max Matveev <makc at sgi.com>
Signed-off-by: Ken Sandars <ksandars at sgi.com>
---
src/qp.c | 51 ++++++++++++++++++++++++++++++++++++++++-----------
1 files changed, 40 insertions(+), 11 deletions(-)
diff --git a/src/qp.c b/src/qp.c
index bb98c09..759ef51 100644
--- a/src/qp.c
+++ b/src/qp.c
@@ -497,6 +497,13 @@ out:
static int num_inline_segs(int data, enum ibv_qp_type type)
{
+ int initial_seg;
+ int num_segs = 0;
+
+ /* ask for nothing, get nothing */
+ if (!data)
+ goto out;
+
/*
* Inline data segments are not allowed to cross 64 byte
* boundaries. For UD QPs, the data segments always start
@@ -505,18 +512,40 @@ static int num_inline_segs(int data, enum ibv_qp_type type)
* control segment and possibly a 16 byte remote address
* segment, so in the worst case there will be only 32 bytes
* available for the first data segment.
+ * So we need to do a little overhead processing only in the
+ * case of a non-UD QP.
*/
- if (type == IBV_QPT_UD)
- data += (sizeof (struct mlx4_wqe_ctrl_seg) +
- sizeof (struct mlx4_wqe_datagram_seg)) %
- MLX4_INLINE_ALIGN;
- else
- data += (sizeof (struct mlx4_wqe_ctrl_seg) +
- sizeof (struct mlx4_wqe_raddr_seg)) %
- MLX4_INLINE_ALIGN;
+ if (type != IBV_QPT_UD) {
+
+ initial_seg = MLX4_INLINE_ALIGN -
+ (sizeof (struct mlx4_wqe_ctrl_seg) +
+ sizeof (struct mlx4_wqe_raddr_seg) +
+ sizeof (struct mlx4_wqe_inline_seg));
+
+ num_segs = 1;
+ /*
+ * no point continuing if everything fits in the
+ * initial segment
+ */
+ if (data <= initial_seg)
+ goto out;
- return (data + MLX4_INLINE_ALIGN - sizeof (struct mlx4_wqe_inline_seg) - 1) /
- (MLX4_INLINE_ALIGN - sizeof (struct mlx4_wqe_inline_seg));
+ /*
+ * If there's room in the initial segment, make sure we
+ * account for it before doing the full segment calcs
+ */
+ data -= initial_seg;
+ }
+
+ /* at this point we are just interested in how many segments are needed */
+ num_segs += data / (MLX4_INLINE_ALIGN - sizeof (struct mlx4_wqe_inline_seg));
+
+ /* account for any leftovers */
+ if (data % (MLX4_INLINE_ALIGN - sizeof (struct mlx4_wqe_inline_seg)))
+ num_segs++;
+
+out:
+ return num_segs;
}
void mlx4_calc_sq_wqe_size(struct ibv_qp_cap *cap, enum ibv_qp_type type,
More information about the general
mailing list