author | Zhi Zhou <zhi.zhou@amlogic.com> | 2017-09-20 03:31:55 (GMT) |
---|---|---|
committer | jie.yuan <jie.yuan@amlogic.com> | 2018-03-02 06:13:24 (GMT) |
commit | be48fa4c7002384e70d37c347831ca6157835f30 (patch) | |
tree | 3c3b88e3f7387d9160de840442ee86e0532d6c5c | |
parent | 003e1bde450ed2103395f13a2511eb567df4408e (diff) | |
download | common-be48fa4c7002384e70d37c347831ca6157835f30.zip common-be48fa4c7002384e70d37c347831ca6157835f30.tar.gz common-be48fa4c7002384e70d37c347831ca6157835f30.tar.bz2 |
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>
-rw-r--r-- | drivers/amlogic/media/common/codec_mm/codec_mm.c | 146 | ||||
-rw-r--r-- | drivers/amlogic/media/common/codec_mm/codec_mm_scatter.c | 4 |
2 files changed, 103 insertions, 47 deletions
diff --git a/drivers/amlogic/media/common/codec_mm/codec_mm.c b/drivers/amlogic/media/common/codec_mm/codec_mm.c index e6859c6..c221e18 100644 --- a/drivers/amlogic/media/common/codec_mm/codec_mm.c +++ b/drivers/amlogic/media/common/codec_mm/codec_mm.c @@ -49,6 +49,7 @@ #define CONFIG_PREFIX "media" +#define MM_ALIGN_DOWN(addr, size) ((addr) & (~((size) - 1))) #define RES_IS_MAPED #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, struct codec_mm_s *mem) { - if (!(mem->flags & CODEC_MM_FLAGS_FOR_LOCAL_MGR)) - mgt->total_alloced_size -= mem->buffer_size; - if (mem->flags & CODEC_MM_FLAGS_FOR_SCATTER) { - mgt->alloced_for_sc_size -= mem->buffer_size; - mgt->alloced_for_sc_cnt--; - } - + 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); - mgt->alloced_cma_size -= mem->buffer_size; } 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; } 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; } 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; } 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)) + mgt->total_alloced_size -= mem->buffer_size; + if (mem->flags & CODEC_MM_FLAGS_FOR_SCATTER) { + mgt->alloced_for_sc_size -= mem->buffer_size; + mgt->alloced_for_sc_cnt--; + } + if (mem->from_flags == AMPORTS_MEM_FLAGS_FROM_GET_FROM_CMA) { + mgt->alloced_cma_size -= mem->buffer_size; + } else if (mem->from_flags == + AMPORTS_MEM_FLAGS_FROM_GET_FROM_REVERSED) { + mgt->alloced_res_size -= mem->buffer_size; + } else if (mem->from_flags == AMPORTS_MEM_FLAGS_FROM_GET_FROM_TVP) { + mgt->tvp_pool.alloced_size -= mem->buffer_size; + } else if (mem->from_flags == AMPORTS_MEM_FLAGS_FROM_GET_FROM_PAGES) { + mgt->alloced_sys_size -= mem->buffer_size; + } else if (mem->from_flags == AMPORTS_MEM_FLAGS_FROM_GET_FROM_CMA_RES) { 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, @@ -839,26 +850,35 @@ int codec_mm_extpool_pool_alloc( mutex_lock(&tvp_pool->pool_lock); try_alloced_size = mgt->total_reserved_size - mgt->alloced_res_size; if (try_alloced_size > 0 && for_tvp) { + int retry = 0; try_alloced_size = min_t(int, size - alloced_size, try_alloced_size); - mem = codec_mm_alloc(TVP_POOL_NAME, - try_alloced_size, - RESERVE_MM_ALIGNED_2N, - CODEC_MM_FLAGS_FOR_LOCAL_MGR | - CODEC_MM_FLAGS_RESERVED); - - if (mem) { - ret = codec_mm_init_tvp_pool( - tvp_pool, - mem); - if (ret < 0) { - codec_mm_release(mem, TVP_POOL_NAME); + try_alloced_size = MM_ALIGN_DOWN(try_alloced_size, + RESERVE_MM_ALIGNED_2N); + do { + mem = codec_mm_alloc(TVP_POOL_NAME, + try_alloced_size, + RESERVE_MM_ALIGNED_2N, + CODEC_MM_FLAGS_FOR_LOCAL_MGR | + CODEC_MM_FLAGS_RESERVED); + + if (mem) { + ret = codec_mm_init_tvp_pool( + tvp_pool, + mem); + if (ret < 0) { + codec_mm_release(mem, TVP_POOL_NAME); + } else { + alloced_size += try_alloced_size; + tvp_pool->slot_num++; + } + break; } else { - alloced_size += try_alloced_size; - tvp_pool->slot_num++; - + try_alloced_size = try_alloced_size - 4 * SZ_1M; + if (try_alloced_size < 16 * SZ_1M) + break; } - } + } while (retry++ < 10); } if (alloced_size >= size) { /*alloc finished. */ @@ -868,9 +888,14 @@ int codec_mm_extpool_pool_alloc( /*alloced from cma:*/ try_alloced_size = mgt->total_cma_size - mgt->alloced_cma_size; if (try_alloced_size > 0) { - try_alloced_size = min_t(int, size - - alloced_size, try_alloced_size); - mem = codec_mm_alloc( + int retry = 0; + + 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 ? TVP_POOL_NAME : CMA_RES_POOL_NAME, @@ -878,18 +903,23 @@ int codec_mm_extpool_pool_alloc( RESERVE_MM_ALIGNED_2N, CODEC_MM_FLAGS_FOR_LOCAL_MGR | CODEC_MM_FLAGS_CMA); - - if (mem) { - ret = codec_mm_init_tvp_pool( - tvp_pool, - mem); - if (ret < 0) { - codec_mm_release(mem, TVP_POOL_NAME); + if (mem) { + ret = codec_mm_init_tvp_pool( + tvp_pool, + mem); + if (ret < 0) { + codec_mm_release(mem, TVP_POOL_NAME); + } else { + alloced_size += try_alloced_size; + tvp_pool->slot_num++; + } + break; } else { - alloced_size += try_alloced_size; - tvp_pool->slot_num++; + try_alloced_size = try_alloced_size - 4 * SZ_1M; + if (try_alloced_size < 16 * SZ_1M) + break; } - } + } while (retry++ < 10); } alloced_finished: @@ -1048,9 +1078,35 @@ unsigned long dma_get_cma_size_int_byte(struct device *dev) return 0; } size = cma_get_size(cma); - 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) { @@ -1103,9 +1159,9 @@ static int dump_mem_infos(void *buf, int size) s = snprintf(pbuf, size - tsize, "\t[%d]CMA size:%d MB:alloced: %d MB,free:%d MB\n", 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)((dma_get_cma_size_int_byte(mgt->dev) - + (int)((mgt->total_cma_size - mgt->alloced_cma_size) / SZ_1M)); tsize += s; pbuf += s; @@ -1287,7 +1343,7 @@ int codec_mm_mgt_init(struct device *dev) mgt->res_mem_flags |= RES_MEM_FLAGS_HAVE_MAPED; #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; /*2M for audio not protect.*/ default_tvp_4k_size = mgt->total_codec_mem_size - SZ_1M * 2; diff --git a/drivers/amlogic/media/common/codec_mm/codec_mm_scatter.c b/drivers/amlogic/media/common/codec_mm/codec_mm_scatter.c index fa6af812..5bbd754 100644 --- a/drivers/amlogic/media/common/codec_mm/codec_mm_scatter.c +++ b/drivers/amlogic/media/common/codec_mm/codec_mm_scatter.c @@ -2441,13 +2441,13 @@ static int codec_mm_scatter_free_all_ignorecache_in( } while ((smgt->scatters_cnt > 0) && (retry_num++ < 1000)); if (need_retry || smgt->scatters_cnt > 0) { 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); if (smgt->total_page_num > 0) { /*have some not free,dump tables for debug */ 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); return smgt->total_page_num; |