From 07fd155411c7a3ad8868f00a223eb811d5a1efbf Mon Sep 17 00:00:00 2001 From: rongrong zhou Date: Thu, 28 Jun 2018 13:49:54 +0800 Subject: [PATCH] codec_mm: alloc fail issue [1/2] PD#167377 1. try_alloc_cma_size 4M -> 16M 2. dump free meminfo Change-Id: Ideaf9f70067861d3b08b48336074b32213986cb6 Signed-off-by: rongrong zhou --- drivers/amlogic/media/common/codec_mm/codec_mm.c | 68 ++++++++++++++++++++++ .../media/common/codec_mm/codec_mm_scatter.c | 53 ++++++++++++++++- 2 files changed, 119 insertions(+), 2 deletions(-) diff --git a/drivers/amlogic/media/common/codec_mm/codec_mm.c b/drivers/amlogic/media/common/codec_mm/codec_mm.c index 814e545..e6665d3 100644 --- a/drivers/amlogic/media/common/codec_mm/codec_mm.c +++ b/drivers/amlogic/media/common/codec_mm/codec_mm.c @@ -33,10 +33,13 @@ #include #include #include +#include #include #include #include +#include +#include #include "codec_mm_priv.h" #include "codec_mm_scatter_priv.h" @@ -50,6 +53,7 @@ #define MM_ALIGN_DOWN(addr, size) ((addr) & (~((size) - 1))) +#define MM_ALIGN_UP2N(addr, alg2n) ((addr+(1<lock, flags); + list_for_each_entry(mem, &mgt->mem_list, list) { + usedb[i].phy_addr = mem->phy_addr; + usedb[i].buffer_size = mem->buffer_size; + usedb[i].align2n = mem->align2n; + if (++i >= 128) { + pr_info("too many memlist in codec_mm, break;\n"); + break; + } + }; + cma_base_phy = cma_get_base(dev_get_cma_area(mgt->dev)); + cma_end_phy = cma_base_phy + dma_get_cma_size_int_byte(mgt->dev); + spin_unlock_irqrestore(&mgt->lock, flags); + pr_info("free cma idea[%x-%x] from codec_mm items %d\n", cma_base_phy, + cma_end_phy, i); + for (j = 0; j < i; j++) { /* free */ + freeb[j].phy_addr = usedb[j].phy_addr + + MM_ALIGN_UP2N(usedb[j].buffer_size, usedb[j].align2n); + minphy = cma_end_phy; + for (k = 0; k < i; k++) { /* used */ + if (usedb[k].phy_addr >= freeb[j].phy_addr && + usedb[k].phy_addr < minphy) + minphy = usedb[k].phy_addr; + } + freeb[j].buffer_size = minphy - freeb[j].phy_addr; + total_free_size += freeb[j].buffer_size; + if (freeb[j].buffer_size > 0) + pr_info("\t[%d] free buf phyaddr=%p, used [%p,%x], size=%x\n", + j, (void *)freeb[j].phy_addr, + (void *)usedb[j].phy_addr, + usedb[j].buffer_size, freeb[j].buffer_size); + } + pr_info("total_free_size %x\n", total_free_size); + kfree(usedb); + return 0; +} + int codec_mm_video_tvp_enabled(void) { struct codec_mm_mgt_s *mgt = get_mem_mgt(); @@ -1306,6 +1370,7 @@ int codec_mm_enough_for_size(int size, int with_wait) return 1; if (debug_mode & 0x20) dump_mem_infos(NULL, 0); + msleep(50); return 0; } return 1; @@ -1711,6 +1776,9 @@ static ssize_t codec_mm_debug_store(struct class *class, case 11: dump_mem_infos(NULL, 0); break; + case 12: + dump_free_mem_infos(NULL, 0); + break; case 20: { int cmd, len; unsigned int addr; 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 b17e3d1..1f3e023 100644 --- a/drivers/amlogic/media/common/codec_mm/codec_mm_scatter.c +++ b/drivers/amlogic/media/common/codec_mm/codec_mm_scatter.c @@ -385,6 +385,44 @@ void codec_mm_clear_alloc_infos(void) codec_mm_clear_alloc_infos_in(codec_mm_get_scatter_mgt(1)); } +#if 0 +static int codec_mm_slot_get_info(struct codec_mm_scatter_mgt *smgt, + int *free_pages, int *slot_num, int *max_sg_pages) +{ + struct codec_mm_slot *slot; + int total_pages = 0; + int alloced_pages = 0; + int slot_used_num = 0; + int max_free_pages_sg = 0; + + codec_mm_list_lock(smgt); + if (!list_empty(&smgt->free_list)) { + struct list_head *header, *list; + + header = &smgt->free_list; + list = header->prev; + while (list != header) { + slot = list_entry(list, struct codec_mm_slot, + free_list); + total_pages += slot->page_num; + alloced_pages += slot->alloced_page_num; + slot_used_num++; + if (slot->page_num - slot->alloced_page_num > + max_free_pages_sg) + max_free_pages_sg = slot->page_num - + slot->alloced_page_num; + list = list->prev; + }; + } + codec_mm_list_unlock(smgt); + if (total_pages < alloced_pages) + return 0; + *free_pages = total_pages - alloced_pages; + *slot_num = slot_used_num; + *max_sg_pages = max_free_pages_sg; + return 0; +} +#endif static int codec_mm_set_slot_in_hash( struct codec_mm_scatter_mgt *smgt, @@ -882,10 +920,19 @@ static int codec_mm_page_alloc_from_slot( /*codec_mm_scatter_info_dump(NULL, 0);*/ slot = codec_mm_slot_alloc(smgt, 0, 0); if (!slot) { + u32 alloc_pages = + smgt->try_alloc_in_cma_page_cnt/4; /* *ERR_LOG("can't alloc slot from system\n"); */ - break; + pr_info("alloc default cma size fail, try %d pages\n", + alloc_pages); + slot = codec_mm_slot_alloc(smgt, + alloc_pages * PAGE_SIZE, 0); + if (!slot) { + pr_info("slot alloc 4M fail!\n"); + break; + } } } codec_mm_list_lock(smgt); @@ -2432,6 +2479,8 @@ static int codec_mm_scatter_free_all_ignorecache_in( smgt->cached_pages = 0; codec_mm_list_unlock(smgt); if (mms) { + pr_info("cache_sc page_max %d, page_used %d\n", + mms->page_max_cnt, mms->page_used); codec_mm_scatter_dec_owner_user(mms, 0); codec_mm_scatter_free_on_nouser(smgt, mms); } @@ -2502,7 +2551,7 @@ static int codec_mm_scatter_mgt_alloc_in(struct codec_mm_scatter_mgt **psmgt) spin_lock_init(&smgt->list_lock); smgt->tag = SMGT_IDENTIFY_TAG; smgt->alloced_page_num = 0; - smgt->try_alloc_in_cma_page_cnt = (4 * 1024 * 1024) / PAGE_SIZE; + smgt->try_alloc_in_cma_page_cnt = (16 * 1024 * 1024) / PAGE_SIZE; smgt->try_alloc_in_sys_page_cnt_max = MAX_SYS_BLOCK_PAGE; smgt->try_alloc_in_sys_page_cnt = MAX_SYS_BLOCK_PAGE; smgt->try_alloc_in_sys_page_cnt_min = MIN_SYS_BLOCK_PAGE; -- 2.7.4