Skip to content

Commit

Permalink
mm: add cma debug interafce [1/1]
Browse files Browse the repository at this point in the history
PD#GH-17

Problem:
sometimes cma allocation failed but it's hard to get
failed log and need recompile code.

Solution:
Add /proc/cma_debug to open cma debug message dynamic.
By default, no debug message is printed. If you write a
value large than 0 to this node, debug message will be
printed.

Verify:
p212

Change-Id: Ibcfd1d48be5f33f674f09df713dc2e493748c405
Signed-off-by: tao zeng <tao.zeng@amlogic.com>
  • Loading branch information
kongsuozt authored and tobetter committed May 3, 2019
1 parent dbdc7f0 commit 90cc428
Show file tree
Hide file tree
Showing 5 changed files with 195 additions and 41 deletions.
115 changes: 75 additions & 40 deletions drivers/amlogic/memory_ext/aml_cma.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,14 @@
#include <linux/spinlock_types.h>
#include <linux/amlogic/aml_cma.h>
#include <linux/hugetlb.h>
#include <linux/proc_fs.h>
#include <trace/events/page_isolation.h>
#ifdef CONFIG_AMLOGIC_PAGE_TRACE
#include <linux/amlogic/page_trace.h>
#endif /* CONFIG_AMLOGIC_PAGE_TRACE */

#define MAX_DEBUG_LEVEL 5

struct work_cma {
struct list_head list;
unsigned long pfn;
Expand All @@ -52,6 +55,8 @@ struct cma_pcp {

static bool can_boost;
static DEFINE_PER_CPU(struct cma_pcp, cma_pcp_thread);
static struct proc_dir_entry *dentry;
int cma_debug_level;

DEFINE_SPINLOCK(cma_iso_lock);
static atomic_t cma_allocate;
Expand Down Expand Up @@ -261,6 +266,7 @@ static int aml_alloc_contig_migrate_range(struct compact_control *cc,
pfn = isolate_migratepages_range(cc, pfn, end);
if (!pfn) {
ret = -EINTR;
cma_debug(1, NULL, " iso migrate page fail\n");
break;
}
tries = 0;
Expand Down Expand Up @@ -336,7 +342,7 @@ static int cma_boost_work_func(void *cma_data)
drain_local_pages(NULL);
}
if (ret)
pr_debug("%s, failed, ret:%d\n", __func__, ret);
cma_debug(1, NULL, "failed, ret:%d\n", ret);
next:
complete(&c_work->end);
if (kthread_should_stop()) {
Expand Down Expand Up @@ -441,34 +447,6 @@ int cma_alloc_contig_boost(unsigned long start_pfn, unsigned long count)
return ret;
}

/*
* Some of these functions are implemented from page_isolate.c
*/
static bool can_free_list_page(struct page *page, struct list_head *list)
{
#if 0
unsigned long flags;
bool ret = false;

if (!spin_trylock_irqsave(&cma_iso_lock, flags))
return ret;

if (!(page->flags & PAGE_FLAGS_CHECK_AT_FREE) &&
!PageSwapBacked(page) &&
(page->lru.next != LIST_POISON1)) {
if (list_empty(&page->lru))
list_add(&page->lru, list);
else
list_move(&page->lru, list);
ret = true;
}
spin_unlock_irqrestore(&cma_iso_lock, flags);
return ret;
#else
return false;
#endif
}

static int __aml_check_pageblock_isolate(unsigned long pfn,
unsigned long end_pfn,
bool skip_hwpoisoned_pages,
Expand Down Expand Up @@ -496,13 +474,7 @@ static int __aml_check_pageblock_isolate(unsigned long pfn,
*/
pfn++;
} else {
/* This page can be freed ? */
if (!page_count(page)) {
if (can_free_list_page(page, list)) {
pfn++;
continue;
}
}
cma_debug(1, page, " isolate failed\n");
break;
}
}
Expand Down Expand Up @@ -581,11 +553,14 @@ int aml_cma_alloc_range(unsigned long start, unsigned long end)
};
INIT_LIST_HEAD(&cc.migratepages);

cma_debug(0, NULL, " range [%lx-%lx]\n", start, end);
ret = start_isolate_page_range(get_align_pfn_low(start),
get_align_pfn_high(end), MIGRATE_CMA,
false);
if (ret)
if (ret) {
cma_debug(1, NULL, "ret:%d\n", ret);
return ret;
}

try_again:
/*
Expand All @@ -600,8 +575,10 @@ int aml_cma_alloc_range(unsigned long start, unsigned long end)
} else
ret = aml_alloc_contig_migrate_range(&cc, start, end, 0);

if (ret && ret != -EBUSY)
if (ret && ret != -EBUSY) {
cma_debug(1, NULL, "ret:%d\n", ret);
goto done;
}

ret = 0;
if (!boost_ok) {
Expand Down Expand Up @@ -633,8 +610,8 @@ int aml_cma_alloc_range(unsigned long start, unsigned long end)

/* Make sure the range is really isolated. */
if (aml_check_pages_isolated(outer_start, end, false)) {
pr_debug("%s check_pages_isolated(%lx, %lx) failed\n",
__func__, outer_start, end);
cma_debug(1, NULL, "check page isolate(%lx, %lx) failed\n",
outer_start, end);
try_times++;
if (try_times < 10)
goto try_again;
Expand All @@ -650,6 +627,8 @@ int aml_cma_alloc_range(unsigned long start, unsigned long end)
pr_info("cma_alloc [%lx-%lx] aborted\n", start, end);
} else
ret = -EBUSY;
cma_debug(1, NULL, "iso free range(%lx, %lx) failed\n",
outer_start, end);
goto done;
}

