From patchwork Wed Sep 29 10:08:45 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eli Cohen X-Patchwork-Id: 216822 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id o8TA8vR9011202 for ; Wed, 29 Sep 2010 10:08:57 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751437Ab0I2KIz (ORCPT ); Wed, 29 Sep 2010 06:08:55 -0400 Received: from mail-fx0-f46.google.com ([209.85.161.46]:35181 "EHLO mail-fx0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750951Ab0I2KIz (ORCPT ); Wed, 29 Sep 2010 06:08:55 -0400 Received: by fxm14 with SMTP id 14so325107fxm.19 for ; Wed, 29 Sep 2010 03:08:50 -0700 (PDT) Received: by 10.223.105.139 with SMTP id t11mr1379753fao.63.1285754930851; Wed, 29 Sep 2010 03:08:50 -0700 (PDT) Received: from localhost ([82.166.227.17]) by mx.google.com with ESMTPS id t6sm3661933faa.3.2010.09.29.03.08.40 (version=TLSv1/SSLv3 cipher=RC4-MD5); Wed, 29 Sep 2010 03:08:46 -0700 (PDT) Date: Wed, 29 Sep 2010 12:08:45 +0200 From: Eli Cohen To: Roland Dreier Cc: RDMA list Subject: [PATCH v2] libmlx4: fix possible inline size Message-ID: <20100929100845.GA4960@mtldesk30> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.20 (2009-06-14) Sender: linux-rdma-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-rdma@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Wed, 29 Sep 2010 10:08:57 +0000 (UTC) diff --git a/src/mlx4.h b/src/mlx4.h index 4445998..5223697 100644 --- a/src/mlx4.h +++ b/src/mlx4.h @@ -130,6 +130,10 @@ enum { MLX4_CQE_OPCODE_RESIZE = 0x16, }; +enum { + MLX4_MAX_WQE_SIZE = 1008 +}; + struct mlx4_device { struct ibv_device ibv_dev; int page_size; @@ -349,6 +353,7 @@ int mlx4_post_recv(struct ibv_qp *ibqp, struct ibv_recv_wr *wr, struct ibv_recv_wr **bad_wr); void mlx4_calc_sq_wqe_size(struct ibv_qp_cap *cap, enum ibv_qp_type type, struct mlx4_qp *qp); +int num_inline_segs(int data, enum ibv_qp_type type); int mlx4_alloc_qp_buf(struct ibv_pd *pd, struct ibv_qp_cap *cap, enum ibv_qp_type type, struct mlx4_qp *qp); void mlx4_set_sq_sizes(struct mlx4_qp *qp, struct ibv_qp_cap *cap, diff --git a/src/qp.c b/src/qp.c index d194ae3..6ceb3ef 100644 --- a/src/qp.c +++ b/src/qp.c @@ -495,7 +495,7 @@ out: return ret; } -static int num_inline_segs(int data, enum ibv_qp_type type) +int num_inline_segs(int data, enum ibv_qp_type type) { /* * Inline data segments are not allowed to cross 64 byte diff --git a/src/verbs.c b/src/verbs.c index 1ac1362..5ab20e5 100644 --- a/src/verbs.c +++ b/src/verbs.c @@ -384,6 +384,49 @@ 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) { + nsegs = num_inline_segs(attr->cap.max_inline_data, attr->qp_type); + size = MLX4_MAX_WQE_SIZE - nsegs * sizeof(struct mlx4_wqe_inline_seg); + switch (attr->qp_type) { + case IBV_QPT_UD: + size -= (sizeof(struct mlx4_wqe_ctrl_seg) + + sizeof(struct mlx4_wqe_datagram_seg)); + break; + + case IBV_QPT_RC: + case IBV_QPT_UC: + size -= (sizeof(struct mlx4_wqe_ctrl_seg) + + sizeof(struct mlx4_wqe_raddr_seg)); + break; + + default: + return 0; + } + + 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 +435,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);