提交 55d763a5 编写于 作者: Z Zhou Wang 提交者: Xie XiuQi

sgl:fix large memory allocation problem in sgl

driver inclusion
category: bugfix
bugzilla: NA
CVE: NA

Currently sgl memory is allocated as block which size is
page_size *(1 << (max_order - 1)),which will be very large
when page_size and max_order are big.

This patches fix this problem by allocating sgl memory as
needed when needed memory is less than one block.

Feature or Bugfix:Bugfix
Signed-off-by: NZhou Wang <wangzhou1@hisilicon.com>
Signed-off-by: Nshenyang39 <shenyang39@huawei.com>
Reviewed-by: NLing Mingqiang <lingmingqiang@huawei.com>
Reviewed-by: NYang Yingliang <yangyingliang@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 a517b226
......@@ -58,7 +58,7 @@ struct hisi_acc_sgl_pool {
struct hisi_acc_sgl_pool *hisi_acc_create_sgl_pool(struct device *dev,
u32 count, u32 sge_nr)
{
u32 sgl_size, block_size, sgl_num_per_block, block_num;
u32 sgl_size, block_size, sgl_num_per_block, block_num, remain_sgl = 0;
struct hisi_acc_sgl_pool *pool;
struct mem_block *block;
u32 i, j;
......@@ -70,10 +70,11 @@ struct hisi_acc_sgl_pool *hisi_acc_create_sgl_pool(struct device *dev,
sizeof(struct hisi_acc_hw_sgl);
block_size = PAGE_SIZE * (1 << (MAX_ORDER - 1));
sgl_num_per_block = block_size / sgl_size;
block_num = count / sgl_num_per_block +
(count % sgl_num_per_block ? 1 : 0);
block_num = count / sgl_num_per_block;
remain_sgl = count % sgl_num_per_block;
if (block_num > HISI_ACC_MEM_BLOCK_NR)
if ((!remain_sgl && block_num > HISI_ACC_MEM_BLOCK_NR) ||
(remain_sgl > 0 && block_num > HISI_ACC_MEM_BLOCK_NR - 1))
return ERR_PTR(-EINVAL);
pool = kzalloc(sizeof(*pool), GFP_KERNEL);
......@@ -85,28 +86,38 @@ struct hisi_acc_sgl_pool *hisi_acc_create_sgl_pool(struct device *dev,
block[i].sgl = dma_alloc_coherent(dev, block_size,
&block[i].sgl_dma,
GFP_KERNEL);
if (!block[i].sgl) {
for (j = 0; j < i; j++) {
dma_free_coherent(dev, block_size,
block[j].sgl,
block[j].sgl_dma);
memset(block + j, 0, sizeof(*block));
}
kfree(pool);
return ERR_PTR(-ENOMEM);
}
if (!block[i].sgl)
goto err_free_mem;
block[i].size = block_size;
}
if (remain_sgl > 0) {
block[i].sgl = dma_alloc_coherent(dev, remain_sgl * sgl_size,
&block[i].sgl_dma,
GFP_KERNEL);
if (!block[i].sgl)
goto err_free_mem;
block[i].size = remain_sgl * sgl_size;
}
pool->sgl_num_per_block = sgl_num_per_block;
pool->block_num = block_num;
pool->block_num = remain_sgl ? block_num + 1 : block_num;
pool->count = count;
pool->sgl_size = sgl_size;
pool->sge_nr = sge_nr;
return pool;
err_free_mem:
for (j = 0; j < i; j++) {
dma_free_coherent(dev, block_size, block[j].sgl,
block[j].sgl_dma);
memset(block + j, 0, sizeof(*block));
}
kfree(pool);
return ERR_PTR(-ENOMEM);
}
EXPORT_SYMBOL_GPL(hisi_acc_create_sgl_pool);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册