Expand Down Expand Up @@ -733,11 +712,67 @@ void aml_cma_free(unsigned long pfn, unsigned int nr_pages)
}
EXPORT_SYMBOL(aml_cma_free);

void show_page(struct page *page)
{
unsigned long trace = 0;

if (!page)
return;
#ifdef CONFIG_AMLOGIC_PAGE_TRACE
trace = get_page_trace(page);
#endif
pr_info("page:%lx, map:%p, f:%lx, m:%d, c:%d, f:%pf\n",
page_to_pfn(page), page->mapping,
page->flags & 0xffffffff,
page_mapcount(page), page_count(page),
(void *)trace);
}

static int cma_debug_show(struct seq_file *m, void *arg)
{
seq_printf(m, "level=%d\n", cma_debug_level);
return 0;
}

static ssize_t cma_debug_write(struct file *file, const char __user *buffer,
size_t count, loff_t *ppos)
{
int arg = 0;

if (kstrtoint_from_user(buffer, count, 10, &arg))
return -EINVAL;

if (arg > MAX_DEBUG_LEVEL)
return -EINVAL;

cma_debug_level = arg;
return count;
}

static int cma_debug_open(struct inode *inode, struct file *file)
{
return single_open(file, cma_debug_show, NULL);
}

static const struct file_operations cma_dbg_file_ops = {
.open = cma_debug_open,
.read = seq_read,
.llseek = seq_lseek,
.write = cma_debug_write,
.release = single_release,
};

static int __init aml_cma_init(void)
{
atomic_set(&cma_allocate, 0);
atomic_long_set(&nr_cma_allocated, 0);

dentry = proc_create("cma_debug", 0644, NULL, &cma_dbg_file_ops);
if (IS_ERR_OR_NULL(dentry)) {
pr_err("%s, create sysfs failed\n", __func__);
return -1;
}

return 0;
}
arch_initcall(aml_cma_init);
12 changes: 12 additions & 0 deletions include/linux/amlogic/aml_cma.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,15 @@ extern bool cma_page(struct page *page);
extern unsigned long get_cma_allocated(void);
extern unsigned long get_total_cmapages(void);
extern spinlock_t cma_iso_lock;
extern int cma_debug_level;
extern int aml_cma_alloc_range(unsigned long start, unsigned long end);

extern void aml_cma_free(unsigned long pfn, unsigned int nr_pages);

extern unsigned long reclaim_clean_pages_from_list(struct zone *zone,
struct list_head *page_list);

extern void show_page(struct page *page);
unsigned long
isolate_freepages_range(struct compact_control *cc,
unsigned long start_pfn, unsigned long end_pfn);
Expand All @@ -91,4 +93,14 @@ isolate_migratepages_range(struct compact_control *cc,
struct page *compaction_cma_alloc(struct page *migratepage,
unsigned long data,
int **result);

#define cma_debug(l, p, format, args...) \
{ \
if (l < cma_debug_level) { \
show_page(p); \
pr_info("%s, %d "format, __func__, __LINE__, ##args); \
} \
}


#endif /* __AMLOGIC_CMA_H__ */
5 changes: 5 additions & 0 deletions mm/cma.c
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,10 @@ struct page *cma_alloc(struct cma *cma, size_t count, unsigned int align)
pr_debug("%s(cma %p, count %zu, align %d)\n", __func__, (void *)cma,
count, align);

#ifdef CONFIG_AMLOGIC_CMA
cma_debug(0, NULL, "(cma %p, count %zu, align %d)\n",
(void *)cma, count, align);
#endif
if (!count)
return NULL;

Expand Down Expand Up @@ -570,6 +574,7 @@ struct page *cma_alloc(struct cma *cma, size_t count, unsigned int align)

#ifdef CONFIG_AMLOGIC_CMA
aml_cma_alloc_post_hook(&dummy, count, page);
cma_debug(0, NULL, "return %p\n", page);
#endif /* CONFIG_AMLOGIC_CMA */
pr_debug("%s(): returned %p\n", __func__, page);
return page;
Expand Down
Loading

0 comments on commit 90cc428

Please sign in to comment.