From 57e54041b36f47e143db79da963fff8df8e0be6d Mon Sep 17 00:00:00 2001 From: xuexizi Date: Wed, 10 Sep 2025 12:00:11 +0800 Subject: [PATCH] ohos inclusion category: feature issue: #ICXA3E CVE: NA -------------------------- Signed-off-by: xuexizi --- fs/proc/meminfo.c | 9 ++++ include/linux/mmzone.h | 3 ++ include/linux/page-flags.h | 9 ++++ mm/Kconfig | 16 +++++++ mm/Makefile | 1 + mm/debug.c | 4 ++ mm/memtrace_ashmem.c | 92 ++++++++++++++++++++++++++++++++++++++ mm/page_alloc.c | 34 +++++++++++++- mm/vmstat.c | 4 +- mm/zsmalloc.c | 3 ++ 10 files changed, 172 insertions(+), 3 deletions(-) create mode 100644 mm/memtrace_ashmem.c diff --git a/fs/proc/meminfo.c b/fs/proc/meminfo.c index 875306ca2b39..4d81eccc768e 100644 --- a/fs/proc/meminfo.c +++ b/fs/proc/meminfo.c @@ -160,6 +160,10 @@ static int meminfo_proc_show(struct seq_file *m, void *v) show_val_kb(m, "VmallocChunk: ", 0ul); show_val_kb(m, "Percpu: ", pcpu_nr_pages()); +#ifdef CONFIG_PAGE_TRACING + show_val_kb(m, "Skb: ", global_zone_page_state(NR_SKB_PAGES)); +#endif + memtest_report_meminfo(m); #ifdef CONFIG_MEMORY_FAILURE @@ -186,6 +190,11 @@ static int meminfo_proc_show(struct seq_file *m, void *v) global_zone_page_state(NR_FREE_CMA_PAGES)); #endif +#ifdef CONFIG_PAGE_TRACING + seq_puts(m, "GLTrack: - kB\n"); + show_val_kb(m, "ZspageUsed: ", global_zone_page_state(NR_ZSPAGES)); +#endif + #ifdef CONFIG_UNACCEPTED_MEMORY show_val_kb(m, "Unaccepted: ", global_zone_page_state(NR_UNACCEPTED)); diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index c378c11c2ee6..c40f72d98bfc 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -161,6 +161,9 @@ enum zone_stat_item { NR_ZSPAGES, /* allocated in zsmalloc */ #endif NR_FREE_CMA_PAGES, +#ifdef CONFIG_PAGE_TRACING + NR_SKB_PAGES, +#endif #ifdef CONFIG_UNACCEPTED_MEMORY NR_UNACCEPTED, #endif diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h index 1893a7916475..aa37e689bae1 100644 --- a/include/linux/page-flags.h +++ b/include/linux/page-flags.h @@ -136,6 +136,10 @@ enum pageflags { PG_arch_2, PG_arch_3, #endif +#ifdef CONFIG_PAGE_TRACING + PG_skb, + PG_zspage, +#endif #ifdef CONFIG_MEM_PURGEABLE PG_purgeable, #endif @@ -631,6 +635,11 @@ TESTCLEARFLAG(Young, young, PF_ANY) PAGEFLAG(Idle, idle, PF_ANY) #endif +#ifdef CONFIG_PAGE_TRACING + PAGEFLAG(SKB, skb, PF_ANY) + PAGEFLAG(Zspage, zspage, PF_ANY) +#endif + /* * PageReported() is used to track reported free pages within the Buddy * allocator. We can use the non-atomic version of the test and set diff --git a/mm/Kconfig b/mm/Kconfig index 11f2f83389e5..da9f076e23f2 100644 --- a/mm/Kconfig +++ b/mm/Kconfig @@ -516,6 +516,12 @@ config HYPERHOLD_ZSWAPD and the refault of anonymous pages is high, the content of zram will exchanged to eswap by a certain percentage. +config PAGE_TRACING + bool "Enable Page Tracing" + default n + help + This option enables page tracing. + config RECLAIM_ACCT bool "Memory reclaim delay accounting" default n @@ -1264,6 +1270,16 @@ config ANON_VMA_NAME area from being merged with adjacent virtual memory areas due to the difference in their name. +# +# Show the process ashmem for debug +# +config MEMTRACE_ASHMEM + bool "Ashmem Process Info Show" + depends on ASHMEM + default n + help + Enable the Ashmem Process Info Show + config USERFAULTFD bool "Enable userfaultfd() system call" depends on MMU diff --git a/mm/Makefile b/mm/Makefile index 94ea4fb43163..833d93d2ca54 100644 --- a/mm/Makefile +++ b/mm/Makefile @@ -71,6 +71,7 @@ ifdef CONFIG_MMU obj-$(CONFIG_ADVISE_SYSCALLS) += madvise.o endif +obj-$(CONFIG_MEMTRACE_ASHMEM) += memtrace_ashmem.o obj-$(CONFIG_SWAP) += page_io.o swap_state.o swapfile.o swap_slots.o obj-$(CONFIG_ZSWAP) += zswap.o obj-$(CONFIG_HAS_DMA) += dmapool.o diff --git a/mm/debug.c b/mm/debug.c index ee533a5ceb79..49b2dd7ac886 100644 --- a/mm/debug.c +++ b/mm/debug.c @@ -33,6 +33,10 @@ const char *migrate_reason_names[MR_TYPES] = { const struct trace_print_flags pageflag_names[] = { __def_pageflag_names, +#ifdef CONFIG_PAGE_TRACING + {1UL << PG_skb, "skb"}, + {1UL << PG_zspage, "zspage"}, +#endif {0, NULL} }; diff --git a/mm/memtrace_ashmem.c b/mm/memtrace_ashmem.c new file mode 100644 index 000000000000..fd045b939407 --- /dev/null +++ b/mm/memtrace_ashmem.c @@ -0,0 +1,92 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * mm/memtrace_ashmem.c + * + * Copyright (c) 2022 Huawei Technologies Co., Ltd. + */ +#include +#include +#include +#include +#include +#include +#include +#include "../drivers/staging/android/ashmem.h" + +static int ashmem_debug_process_info_open(struct inode *inode, + struct file *file); + +struct ashmem_debug_process_info_args { + struct seq_file *seq; + struct task_struct *tsk; +}; + +static const struct proc_ops debug_process_ashmem_info_fops = { + .proc_open = ashmem_debug_process_info_open, + .proc_read = seq_read, + .proc_lseek = seq_lseek, + .proc_release = single_release, +}; + +static int ashmem_debug_process_info_cb(const void *data, + struct file *f, unsigned int fd) +{ + const struct ashmem_debug_process_info_args *args = data; + struct task_struct *tsk = args->tsk; + + if (!is_ashmem_file(f)) + return 0; + seq_printf(args->seq, + "%s %u %u %s %zu\n", + tsk->comm, tsk->pid, fd, + get_ashmem_name_by_file(f), + get_ashmem_size_by_file(f)); + return 0; +} + +static int ashmem_debug_process_info_show(struct seq_file *s, void *d) +{ + struct task_struct *tsk = NULL; + struct ashmem_debug_process_info_args cb_args; + + seq_puts(s, "Process ashmem detail info:\n"); + seq_puts(s, "----------------------------------------------------\n"); + seq_printf(s, "%s %s %s %s %s\n", + "Process name", "Process ID", + "fd", "ashmem_name", "size"); + + ashmem_mutex_lock(); + rcu_read_lock(); + for_each_process(tsk) { + if (tsk->flags & PF_KTHREAD) + continue; + cb_args.seq = s; + cb_args.tsk = tsk; + + task_lock(tsk); + iterate_fd(tsk->files, 0, + ashmem_debug_process_info_cb, (void *)&cb_args); + task_unlock(tsk); + } + rcu_read_unlock(); + ashmem_mutex_unlock(); + seq_puts(s, "----------------------------------------------------\n"); + return 0; +} + +static int ashmem_debug_process_info_open(struct inode *inode, + struct file *file) +{ + return single_open(file, ashmem_debug_process_info_show, + inode->i_private); +} + +void init_ashmem_process_info(void) +{ + struct proc_dir_entry *entry = NULL; + + entry = proc_create_data("ashmem_process_info", 0444, + NULL, &debug_process_ashmem_info_fops, NULL); + if (!entry) + pr_err("Failed to create ashmem debug info\n"); +} diff --git a/mm/page_alloc.c b/mm/page_alloc.c index e9357c1a5443..e931fcc656f0 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -4637,6 +4637,22 @@ static struct page *__page_frag_cache_refill(struct page_frag_cache *nc, page = alloc_pages_node(NUMA_NO_NODE, gfp, 0); nc->va = page ? page_address(page) : NULL; +#ifdef CONFIG_PAGE_TRACING + if (likely(page)) { + int order = get_order(nc->size); + int i; + struct page *newpage = page; + unsigned int deta = 1U << (unsigned int)order; + + for (i = 0; i < (1 << order); i++) { + if (!newpage) + break; + SetPageSKB(newpage); + newpage++; + } + mod_zone_page_state(page_zone(page), NR_SKB_PAGES, (long)deta); + } +#endif return page; } @@ -4645,8 +4661,15 @@ void __page_frag_cache_drain(struct page *page, unsigned int count) { VM_BUG_ON_PAGE(page_ref_count(page) == 0, page); - if (page_ref_sub_and_test(page, count)) + if (page_ref_sub_and_test(page, count)) { +#ifdef CONFIG_PAGE_TRACING + if (likely(page)) { + unsigned int deta = 1U << compound_order(page); + mod_zone_page_state(page_zone(page), NR_SKB_PAGES, -(long)deta); + } +#endif free_the_page(page, compound_order(page)); + } } EXPORT_SYMBOL(__page_frag_cache_drain); @@ -4730,8 +4753,15 @@ void page_frag_free(void *addr) { struct page *page = virt_to_head_page(addr); - if (unlikely(put_page_testzero(page))) + if (unlikely(put_page_testzero(page))) { +#ifdef CONFIG_PAGE_TRACING + if (likely(page)) { + unsigned int deta = 1U << compound_order(page); + mod_zone_page_state(page_zone(page), NR_SKB_PAGES, -(long)deta); + } +#endif free_the_page(page, compound_order(page)); + } } EXPORT_SYMBOL(page_frag_free); diff --git a/mm/vmstat.c b/mm/vmstat.c index 3d8ffcc4072a..9a3e746e1f69 100644 --- a/mm/vmstat.c +++ b/mm/vmstat.c @@ -1187,7 +1187,9 @@ const char * const vmstat_text[] = { #ifdef CONFIG_UNACCEPTED_MEMORY "nr_unaccepted", #endif - +#ifdef CONFIG_PAGE_TRACING + "nr_skb_pages", +#endif /* enum numa_stat_item counters */ #ifdef CONFIG_NUMA "numa_hit", diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c index c82070167d8a..cb2c39647826 100644 --- a/mm/zsmalloc.c +++ b/mm/zsmalloc.c @@ -1008,6 +1008,9 @@ static struct zspage *alloc_zspage(struct zs_pool *pool, } inc_zone_page_state(page, NR_ZSPAGES); +#ifdef CONFIG_PAGE_TRACING + SetPageZspage(page); +#endif pages[i] = page; } -- Gitee