RDMA/hns: Fix bug that caused srq creation to fail
authorLijun Ou <oulijun@huawei.com>
Sun, 7 Apr 2019 05:23:38 +0000 (13:23 +0800)
committerJason Gunthorpe <jgg@mellanox.com>
Mon, 8 Apr 2019 16:27:58 +0000 (13:27 -0300)
Due to the incorrect use of the seg and obj information, the position of
the mtt is calculated incorrectly, and the free space of the page is not
enough to store the entire mtt, resulting in access to the next page. This
patch fixes this problem.

 Unable to handle kernel paging request at virtual address ffff00006e3cd000
 ...
 Call trace:
  hns_roce_write_mtt+0x154/0x2f0 [hns_roce]
  hns_roce_buf_write_mtt+0xa8/0xd8 [hns_roce]
  hns_roce_create_srq+0x74c/0x808 [hns_roce]
  ib_create_srq+0x28/0xc8

Fixes: 0203b14c4f32 ("RDMA/hns: Unify the calculation for hem index in hip08")
Signed-off-by: chenglang <chenglang@huawei.com>
Signed-off-by: Lijun Ou <oulijun@huawei.com>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
drivers/infiniband/hw/hns/hns_roce_hem.c
drivers/infiniband/hw/hns/hns_roce_mr.c

index f1fec56f3ff49047d7ade725d13b43d3dba8bbb6..8e29dbb5b5fbc3bd883384915e76155201572848 100644 (file)
@@ -792,6 +792,8 @@ void *hns_roce_table_find(struct hns_roce_dev *hr_dev,
                idx_offset = (obj & (table->num_obj - 1)) % obj_per_chunk;
                dma_offset = offset = idx_offset * table->obj_size;
        } else {
+               u32 seg_size = 64; /* 8 bytes per BA and 8 BA per segment */
+
                hns_roce_calc_hem_mhop(hr_dev, table, &mhop_obj, &mhop);
                /* mtt mhop */
                i = mhop.l0_idx;
@@ -803,8 +805,8 @@ void *hns_roce_table_find(struct hns_roce_dev *hr_dev,
                        hem_idx = i;
 
                hem = table->hem[hem_idx];
-               dma_offset = offset = (obj & (table->num_obj - 1)) *
-                                      table->obj_size % mhop.bt_chunk_size;
+               dma_offset = offset = (obj & (table->num_obj - 1)) * seg_size %
+                                      mhop.bt_chunk_size;
                if (mhop.hop_num == 2)
                        dma_offset = offset = 0;
        }
index b09f1cde2ff54ca9522a60d21ba3e82967938574..08be0e4eabcd764e9af0a666cec02fad1e921f76 100644 (file)
@@ -746,7 +746,6 @@ static int hns_roce_write_mtt_chunk(struct hns_roce_dev *hr_dev,
        struct hns_roce_hem_table *table;
        dma_addr_t dma_handle;
        __le64 *mtts;
-       u32 s = start_index * sizeof(u64);
        u32 bt_page_size;
        u32 i;
 
@@ -780,7 +779,8 @@ static int hns_roce_write_mtt_chunk(struct hns_roce_dev *hr_dev,
                return -EINVAL;
 
        mtts = hns_roce_table_find(hr_dev, table,
-                               mtt->first_seg + s / hr_dev->caps.mtt_entry_sz,
+                               mtt->first_seg +
+                               start_index / HNS_ROCE_MTT_ENTRY_PER_SEG,
                                &dma_handle);
        if (!mtts)
                return -ENOMEM;