RDMA/hns: Limit the size of extend sge of sq
authorLijun Ou <oulijun@huawei.com>
Sun, 30 Sep 2018 09:00:31 +0000 (17:00 +0800)
committerJason Gunthorpe <jgg@mellanox.com>
Wed, 3 Oct 2018 22:21:17 +0000 (16:21 -0600)
The hip08 split two hardware version. The version id are 0x20 and 0x21
according to the PCI revison. The max size of extend sge of sq is limited
to 2M for 0x20 version and 8M for 0x21 version. It may be exceeded to 2M
according to the algorithm that compute the product of wqe count and
extend sge number of every wqe. But the product always less than 8M.

Signed-off-by: Lijun Ou <oulijun@huawei.com>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
drivers/infiniband/hw/hns/hns_roce_device.h
drivers/infiniband/hw/hns/hns_roce_hw_v2.c
drivers/infiniband/hw/hns/hns_roce_hw_v2.h
drivers/infiniband/hw/hns/hns_roce_qp.c

index 34f8e90c8044c33db24001ee2977d3bf7f49fd12..b06d3e432f3793d235d82ab9ee3b4015f1ab4607 100644 (file)
@@ -670,6 +670,7 @@ struct hns_roce_caps {
        u32             max_sq_sg;      /* 2 */
        u32             max_sq_inline;  /* 32 */
        u32             max_rq_sg;      /* 2 */
+       u32             max_extend_sg;
        int             num_qps;        /* 256k */
        int             reserved_qps;
        u32             max_wqes;       /* 16k */
index 20cc866200639b53bd1e8e7320d185849228d652..d563d29555977343f6ac98db4335be146776518a 100644 (file)
@@ -1191,6 +1191,7 @@ static int hns_roce_v2_profile(struct hns_roce_dev *hr_dev)
        caps->num_cqs           = HNS_ROCE_V2_MAX_CQ_NUM;
        caps->max_cqes          = HNS_ROCE_V2_MAX_CQE_NUM;
        caps->max_sq_sg         = HNS_ROCE_V2_MAX_SQ_SGE_NUM;
+       caps->max_extend_sg     = HNS_ROCE_V2_MAX_EXTEND_SGE_NUM;
        caps->max_rq_sg         = HNS_ROCE_V2_MAX_RQ_SGE_NUM;
        caps->max_sq_inline     = HNS_ROCE_V2_MAX_SQ_INLINE;
        caps->num_uars          = HNS_ROCE_V2_UAR_NUM;
index 18775813cf13bcf4935ca48c81f4c93782fec2b5..b921ca6358e09cc1e7ac6663f78c1f54290d4b06 100644 (file)
@@ -50,6 +50,7 @@
 #define HNS_ROCE_V2_MAX_CQE_NUM                        0x10000
 #define HNS_ROCE_V2_MAX_RQ_SGE_NUM             0x100
 #define HNS_ROCE_V2_MAX_SQ_SGE_NUM             0xff
+#define HNS_ROCE_V2_MAX_EXTEND_SGE_NUM         0x200000
 #define HNS_ROCE_V2_MAX_SQ_INLINE              0x20
 #define HNS_ROCE_V2_UAR_NUM                    256
 #define HNS_ROCE_V2_PHY_UAR_NUM                        1
index 0e0c79609b0c9fc438b69efc3d9b82d1e3917d7b..2805ab2ab2c597dec3f5cb03b181b34f11f7861e 100644 (file)
@@ -31,6 +31,7 @@
  * SOFTWARE.
  */
 
+#include <linux/pci.h>
 #include <linux/platform_device.h>
 #include <rdma/ib_addr.h>
 #include <rdma/ib_umem.h>
@@ -372,6 +373,16 @@ static int hns_roce_set_user_sq_size(struct hns_roce_dev *hr_dev,
        if (hr_qp->sq.max_gs > 2)
                hr_qp->sge.sge_cnt = roundup_pow_of_two(hr_qp->sq.wqe_cnt *
                                                        (hr_qp->sq.max_gs - 2));
+
+       if ((hr_qp->sq.max_gs > 2) && (hr_dev->pci_dev->revision == 0x20)) {
+               if (hr_qp->sge.sge_cnt > hr_dev->caps.max_extend_sg) {
+                       dev_err(hr_dev->dev,
+                               "The extended sge cnt error! sge_cnt=%d\n",
+                               hr_qp->sge.sge_cnt);
+                       return -EINVAL;
+               }
+       }
+
        hr_qp->sge.sge_shift = 4;
 
        /* Get buf size, SQ and RQ  are aligned to page_szie */
@@ -465,6 +476,14 @@ static int hns_roce_set_kernel_sq_size(struct hns_roce_dev *hr_dev,
                hr_qp->sge.sge_shift = 4;
        }
 
+       if ((hr_qp->sq.max_gs > 2) && hr_dev->pci_dev->revision == 0x20) {
+               if (hr_qp->sge.sge_cnt > hr_dev->caps.max_extend_sg) {
+                       dev_err(dev, "The extended sge cnt error! sge_cnt=%d\n",
+                               hr_qp->sge.sge_cnt);
+                       return -EINVAL;
+               }
+       }
+
        /* Get buf size, SQ and RQ are aligned to PAGE_SIZE */
        page_size = 1 << (hr_dev->caps.mtt_buf_pg_sz + PAGE_SHIFT);
        hr_qp->sq.offset = 0;