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:
Zhi Zhou
2017-09-20 11:31:55 +08:00
committed by Jianxin Pan
parent 5089368f74
commit cc1dabc182
2 changed files with 106 additions and 50 deletions

View File

@@ -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;

View File

@@ -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;