mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 04:10:18 +09:00
media: codec_mm: fixed some bugs
PD#154520: media: fixed some bugs 1. codec_mm: fixed alloc & free statistics error bug 2. codec_mm: when some buffers have used. a big size alloc failed, because of faragmented. add retry for alloc small size. and del some dump infos 3. codec_mm: fixed codec_mm fast play bug 4. don't used system's cma pool Change-Id: I047f1bed75729cf6fe14040243d82906832c9497 Signed-off-by: Zhi Zhou <zhi.zhou@amlogic.com>
This commit is contained in:
@@ -49,6 +49,7 @@
|
|||||||
#define CONFIG_PREFIX "media"
|
#define CONFIG_PREFIX "media"
|
||||||
|
|
||||||
|
|
||||||
|
#define MM_ALIGN_DOWN(addr, size) ((addr) & (~((size) - 1)))
|
||||||
|
|
||||||
#define RES_IS_MAPED
|
#define RES_IS_MAPED
|
||||||
#define DEFAULT_TVP_SIZE_FOR_4K (256 * SZ_1M)
|
#define DEFAULT_TVP_SIZE_FOR_4K (256 * SZ_1M)
|
||||||
@@ -486,40 +487,50 @@ static int codec_mm_alloc_in(
|
|||||||
static void codec_mm_free_in(struct codec_mm_mgt_s *mgt,
|
static void codec_mm_free_in(struct codec_mm_mgt_s *mgt,
|
||||||
struct codec_mm_s *mem)
|
struct codec_mm_s *mem)
|
||||||
{
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
if (mem->from_flags == AMPORTS_MEM_FLAGS_FROM_GET_FROM_CMA) {
|
||||||
|
dma_release_from_contiguous(mgt->dev,
|
||||||
|
mem->mem_handle, mem->page_count);
|
||||||
|
} else if (mem->from_flags ==
|
||||||
|
AMPORTS_MEM_FLAGS_FROM_GET_FROM_REVERSED) {
|
||||||
|
gen_pool_free(mgt->res_pool,
|
||||||
|
(unsigned long)mem->mem_handle, mem->buffer_size);
|
||||||
|
} else if (mem->from_flags == AMPORTS_MEM_FLAGS_FROM_GET_FROM_TVP) {
|
||||||
|
codec_mm_extpool_free(
|
||||||
|
(struct gen_pool *)mem->from_ext,
|
||||||
|
mem->mem_handle,
|
||||||
|
mem->buffer_size);
|
||||||
|
} else if (mem->from_flags == AMPORTS_MEM_FLAGS_FROM_GET_FROM_PAGES) {
|
||||||
|
free_pages((unsigned long)mem->mem_handle,
|
||||||
|
get_order(mem->buffer_size));
|
||||||
|
} else if (mem->from_flags == AMPORTS_MEM_FLAGS_FROM_GET_FROM_CMA_RES) {
|
||||||
|
codec_mm_extpool_free(
|
||||||
|
(struct gen_pool *)mem->from_ext,
|
||||||
|
mem->mem_handle,
|
||||||
|
mem->buffer_size);
|
||||||
|
}
|
||||||
|
spin_lock_irqsave(&mgt->lock, flags);
|
||||||
if (!(mem->flags & CODEC_MM_FLAGS_FOR_LOCAL_MGR))
|
if (!(mem->flags & CODEC_MM_FLAGS_FOR_LOCAL_MGR))
|
||||||
mgt->total_alloced_size -= mem->buffer_size;
|
mgt->total_alloced_size -= mem->buffer_size;
|
||||||
if (mem->flags & CODEC_MM_FLAGS_FOR_SCATTER) {
|
if (mem->flags & CODEC_MM_FLAGS_FOR_SCATTER) {
|
||||||
mgt->alloced_for_sc_size -= mem->buffer_size;
|
mgt->alloced_for_sc_size -= mem->buffer_size;
|
||||||
mgt->alloced_for_sc_cnt--;
|
mgt->alloced_for_sc_cnt--;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mem->from_flags == AMPORTS_MEM_FLAGS_FROM_GET_FROM_CMA) {
|
if (mem->from_flags == AMPORTS_MEM_FLAGS_FROM_GET_FROM_CMA) {
|
||||||
dma_release_from_contiguous(mgt->dev,
|
|
||||||
mem->mem_handle, mem->page_count);
|
|
||||||
mgt->alloced_cma_size -= mem->buffer_size;
|
mgt->alloced_cma_size -= mem->buffer_size;
|
||||||
} else if (mem->from_flags ==
|
} else if (mem->from_flags ==
|
||||||
AMPORTS_MEM_FLAGS_FROM_GET_FROM_REVERSED) {
|
AMPORTS_MEM_FLAGS_FROM_GET_FROM_REVERSED) {
|
||||||
gen_pool_free(mgt->res_pool,
|
|
||||||
(unsigned long)mem->mem_handle, mem->buffer_size);
|
|
||||||
mgt->alloced_res_size -= mem->buffer_size;
|
mgt->alloced_res_size -= mem->buffer_size;
|
||||||
} else if (mem->from_flags == AMPORTS_MEM_FLAGS_FROM_GET_FROM_TVP) {
|
} else if (mem->from_flags == AMPORTS_MEM_FLAGS_FROM_GET_FROM_TVP) {
|
||||||
codec_mm_extpool_free(
|
|
||||||
(struct gen_pool *)mem->from_ext,
|
|
||||||
mem->mem_handle,
|
|
||||||
mem->buffer_size);
|
|
||||||
mgt->tvp_pool.alloced_size -= mem->buffer_size;
|
mgt->tvp_pool.alloced_size -= mem->buffer_size;
|
||||||
} else if (mem->from_flags == AMPORTS_MEM_FLAGS_FROM_GET_FROM_PAGES) {
|
} else if (mem->from_flags == AMPORTS_MEM_FLAGS_FROM_GET_FROM_PAGES) {
|
||||||
free_pages((unsigned long)mem->mem_handle,
|
|
||||||
get_order(mem->buffer_size));
|
|
||||||
mgt->alloced_sys_size -= mem->buffer_size;
|
mgt->alloced_sys_size -= mem->buffer_size;
|
||||||
} else if (mem->from_flags == AMPORTS_MEM_FLAGS_FROM_GET_FROM_CMA_RES) {
|
} else if (mem->from_flags == AMPORTS_MEM_FLAGS_FROM_GET_FROM_CMA_RES) {
|
||||||
codec_mm_extpool_free(
|
|
||||||
(struct gen_pool *)mem->from_ext,
|
|
||||||
mem->mem_handle,
|
|
||||||
mem->buffer_size);
|
|
||||||
mgt->cma_res_pool.alloced_size -= mem->buffer_size;
|
mgt->cma_res_pool.alloced_size -= mem->buffer_size;
|
||||||
}
|
}
|
||||||
|
spin_unlock_irqrestore(&mgt->lock, flags);
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct codec_mm_s *codec_mm_alloc(const char *owner, int size,
|
struct codec_mm_s *codec_mm_alloc(const char *owner, int size,
|
||||||
@@ -839,26 +850,35 @@ int codec_mm_extpool_pool_alloc(
|
|||||||
mutex_lock(&tvp_pool->pool_lock);
|
mutex_lock(&tvp_pool->pool_lock);
|
||||||
try_alloced_size = mgt->total_reserved_size - mgt->alloced_res_size;
|
try_alloced_size = mgt->total_reserved_size - mgt->alloced_res_size;
|
||||||
if (try_alloced_size > 0 && for_tvp) {
|
if (try_alloced_size > 0 && for_tvp) {
|
||||||
|
int retry = 0;
|
||||||
try_alloced_size = min_t(int,
|
try_alloced_size = min_t(int,
|
||||||
size - alloced_size, try_alloced_size);
|
size - alloced_size, try_alloced_size);
|
||||||
mem = codec_mm_alloc(TVP_POOL_NAME,
|
try_alloced_size = MM_ALIGN_DOWN(try_alloced_size,
|
||||||
try_alloced_size,
|
RESERVE_MM_ALIGNED_2N);
|
||||||
RESERVE_MM_ALIGNED_2N,
|
do {
|
||||||
CODEC_MM_FLAGS_FOR_LOCAL_MGR |
|
mem = codec_mm_alloc(TVP_POOL_NAME,
|
||||||
CODEC_MM_FLAGS_RESERVED);
|
try_alloced_size,
|
||||||
|
RESERVE_MM_ALIGNED_2N,
|
||||||
|
CODEC_MM_FLAGS_FOR_LOCAL_MGR |
|
||||||
|
CODEC_MM_FLAGS_RESERVED);
|
||||||
|
|
||||||
if (mem) {
|
if (mem) {
|
||||||
ret = codec_mm_init_tvp_pool(
|
ret = codec_mm_init_tvp_pool(
|
||||||
tvp_pool,
|
tvp_pool,
|
||||||
mem);
|
mem);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
codec_mm_release(mem, TVP_POOL_NAME);
|
codec_mm_release(mem, TVP_POOL_NAME);
|
||||||
|
} else {
|
||||||
|
alloced_size += try_alloced_size;
|
||||||
|
tvp_pool->slot_num++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
} else {
|
} else {
|
||||||
alloced_size += try_alloced_size;
|
try_alloced_size = try_alloced_size - 4 * SZ_1M;
|
||||||
tvp_pool->slot_num++;
|
if (try_alloced_size < 16 * SZ_1M)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
} while (retry++ < 10);
|
||||||
}
|
}
|
||||||
if (alloced_size >= size) {
|
if (alloced_size >= size) {
|
||||||
/*alloc finished. */
|
/*alloc finished. */
|
||||||
@@ -868,9 +888,14 @@ int codec_mm_extpool_pool_alloc(
|
|||||||
/*alloced from cma:*/
|
/*alloced from cma:*/
|
||||||
try_alloced_size = mgt->total_cma_size - mgt->alloced_cma_size;
|
try_alloced_size = mgt->total_cma_size - mgt->alloced_cma_size;
|
||||||
if (try_alloced_size > 0) {
|
if (try_alloced_size > 0) {
|
||||||
try_alloced_size = min_t(int, size -
|
int retry = 0;
|
||||||
alloced_size, try_alloced_size);
|
|
||||||
mem = codec_mm_alloc(
|
try_alloced_size = min_t(int,
|
||||||
|
size - alloced_size, try_alloced_size);
|
||||||
|
try_alloced_size = MM_ALIGN_DOWN(try_alloced_size,
|
||||||
|
RESERVE_MM_ALIGNED_2N);
|
||||||
|
do {
|
||||||
|
mem = codec_mm_alloc(
|
||||||
for_tvp ?
|
for_tvp ?
|
||||||
TVP_POOL_NAME :
|
TVP_POOL_NAME :
|
||||||
CMA_RES_POOL_NAME,
|
CMA_RES_POOL_NAME,
|
||||||
@@ -878,18 +903,23 @@ int codec_mm_extpool_pool_alloc(
|
|||||||
RESERVE_MM_ALIGNED_2N,
|
RESERVE_MM_ALIGNED_2N,
|
||||||
CODEC_MM_FLAGS_FOR_LOCAL_MGR |
|
CODEC_MM_FLAGS_FOR_LOCAL_MGR |
|
||||||
CODEC_MM_FLAGS_CMA);
|
CODEC_MM_FLAGS_CMA);
|
||||||
|
if (mem) {
|
||||||
if (mem) {
|
ret = codec_mm_init_tvp_pool(
|
||||||
ret = codec_mm_init_tvp_pool(
|
tvp_pool,
|
||||||
tvp_pool,
|
mem);
|
||||||
mem);
|
if (ret < 0) {
|
||||||
if (ret < 0) {
|
codec_mm_release(mem, TVP_POOL_NAME);
|
||||||
codec_mm_release(mem, TVP_POOL_NAME);
|
} else {
|
||||||
|
alloced_size += try_alloced_size;
|
||||||
|
tvp_pool->slot_num++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
} else {
|
} else {
|
||||||
alloced_size += try_alloced_size;
|
try_alloced_size = try_alloced_size - 4 * SZ_1M;
|
||||||
tvp_pool->slot_num++;
|
if (try_alloced_size < 16 * SZ_1M)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
} while (retry++ < 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
alloced_finished:
|
alloced_finished:
|
||||||
@@ -1048,9 +1078,35 @@ unsigned long dma_get_cma_size_int_byte(struct device *dev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
size = cma_get_size(cma);
|
size = cma_get_size(cma);
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(dma_get_cma_size_int_byte);
|
||||||
|
|
||||||
|
|
||||||
|
static int codec_mm_get_cma_size_int_byte(struct device *dev)
|
||||||
|
{
|
||||||
|
static int static_size = -1;
|
||||||
|
struct cma *cma = NULL;
|
||||||
|
|
||||||
|
if (static_size >= 0)
|
||||||
|
return static_size;
|
||||||
|
if (!dev) {
|
||||||
|
pr_err("CMA: NULL DEV\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cma = dev_get_cma_area(dev);
|
||||||
|
if (!cma) {
|
||||||
|
pr_err("CMA: NO CMA region\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (cma == dev_get_cma_area(NULL))
|
||||||
|
static_size = 0;/*ignore default cma pool*/
|
||||||
|
else
|
||||||
|
static_size = cma_get_size(cma);
|
||||||
|
|
||||||
|
return static_size;
|
||||||
|
}
|
||||||
|
|
||||||
static int dump_mem_infos(void *buf, int size)
|
static int dump_mem_infos(void *buf, int size)
|
||||||
{
|
{
|
||||||
@@ -1103,9 +1159,9 @@ static int dump_mem_infos(void *buf, int size)
|
|||||||
s = snprintf(pbuf, size - tsize,
|
s = snprintf(pbuf, size - tsize,
|
||||||
"\t[%d]CMA size:%d MB:alloced: %d MB,free:%d MB\n",
|
"\t[%d]CMA size:%d MB:alloced: %d MB,free:%d MB\n",
|
||||||
AMPORTS_MEM_FLAGS_FROM_GET_FROM_CMA,
|
AMPORTS_MEM_FLAGS_FROM_GET_FROM_CMA,
|
||||||
(int)(dma_get_cma_size_int_byte(mgt->dev) / SZ_1M),
|
(int)(mgt->total_cma_size / SZ_1M),
|
||||||
(int)(mgt->alloced_cma_size / SZ_1M),
|
(int)(mgt->alloced_cma_size / SZ_1M),
|
||||||
(int)((dma_get_cma_size_int_byte(mgt->dev) -
|
(int)((mgt->total_cma_size -
|
||||||
mgt->alloced_cma_size) / SZ_1M));
|
mgt->alloced_cma_size) / SZ_1M));
|
||||||
tsize += s;
|
tsize += s;
|
||||||
pbuf += s;
|
pbuf += s;
|
||||||
@@ -1287,7 +1343,7 @@ int codec_mm_mgt_init(struct device *dev)
|
|||||||
mgt->res_mem_flags |= RES_MEM_FLAGS_HAVE_MAPED;
|
mgt->res_mem_flags |= RES_MEM_FLAGS_HAVE_MAPED;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
mgt->total_cma_size = dma_get_cma_size_int_byte(mgt->dev);
|
mgt->total_cma_size = codec_mm_get_cma_size_int_byte(mgt->dev);
|
||||||
mgt->total_codec_mem_size += mgt->total_cma_size;
|
mgt->total_codec_mem_size += mgt->total_cma_size;
|
||||||
/*2M for audio not protect.*/
|
/*2M for audio not protect.*/
|
||||||
default_tvp_4k_size = mgt->total_codec_mem_size - SZ_1M * 2;
|
default_tvp_4k_size = mgt->total_codec_mem_size - SZ_1M * 2;
|
||||||
|
|||||||
@@ -2443,13 +2443,13 @@ static int codec_mm_scatter_free_all_ignorecache_in(
|
|||||||
} while ((smgt->scatters_cnt > 0) && (retry_num++ < 1000));
|
} while ((smgt->scatters_cnt > 0) && (retry_num++ < 1000));
|
||||||
if (need_retry || smgt->scatters_cnt > 0) {
|
if (need_retry || smgt->scatters_cnt > 0) {
|
||||||
pr_info("can't free all scatter, because some have used!!\n");
|
pr_info("can't free all scatter, because some have used!!\n");
|
||||||
codec_mm_dump_all_scatters();
|
/*codec_mm_dump_all_scatters();*/
|
||||||
}
|
}
|
||||||
codec_mm_free_all_free_slots_in(smgt);
|
codec_mm_free_all_free_slots_in(smgt);
|
||||||
if (smgt->total_page_num > 0) {
|
if (smgt->total_page_num > 0) {
|
||||||
/*have some not free,dump tables for debug */
|
/*have some not free,dump tables for debug */
|
||||||
pr_info("Some slots have not free!!\n\n");
|
pr_info("Some slots have not free!!\n\n");
|
||||||
codec_mm_dump_all_hash_table();
|
/*codec_mm_dump_all_hash_table();*/
|
||||||
}
|
}
|
||||||
mutex_unlock(&smgt->monitor_lock);
|
mutex_unlock(&smgt->monitor_lock);
|
||||||
return smgt->total_page_num;
|
return smgt->total_page_num;
|
||||||
|
|||||||
Reference in New Issue
Block a user