Skip to content

Commit df5b7c6

Browse files
kongsuozttobetter
authored andcommitted
mm: add cma debug interafce [1/1]
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 <[email protected]>
1 parent f9b0766 commit df5b7c6

File tree

5 files changed

+195
-41
lines changed

5 files changed

+195
-41
lines changed

drivers/amlogic/memory_ext/aml_cma.c

Lines changed: 75 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,14 @@
3030
#include <linux/spinlock_types.h>
3131
#include <linux/amlogic/aml_cma.h>
3232
#include <linux/hugetlb.h>
33+
#include <linux/proc_fs.h>
3334
#include <trace/events/page_isolation.h>
3435
#ifdef CONFIG_AMLOGIC_PAGE_TRACE
3536
#include <linux/amlogic/page_trace.h>
3637
#endif /* CONFIG_AMLOGIC_PAGE_TRACE */
3738

39+
#define MAX_DEBUG_LEVEL 5
40+
3841
struct work_cma {
3942
struct list_head list;
4043
unsigned long pfn;
@@ -52,6 +55,8 @@ struct cma_pcp {
5255

5356
static bool can_boost;
5457
static DEFINE_PER_CPU(struct cma_pcp, cma_pcp_thread);
58+
static struct proc_dir_entry *dentry;
59+
int cma_debug_level;
5560

5661
DEFINE_SPINLOCK(cma_iso_lock);
5762
static atomic_t cma_allocate;
@@ -261,6 +266,7 @@ static int aml_alloc_contig_migrate_range(struct compact_control *cc,
261266
pfn = isolate_migratepages_range(cc, pfn, end);
262267
if (!pfn) {
263268
ret = -EINTR;
269+
cma_debug(1, NULL, " iso migrate page fail\n");
264270
break;
265271
}
266272
tries = 0;
@@ -336,7 +342,7 @@ static int cma_boost_work_func(void *cma_data)
336342
drain_local_pages(NULL);
337343
}
338344
if (ret)
339-
pr_debug("%s, failed, ret:%d\n", __func__, ret);
345+
cma_debug(1, NULL, "failed, ret:%d\n", ret);
340346
next:
341347
complete(&c_work->end);
342348
if (kthread_should_stop()) {
@@ -441,34 +447,6 @@ int cma_alloc_contig_boost(unsigned long start_pfn, unsigned long count)
441447
return ret;
442448
}
443449

444-
/*
445-
* Some of these functions are implemented from page_isolate.c
446-
*/
447-
static bool can_free_list_page(struct page *page, struct list_head *list)
448-
{
449-
#if 0
450-
unsigned long flags;
451-
bool ret = false;
452-
453-
if (!spin_trylock_irqsave(&cma_iso_lock, flags))
454-
return ret;
455-
456-
if (!(page->flags & PAGE_FLAGS_CHECK_AT_FREE) &&
457-
!PageSwapBacked(page) &&
458-
(page->lru.next != LIST_POISON1)) {
459-
if (list_empty(&page->lru))
460-
list_add(&page->lru, list);
461-
else
462-
list_move(&page->lru, list);
463-
ret = true;
464-
}
465-
spin_unlock_irqrestore(&cma_iso_lock, flags);
466-
return ret;
467-
#else
468-
return false;
469-
#endif
470-
}
471-
472450
static int __aml_check_pageblock_isolate(unsigned long pfn,
473451
unsigned long end_pfn,
474452
bool skip_hwpoisoned_pages,
@@ -496,13 +474,7 @@ static int __aml_check_pageblock_isolate(unsigned long pfn,
496474
*/
497475
pfn++;
498476
} else {
499-
/* This page can be freed ? */
500-
if (!page_count(page)) {
501-
if (can_free_list_page(page, list)) {
502-
pfn++;
503-
continue;
504-
}
505-
}
477+
cma_debug(1, page, " isolate failed\n");
506478
break;
507479
}
508480
}
@@ -581,11 +553,14 @@ int aml_cma_alloc_range(unsigned long start, unsigned long end)
581553
};
582554
INIT_LIST_HEAD(&cc.migratepages);
583555

556+
cma_debug(0, NULL, " range [%lx-%lx]\n", start, end);
584557
ret = start_isolate_page_range(get_align_pfn_low(start),
585558
get_align_pfn_high(end), MIGRATE_CMA,
586559
false);
587-
if (ret)
560+
if (ret) {
561+
cma_debug(1, NULL, "ret:%d\n", ret);
588562
return ret;
563+
}
589564

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

603-
if (ret && ret != -EBUSY)
578+
if (ret && ret != -EBUSY) {
579+
cma_debug(1, NULL, "ret:%d\n", ret);
604580
goto done;
581+
}
605582

606583
ret = 0;
607584
if (!boost_ok) {
@@ -633,8 +610,8 @@ int aml_cma_alloc_range(unsigned long start, unsigned long end)
633610

634611
/* Make sure the range is really isolated. */
635612
if (aml_check_pages_isolated(outer_start, end, false)) {
636-
pr_debug("%s check_pages_isolated(%lx, %lx) failed\n",
637-
__func__, outer_start, end);
613+
cma_debug(1, NULL, "check page isolate(%lx, %lx) failed\n",
614+
outer_start, end);
638615
try_times++;
639616
if (try_times < 10)
640617
goto try_again;
@@ -650,6 +627,8 @@ int aml_cma_alloc_range(unsigned long start, unsigned long end)
650627
pr_info("cma_alloc [%lx-%lx] aborted\n", start, end);
651628
} else
652629
ret = -EBUSY;
630+
cma_debug(1, NULL, "iso free range(%lx, %lx) failed\n",
631+
outer_start, end);
653632
goto done;
654633
}
655634

@@ -733,11 +712,67 @@ void aml_cma_free(unsigned long pfn, unsigned int nr_pages)
733712
}
734713
EXPORT_SYMBOL(aml_cma_free);
735714

