30
30
#include <linux/spinlock_types.h>
31
31
#include <linux/amlogic/aml_cma.h>
32
32
#include <linux/hugetlb.h>
33
+ #include <linux/proc_fs.h>
33
34
#include <trace/events/page_isolation.h>
34
35
#ifdef CONFIG_AMLOGIC_PAGE_TRACE
35
36
#include <linux/amlogic/page_trace.h>
36
37
#endif /* CONFIG_AMLOGIC_PAGE_TRACE */
37
38
39
+ #define MAX_DEBUG_LEVEL 5
40
+
38
41
struct work_cma {
39
42
struct list_head list ;
40
43
unsigned long pfn ;
@@ -52,6 +55,8 @@ struct cma_pcp {
52
55
53
56
static bool can_boost ;
54
57
static DEFINE_PER_CPU (struct cma_pcp , cma_pcp_thread ) ;
58
+ static struct proc_dir_entry * dentry ;
59
+ int cma_debug_level ;
55
60
56
61
DEFINE_SPINLOCK (cma_iso_lock );
57
62
static atomic_t cma_allocate ;
@@ -261,6 +266,7 @@ static int aml_alloc_contig_migrate_range(struct compact_control *cc,
261
266
pfn = isolate_migratepages_range (cc , pfn , end );
262
267
if (!pfn ) {
263
268
ret = - EINTR ;
269
+ cma_debug (1 , NULL , " iso migrate page fail\n" );
264
270
break ;
265
271
}
266
272
tries = 0 ;
@@ -336,7 +342,7 @@ static int cma_boost_work_func(void *cma_data)
336
342
drain_local_pages (NULL );
337
343
}
338
344
if (ret )
339
- pr_debug ( "%s, failed, ret:%d\n", __func__ , ret );
345
+ cma_debug ( 1 , NULL , " failed, ret:%d\n" , ret );
340
346
next :
341
347
complete (& c_work -> end );
342
348
if (kthread_should_stop ()) {
@@ -441,34 +447,6 @@ int cma_alloc_contig_boost(unsigned long start_pfn, unsigned long count)
441
447
return ret ;
442
448
}
443
449
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
-
472
450
static int __aml_check_pageblock_isolate (unsigned long pfn ,
473
451
unsigned long end_pfn ,
474
452
bool skip_hwpoisoned_pages ,
@@ -496,13 +474,7 @@ static int __aml_check_pageblock_isolate(unsigned long pfn,
496
474
*/
497
475
pfn ++ ;
498
476
} 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" );
506
478
break ;
507
479
}
508
480
}
@@ -581,11 +553,14 @@ int aml_cma_alloc_range(unsigned long start, unsigned long end)
581
553
};
582
554
INIT_LIST_HEAD (& cc .migratepages );
583
555
556
+ cma_debug (0 , NULL , " range [%lx-%lx]\n" , start , end );
584
557
ret = start_isolate_page_range (get_align_pfn_low (start ),
585
558
get_align_pfn_high (end ), MIGRATE_CMA ,
586
559
false);
587
- if (ret )
560
+ if (ret ) {
561
+ cma_debug (1 , NULL , "ret:%d\n" , ret );
588
562
return ret ;
563
+ }
589
564
590
565
try_again :
591
566
/*
@@ -600,8 +575,10 @@ int aml_cma_alloc_range(unsigned long start, unsigned long end)
600
575
} else
601
576
ret = aml_alloc_contig_migrate_range (& cc , start , end , 0 );
602
577
603
- if (ret && ret != - EBUSY )
578
+ if (ret && ret != - EBUSY ) {
579
+ cma_debug (1 , NULL , "ret:%d\n" , ret );
604
580
goto done ;
581
+ }
605
582
606
583
ret = 0 ;
607
584
if (!boost_ok ) {
@@ -633,8 +610,8 @@ int aml_cma_alloc_range(unsigned long start, unsigned long end)
633
610
634
611
/* Make sure the range is really isolated. */
635
612
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 );
638
615
try_times ++ ;
639
616
if (try_times < 10 )
640
617
goto try_again ;
@@ -650,6 +627,8 @@ int aml_cma_alloc_range(unsigned long start, unsigned long end)
650
627
pr_info ("cma_alloc [%lx-%lx] aborted\n" , start , end );
651
628
} else
652
629
ret = - EBUSY ;
630
+ cma_debug (1 , NULL , "iso free range(%lx, %lx) failed\n" ,
631
+ outer_start , end );
653
632
goto done ;
654
633
}
655
634
@@ -733,11 +712,67 @@ void aml_cma_free(unsigned long pfn, unsigned int nr_pages)
733
712
}
734
713
EXPORT_SYMBOL (aml_cma_free );
735
714
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
+
736
765
static int __init aml_cma_init (void )
737
766
{
738
767
atomic_set (& cma_allocate , 0 );
739
768
atomic_long_set (& nr_cma_allocated , 0 );
740
769
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
+
741
776
return 0 ;
742
777
}
743
778
arch_initcall (aml_cma_init );
0 commit comments