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 <rongrong.zhou@amlogic.com>
This commit is contained in:
rongrong zhou
2018-06-28 13:49:54 +08:00
committed by Yixun Lan
parent cda6cea915
commit 07fd155411
2 changed files with 119 additions and 2 deletions

View File

@@ -33,10 +33,13 @@
#include <linux/genalloc.h>
#include <linux/dma-mapping.h>
#include <linux/dma-contiguous.h>
#include <linux/delay.h>
#include <linux/amlogic/media/codec_mm/codec_mm.h>
#include <linux/amlogic/media/codec_mm/codec_mm_scatter.h>
#include <linux/amlogic/media/codec_mm/configs.h>
#include <linux/amlogic/media/video_sink/video_keeper.h>
#include <linux/amlogic/media/utils/vdec_reg.h>
#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<<alg2n)-1)&(~((1<<alg2n)-1)))
#define RES_IS_MAPED
#define DEFAULT_TVP_SIZE_FOR_4K (256 * SZ_1M)
@@ -70,6 +74,7 @@
#define RES_MEM_FLAGS_HAVE_MAPED 0x4
static int dump_mem_infos(void *buf, int size);
static int dump_free_mem_infos(void *buf, int size);
/*
*debug_mode:
@@ -577,6 +582,7 @@ struct codec_mm_s *codec_mm_alloc(const char *owner, int size,
!(memflags & CODEC_MM_FLAGS_FOR_SCATTER)) {
/*if not scatter, free scatter caches. */
pr_err(" No mem ret=%d, clear scatter cache!!\n", ret);
dump_free_mem_infos(NULL, 0);
codec_mm_scatter_free_all_ignorecache(1);
ret = codec_mm_alloc_in(mgt, mem);
}
@@ -1236,6 +1242,64 @@ static int dump_mem_infos(void *buf, int size)
return tsize;
}
static int dump_free_mem_infos(void *buf, int size)
{
struct codec_mm_mgt_s *mgt = get_mem_mgt();
struct codec_mm_s *mem;
unsigned long flags;
int i = 0, j, k;
unsigned long minphy;
u32 cma_base_phy, cma_end_phy;
struct dump_buf_s {
unsigned long phy_addr;
int buffer_size;
int align2n;
} *usedb, *freeb;
int total_free_size = 0;
usedb = kzalloc(sizeof(struct dump_buf_s) * 256, GFP_KERNEL);
if (usedb == NULL)
return 0;
freeb = usedb + 128;
spin_lock_irqsave(&mgt->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;

View File

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