715+
void show_page(struct page *page)
716+
{
717+
unsigned long trace = 0;
718+
719+
if (!page)
720+
return;
721+
#ifdef CONFIG_AMLOGIC_PAGE_TRACE
722+
trace = get_page_trace(page);
723+
#endif
724+
pr_info("page:%lx, map:%p, f:%lx, m:%d, c:%d, f:%pf\n",
725+
page_to_pfn(page), page->mapping,
726+
page->flags & 0xffffffff,
727+
page_mapcount(page), page_count(page),
728+
(void *)trace);
729+
}
730+
731+
static int cma_debug_show(struct seq_file *m, void *arg)
732+
{
733+
seq_printf(m, "level=%d\n", cma_debug_level);
734+
return 0;
735+
}
736+
737+
static ssize_t cma_debug_write(struct file *file, const char __user *buffer,
738+
size_t count, loff_t *ppos)
739+
{
740+
int arg = 0;
741+
742+
if (kstrtoint_from_user(buffer, count, 10, &arg))
743+
return -EINVAL;
744+
745+
if (arg > MAX_DEBUG_LEVEL)
746+
return -EINVAL;
747+
748+
cma_debug_level = arg;
749+
return count;
750+
}
751+
752+
static int cma_debug_open(struct inode *inode, struct file *file)
753+
{
754+
return single_open(file, cma_debug_show, NULL);
755+
}
756+
757+
static const struct file_operations cma_dbg_file_ops = {
758+
.open = cma_debug_open,
759+
.read = seq_read,
760+
.llseek = seq_lseek,
761+
.write = cma_debug_write,
762+
.release = single_release,
763+
};
764+
736765
static int __init aml_cma_init(void)
737766
{
738767
atomic_set(&cma_allocate, 0);
739768
atomic_long_set(&nr_cma_allocated, 0);
740769

770+
dentry = proc_create("cma_debug", 0644, NULL, &cma_dbg_file_ops);
771+
if (IS_ERR_OR_NULL(dentry)) {
772+
pr_err("%s, create sysfs failed\n", __func__);
773+
return -1;
774+
}
775+
741776
return 0;
742777
}
743778
arch_initcall(aml_cma_init);

include/linux/amlogic/aml_cma.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,15 @@ extern bool cma_page(struct page *page);
7474
extern unsigned long get_cma_allocated(void);
7575
extern unsigned long get_total_cmapages(void);
7676
extern spinlock_t cma_iso_lock;
77+
extern int cma_debug_level;
7778
extern int aml_cma_alloc_range(unsigned long start, unsigned long end);
7879

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

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

85+
extern void show_page(struct page *page);
8486
unsigned long
8587
isolate_freepages_range(struct compact_control *cc,
8688
unsigned long start_pfn, unsigned long end_pfn);
@@ -91,4 +93,14 @@ isolate_migratepages_range(struct compact_control *cc,
9193
struct page *compaction_cma_alloc(struct page *migratepage,
9294
unsigned long data,
9395
int **result);
96+
97+
#define cma_debug(l, p, format, args...) \
98+
{ \
99+
if (l < cma_debug_level) { \
100+
show_page(p); \
101+
pr_info("%s, %d "format, __func__, __LINE__, ##args); \
102+
} \
103+
}
104+
105+
94106
#endif /* __AMLOGIC_CMA_H__ */

mm/cma.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,10 @@ struct page *cma_alloc(struct cma *cma, size_t count, unsigned int align)
509509
pr_debug("%s(cma %p, count %zu, align %d)\n", __func__, (void *)cma,
510510
count, align);
511511

512+
#ifdef CONFIG_AMLOGIC_CMA
513+
cma_debug(0, NULL, "(cma %p, count %zu, align %d)\n",
514+
(void *)cma, count, align);
515+
#endif
512516
if (!count)
513517
return NULL;
514518

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

571575
#ifdef CONFIG_AMLOGIC_CMA
572576
aml_cma_alloc_post_hook(&dummy, count, page);
577+
cma_debug(0, NULL, "return %p\n", page);
573578
#endif /* CONFIG_AMLOGIC_CMA */
574579
pr_debug("%s(): returned %p\n", __func__, page);
575580
return page;

0 commit comments

Comments
 (0)