aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/hns/hns_roce_alloc.c
diff options
context:
space:
mode:
authorXi Wang <wangxi11@huawei.com>2021-05-21 17:29:51 +0800
committerJason Gunthorpe <jgg@nvidia.com>2021-05-28 20:13:57 -0300
commit7b0006db6800da4c05883584befa46502d85dede (patch)
treedf6f449dcefdfe4504d35b8e5702823dcb61a11c /drivers/infiniband/hw/hns/hns_roce_alloc.c
parentRDMA/mlx5: Take qp type from mlx5_ib_qp (diff)
downloadlinux-dev-7b0006db6800da4c05883584befa46502d85dede.tar.xz
linux-dev-7b0006db6800da4c05883584befa46502d85dede.zip
RDMA/hns: Optimize the base address table config for MTR
The base address table is allocated by dma allocator, and the size is always aligned to PAGE_SIZE. If a fixed size is used to allocate the table, the number of base address entries stored in the table will be smaller than that can actually stored. Link: https://lore.kernel.org/r/1621589395-2435-2-git-send-email-liweihang@huawei.com Signed-off-by: Xi Wang <wangxi11@huawei.com> Signed-off-by: Weihang Li <liweihang@huawei.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Diffstat (limited to 'drivers/infiniband/hw/hns/hns_roce_alloc.c')
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_alloc.c51
1 files changed, 21 insertions, 30 deletions
diff --git a/drivers/infiniband/hw/hns/hns_roce_alloc.c b/drivers/infiniband/hw/hns/hns_roce_alloc.c
index 5d389ed55376..51374b688ad7 100644
--- a/drivers/infiniband/hw/hns/hns_roce_alloc.c
+++ b/drivers/infiniband/hw/hns/hns_roce_alloc.c
@@ -208,10 +208,10 @@ struct hns_roce_buf *hns_roce_buf_alloc(struct hns_roce_dev *hr_dev, u32 size,
/* Calc the trunk size and num by required size and page_shift */
if (flags & HNS_ROCE_BUF_DIRECT) {
- buf->trunk_shift = ilog2(ALIGN(size, PAGE_SIZE));
+ buf->trunk_shift = order_base_2(ALIGN(size, PAGE_SIZE));
ntrunk = 1;
} else {
- buf->trunk_shift = ilog2(ALIGN(page_size, PAGE_SIZE));
+ buf->trunk_shift = order_base_2(ALIGN(page_size, PAGE_SIZE));
ntrunk = DIV_ROUND_UP(size, 1 << buf->trunk_shift);
}
@@ -252,50 +252,41 @@ struct hns_roce_buf *hns_roce_buf_alloc(struct hns_roce_dev *hr_dev, u32 size,
}
int hns_roce_get_kmem_bufs(struct hns_roce_dev *hr_dev, dma_addr_t *bufs,
- int buf_cnt, int start, struct hns_roce_buf *buf)
+ int buf_cnt, struct hns_roce_buf *buf,
+ unsigned int page_shift)
{
- int i, end;
- int total;
-
- end = start + buf_cnt;
- if (end > buf->npages) {
- dev_err(hr_dev->dev,
- "failed to check kmem bufs, end %d + %d total %u!\n",
- start, buf_cnt, buf->npages);
+ unsigned int offset, max_size;
+ int total = 0;
+ int i;
+
+ if (page_shift > buf->trunk_shift) {
+ dev_err(hr_dev->dev, "failed to check kmem buf shift %u > %u\n",
+ page_shift, buf->trunk_shift);
return -EINVAL;
}
- total = 0;
- for (i = start; i < end; i++)
- bufs[total++] = hns_roce_buf_page(buf, i);
+ offset = 0;
+ max_size = buf->ntrunks << buf->trunk_shift;
+ for (i = 0; i < buf_cnt && offset < max_size; i++) {
+ bufs[total++] = hns_roce_buf_dma_addr(buf, offset);
+ offset += (1 << page_shift);
+ }
return total;
}
int hns_roce_get_umem_bufs(struct hns_roce_dev *hr_dev, dma_addr_t *bufs,
- int buf_cnt, int start, struct ib_umem *umem,
+ int buf_cnt, struct ib_umem *umem,
unsigned int page_shift)
{
struct ib_block_iter biter;
int total = 0;
- int idx = 0;
- u64 addr;
-
- if (page_shift < HNS_HW_PAGE_SHIFT) {
- dev_err(hr_dev->dev, "failed to check umem page shift %u!\n",
- page_shift);
- return -EINVAL;
- }
/* convert system page cnt to hw page cnt */
rdma_umem_for_each_dma_block(umem, &biter, 1 << page_shift) {
- addr = rdma_block_iter_dma_address(&biter);
- if (idx >= start) {
- bufs[total++] = addr;
- if (total >= buf_cnt)
- goto done;
- }
- idx++;
+ bufs[total++] = rdma_block_iter_dma_address(&biter);
+ if (total >= buf_cnt)
+ goto done;
}
done: