mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-05 00:20:32 +00:00
RDMA/hns: Use ib_umem_num_dma_blocks() instead of opencoding
mtr_umem_page_count() does the same thing, replace it with the core code. Also, ib_umem_find_best_pgsz() should always be called to check that the umem meets the page_size requirement. If there is a limited set of page_sizes that work it the pgsz_bitmap should be set to that set. 0 is a failure and the umem cannot be used. Lightly tidy the control flow to implement this flow properly. Link: https://lore.kernel.org/r/12-v2-270386b7e60b+28f4-umem_1_jgg@nvidia.com Acked-by: Weihang Li <liweihang@huawei.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
This commit is contained in:
parent
84e71b4d9b
commit
cf9ce3c8ab
1 changed files with 19 additions and 30 deletions
|
@ -707,19 +707,6 @@ static inline size_t mtr_bufs_size(struct hns_roce_buf_attr *attr)
|
|||
return size;
|
||||
}
|
||||
|
||||
static inline int mtr_umem_page_count(struct ib_umem *umem,
|
||||
unsigned int page_shift)
|
||||
{
|
||||
int count = ib_umem_page_count(umem);
|
||||
|
||||
if (page_shift >= PAGE_SHIFT)
|
||||
count >>= page_shift - PAGE_SHIFT;
|
||||
else
|
||||
count <<= PAGE_SHIFT - page_shift;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static inline size_t mtr_kmem_direct_size(bool is_direct, size_t alloc_size,
|
||||
unsigned int page_shift)
|
||||
{
|
||||
|
@ -767,12 +754,10 @@ static int mtr_alloc_bufs(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr,
|
|||
struct ib_udata *udata, unsigned long user_addr)
|
||||
{
|
||||
struct ib_device *ibdev = &hr_dev->ib_dev;
|
||||
unsigned int max_pg_shift = buf_attr->page_shift;
|
||||
unsigned int best_pg_shift = 0;
|
||||
unsigned int best_pg_shift;
|
||||
int all_pg_count = 0;
|
||||
size_t direct_size;
|
||||
size_t total_size;
|
||||
unsigned long tmp;
|
||||
int ret;
|
||||
|
||||
total_size = mtr_bufs_size(buf_attr);
|
||||
|
@ -782,6 +767,9 @@ static int mtr_alloc_bufs(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr,
|
|||
}
|
||||
|
||||
if (udata) {
|
||||
unsigned long pgsz_bitmap;
|
||||
unsigned long page_size;
|
||||
|
||||
mtr->kmem = NULL;
|
||||
mtr->umem = ib_umem_get(ibdev, user_addr, total_size,
|
||||
buf_attr->user_access);
|
||||
|
@ -790,15 +778,17 @@ static int mtr_alloc_bufs(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr,
|
|||
PTR_ERR(mtr->umem));
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (buf_attr->fixed_page) {
|
||||
best_pg_shift = max_pg_shift;
|
||||
} else {
|
||||
tmp = GENMASK(max_pg_shift, 0);
|
||||
ret = ib_umem_find_best_pgsz(mtr->umem, tmp, user_addr);
|
||||
best_pg_shift = (ret <= PAGE_SIZE) ?
|
||||
PAGE_SHIFT : ilog2(ret);
|
||||
}
|
||||
all_pg_count = mtr_umem_page_count(mtr->umem, best_pg_shift);
|
||||
if (buf_attr->fixed_page)
|
||||
pgsz_bitmap = 1 << buf_attr->page_shift;
|
||||
else
|
||||
pgsz_bitmap = GENMASK(buf_attr->page_shift, PAGE_SHIFT);
|
||||
|
||||
page_size = ib_umem_find_best_pgsz(mtr->umem, pgsz_bitmap,
|
||||
user_addr);
|
||||
if (!page_size)
|
||||
return -EINVAL;
|
||||
best_pg_shift = order_base_2(page_size);
|
||||
all_pg_count = ib_umem_num_dma_blocks(mtr->umem, page_size);
|
||||
ret = 0;
|
||||
} else {
|
||||
mtr->umem = NULL;
|
||||
|
@ -808,16 +798,15 @@ static int mtr_alloc_bufs(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr,
|
|||
return -ENOMEM;
|
||||
}
|
||||
direct_size = mtr_kmem_direct_size(is_direct, total_size,
|
||||
max_pg_shift);
|
||||
buf_attr->page_shift);
|
||||
ret = hns_roce_buf_alloc(hr_dev, total_size, direct_size,
|
||||
mtr->kmem, max_pg_shift);
|
||||
mtr->kmem, buf_attr->page_shift);
|
||||
if (ret) {
|
||||
ibdev_err(ibdev, "Failed to alloc kmem, ret %d\n", ret);
|
||||
goto err_alloc_mem;
|
||||
} else {
|
||||
best_pg_shift = max_pg_shift;
|
||||
all_pg_count = mtr->kmem->npages;
|
||||
}
|
||||
best_pg_shift = buf_attr->page_shift;
|
||||
all_pg_count = mtr->kmem->npages;
|
||||
}
|
||||
|
||||
/* must bigger than minimum hardware page shift */
|
||||
|
|
Loading…
Reference in a new issue