From a1db7dca6c5fa134f2d859b92268a6d1dfce577a Mon Sep 17 00:00:00 2001 From: Tao Zeng Date: Thu, 20 Jan 2022 15:09:43 +0800 Subject: [PATCH] mm: add pagetrace support [1/2] PD#SWPL-70022 Problem: No pagetrace function on 5.15 kernel Solution: porting it from 5.4 Verify: local Signed-off-by: Tao Zeng Change-Id: I69cc8b4f4fa4c323204f86e5c76613cd3d6087df --- include/linux/mm.h | 16 ++++++++++++++++ include/linux/mm_types.h | 10 ++++++++++ init/main.c | 8 ++++++++ mm/compaction.c | 6 ++++++ mm/mm_init.c | 5 +++++ mm/page_alloc.c | 13 +++++++++++++ 6 files changed, 58 insertions(+) diff --git a/include/linux/mm.h b/include/linux/mm.h index 86a219839714..d2a28f2e12b8 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1143,7 +1143,23 @@ vm_fault_t finish_mkwrite_fault(struct vm_fault *vmf); */ /* Page flags: | [SECTION] | [NODE] | ZONE | [LAST_CPUPID] | ... | FLAGS | */ +#ifdef CONFIG_AMLOGIC_PAGE_TRACE_INLINE +/* + * We use high 32bit of page->flags for page trace, Make sure: + * __NR_PAGEFLAGS : about 21 bits + * ZONES_WIDTH : about 2 bits, MAX 4 zone types + * NODES_WIDTH : about 2 bits if open CONFIG_NUMA, else 0 bit + * SECTIONS_WIDTH : 0 bit if defined CONFIG_SPARSEMEM_VMEMMAP otherwise 18 + * bits on ARM64 + * LAST_CPUPID_SHIFT : 0 bit if not define CONFIG_NUMA_BALANCING, otherwise + * 8 + NR_CPUS_BITS + * All of these macros should be using less than 32bits in total, otherwise + * compile will fail + */ +#define SECTIONS_PGOFF ((sizeof(unsigned int) * 8) - SECTIONS_WIDTH) +#else #define SECTIONS_PGOFF ((sizeof(unsigned long)*8) - SECTIONS_WIDTH) +#endif /* CONFIG_AMLOGIC_PAGE_TRACE_INLINE */ #define NODES_PGOFF (SECTIONS_PGOFF - NODES_WIDTH) #define ZONES_PGOFF (NODES_PGOFF - ZONES_WIDTH) #define LAST_CPUPID_PGOFF (ZONES_PGOFF - LAST_CPUPID_WIDTH) diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 076bb5eb99f2..8caa17dc547d 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -70,8 +70,18 @@ struct mem_cgroup; #endif struct page { +#ifdef CONFIG_AMLOGIC_PAGE_TRACE_INLINE + union { + unsigned long flags; + struct { + unsigned int s_flags; + unsigned int trace; + }; + }; +#else unsigned long flags; /* Atomic flags, some possibly * updated asynchronously */ +#endif /* CONFIG_AMLOGIC_PAGE_TRACE_INLINE */ /* * Five words (20/40 bytes) are available in this union. * WARNING: bit 0 of the first word is used for PageTail(). That diff --git a/init/main.c b/init/main.c index 74aa707f2f71..bfa45a214d76 100644 --- a/init/main.c +++ b/init/main.c @@ -113,6 +113,10 @@ #include +#ifdef CONFIG_AMLOGIC_PAGE_TRACE +#include +#endif + static int kernel_init(void *); extern void init_IRQ(void); @@ -860,6 +864,10 @@ static void __init mm_init(void) kfence_alloc_pool(); report_meminit(); stack_depot_init(); +#ifdef CONFIG_AMLOGIC_PAGE_TRACE + /* allocate memory before first page allocated */ + page_trace_mem_init(); +#endif mem_init(); mem_init_print_info(); /* page_owner must be initialized after buddy is ready */ diff --git a/mm/compaction.c b/mm/compaction.c index cccb46701c23..2d05f1a97c1a 100644 --- a/mm/compaction.c +++ b/mm/compaction.c @@ -24,6 +24,9 @@ #include #include #include "internal.h" +#ifdef CONFIG_AMLOGIC_PAGE_TRACE +#include +#endif #ifdef CONFIG_COMPACTION static inline void count_compact_event(enum vm_event_item item) @@ -1738,6 +1741,9 @@ static struct page *compaction_alloc(struct page *migratepage, freepage = list_entry(cc->freepages.next, struct page, lru); list_del(&freepage->lru); cc->nr_freepages--; +#ifdef CONFIG_AMLOGIC_PAGE_TRACE + replace_page_trace(freepage, migratepage); +#endif return freepage; } diff --git a/mm/mm_init.c b/mm/mm_init.c index 0d7b2bd2454a..9383fd4c80bc 100644 --- a/mm/mm_init.c +++ b/mm/mm_init.c @@ -63,7 +63,12 @@ void __init mminit_verify_pageflags_layout(void) int shift, width; unsigned long or_mask, add_mask; +#ifdef CONFIG_AMLOGIC_PAGE_TRACE_INLINE + /* high 32bits have been taken by pagetrace, avoid bug in line 117 */ + shift = 8 * sizeof(unsigned int); +#else shift = 8 * sizeof(unsigned long); +#endif width = shift - SECTIONS_WIDTH - NODES_WIDTH - ZONES_WIDTH - LAST_CPUPID_SHIFT - KASAN_TAG_WIDTH - LRU_GEN_WIDTH - LRU_REFS_WIDTH; mminit_dprintk(MMINIT_TRACE, "pageflags_layout_widths", diff --git a/mm/page_alloc.c b/mm/page_alloc.c index aaf0fa0c86ba..e52aafa96869 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -81,6 +81,10 @@ #include "shuffle.h" #include "page_reporting.h" +#ifdef CONFIG_AMLOGIC_PAGE_TRACE +#include +#endif + EXPORT_TRACEPOINT_SYMBOL_GPL(mm_page_alloc); EXPORT_TRACEPOINT_SYMBOL_GPL(mm_page_free); @@ -1486,6 +1490,9 @@ static __always_inline bool free_pages_prepare(struct page *page, debug_pagealloc_unmap_pages(page, 1 << order); +#ifdef CONFIG_AMLOGIC_PAGE_TRACE + reset_page_trace(page, order); +#endif /* CONFIG_AMLOGIC_PAGE_TRACE */ return true; } @@ -5624,6 +5631,9 @@ unsigned long __alloc_pages_bulk(gfp_t gfp, int preferred_nid, else page_array[nr_populated] = page; nr_populated++; + #ifdef CONFIG_AMLOGIC_PAGE_TRACE + set_page_trace(page, 0, gfp, NULL); + #endif /* CONFIG_AMLOGIC_PAGE_TRACE */ } pcp_spin_unlock_irqrestore(pcp, flags); @@ -5717,6 +5727,9 @@ out: } trace_mm_page_alloc(page, order, alloc_gfp, ac.migratetype); +#ifdef CONFIG_AMLOGIC_PAGE_TRACE + set_page_trace(page, order, gfp, NULL); +#endif /* CONFIG_AMLOGIC_PAGE_TRACE */ return page; }