提交 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 { ...@@ -58,7 +58,7 @@ struct hisi_acc_sgl_pool {
struct hisi_acc_sgl_pool *hisi_acc_create_sgl_pool(struct device *dev, struct hisi_acc_sgl_pool *hisi_acc_create_sgl_pool(struct device *dev,
u32 count, u32 sge_nr) 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 hisi_acc_sgl_pool *pool;
struct mem_block *block; struct mem_block *block;
u32 i, j; u32 i, j;
...@@ -70,10 +70,11 @@ struct hisi_acc_sgl_pool *hisi_acc_create_sgl_pool(struct device *dev, ...@@ -70,10 +70,11 @@ struct hisi_acc_sgl_pool *hisi_acc_create_sgl_pool(struct device *dev,
sizeof(struct hisi_acc_hw_sgl); sizeof(struct hisi_acc_hw_sgl);
block_size = PAGE_SIZE * (1 << (MAX_ORDER - 1)); block_size = PAGE_SIZE * (1 << (MAX_ORDER - 1));
sgl_num_per_block = block_size / sgl_size; sgl_num_per_block = block_size / sgl_size;
block_num = count / sgl_num_per_block + block_num = count / sgl_num_per_block;
(count % sgl_num_per_block ? 1 : 0); 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); return ERR_PTR(-EINVAL);
pool = kzalloc(sizeof(*pool), GFP_KERNEL); pool = kzalloc(sizeof(*pool), GFP_KERNEL);
...@@ -85,28 +86,38 @@ struct hisi_acc_sgl_pool *hisi_acc_create_sgl_pool(struct device *dev, ...@@ -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_alloc_coherent(dev, block_size,
&block[i].sgl_dma, &block[i].sgl_dma,
GFP_KERNEL); GFP_KERNEL);
if (!block[i].sgl) { if (!block[i].sgl)
for (j = 0; j < i; j++) { goto err_free_mem;
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);
}
block[i].size = block_size; 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->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->count = count;
pool->sgl_size = sgl_size; pool->sgl_size = sgl_size;
pool->sge_nr = sge_nr; pool->sge_nr = sge_nr;
return pool; 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); 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.
先完成此消息的编辑!
想要评论请 注册