From 6c3e3d0e46660e391d4fd5e107a1d5b992958436 Mon Sep 17 00:00:00 2001 From: lk_hauwei Date: Sun, 8 May 2022 16:16:52 +0800 Subject: [PATCH 1/3] Add lowmem killer debug info ohos inclusion category: feature issue: #I569HG CVE: NA -------------------------------- For lmkd to trigger in-kernel lowmem info dump Signed-off-by: lk_hauwei --- include/linux/lowmem_dbg.h | 16 +++++ mm/Kconfig | 14 +++++ mm/Makefile | 2 + mm/lmkd_dbg_trigger.c | 93 +++++++++++++++++++++++++++ mm/lowmem_dbg.c | 125 +++++++++++++++++++++++++++++++++++++ 5 files changed, 250 insertions(+) create mode 100644 include/linux/lowmem_dbg.h create mode 100644 mm/lmkd_dbg_trigger.c create mode 100644 mm/lowmem_dbg.c diff --git a/include/linux/lowmem_dbg.h b/include/linux/lowmem_dbg.h new file mode 100644 index 000000000000..be459bd18603 --- /dev/null +++ b/include/linux/lowmem_dbg.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * include/linux/lowmem_dbg.h + * + * Copyright (c) 2020-2022 Huawei Technologies Co., Ltd. + */ +#ifndef __LMK_DBG_H +#define __LMK_DBG_H + +#ifdef CONFIG_LOWMEM +void lowmem_dbg(short oom_score_adj); +#else +static inline void lowmem_dbg(short oom_score_adj) {} +#endif +#endif + diff --git a/mm/Kconfig b/mm/Kconfig index 11f2f83389e5..2acd0e298db6 100644 --- a/mm/Kconfig +++ b/mm/Kconfig @@ -1263,6 +1263,20 @@ config ANON_VMA_NAME Assigning a name to anonymous virtual memory area might prevent that area from being merged with adjacent virtual memory areas due to the difference in their name. +# +# For lmkd to trigger in-kernel lowmem info +# +config LOWMEM + bool "Low Memory Killer" + default n + help + Enables lowmem killer parameter tuning + +config LMKD_DBG + bool "Low Memory Killer Debug" + default n + help + print processes info when lmk happen per several seconds config USERFAULTFD bool "Enable userfaultfd() system call" diff --git a/mm/Makefile b/mm/Makefile index 94ea4fb43163..2aaf330799e6 100644 --- a/mm/Makefile +++ b/mm/Makefile @@ -71,6 +71,8 @@ ifdef CONFIG_MMU obj-$(CONFIG_ADVISE_SYSCALLS) += madvise.o endif +obj-$(CONFIG_LMKD_DBG) += lmkd_dbg_trigger.o +obj-$(CONFIG_LOWMEM) += lowmem_dbg.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/lmkd_dbg_trigger.c b/mm/lmkd_dbg_trigger.c new file mode 100644 index 000000000000..e845b14f5f02 --- /dev/null +++ b/mm/lmkd_dbg_trigger.c @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * mm/lmkd_dbg_trigger.c + * + * Copyright (c) 2020-2022 Huawei Technologies Co., Ltd. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define PROC_NUMBUF 8 + +static int lmkd_oom_score_adj; +static atomic64_t lmkd_no_cma_cnt = ATOMIC64_INIT(0); + +void lmkd_inc_no_cma_cnt(void) +{ + atomic64_inc(&lmkd_no_cma_cnt); +} + +void lmkd_dec_no_cma_cnt(void) +{ + atomic64_dec(&lmkd_no_cma_cnt); +} + +static int lmkd_dbg_trigger_proc_show(struct seq_file *m, void *v) +{ + seq_printf(m, "lmkd_oom_score_adj: %d\n", lmkd_oom_score_adj); + seq_printf(m, "lmkd_no_cma_cnt: %lld\n", + atomic64_read(&lmkd_no_cma_cnt)); + return 0; +} + +static int lmkd_dbg_trigger_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, lmkd_dbg_trigger_proc_show, NULL); +} + +static ssize_t lmkd_dbg_trigger_write(struct file *file, const char __user *buf, + size_t count, loff_t *ppos) +{ + char buffer[PROC_NUMBUF]; + int oom_score_adj; + int err; + + memset(buffer, 0, sizeof(buffer)); + if (count > sizeof(buffer) - 1) + count = sizeof(buffer) - 1; + if (copy_from_user(buffer, buf, count)) { + err = -EFAULT; + goto out; + } + + err = kstrtoint(strstrip(buffer), 0, &oom_score_adj); + if (err) + goto out; + + if (oom_score_adj < OOM_SCORE_ADJ_MIN || + oom_score_adj > OOM_SCORE_ADJ_MAX) { + err = -EINVAL; + goto out; + } + + lmkd_oom_score_adj = oom_score_adj; + lowmem_dbg(oom_score_adj); + +out: + return err < 0 ? err : count; +} + +static const struct proc_ops lmkd_dbg_trigger_proc_fops = { + .proc_open = lmkd_dbg_trigger_proc_open, + .proc_read = seq_read, + .proc_lseek = seq_lseek, + .proc_release = single_release, + .proc_write = lmkd_dbg_trigger_write, +}; + +static int __init proc_lmkd_dbg_trigger_init(void) +{ + proc_create("lmkd_dbg_trigger", 0660, NULL, + &lmkd_dbg_trigger_proc_fops); + return 0; +} + +fs_initcall(proc_lmkd_dbg_trigger_init); + diff --git a/mm/lowmem_dbg.c b/mm/lowmem_dbg.c new file mode 100644 index 000000000000..fc548ce78fd2 --- /dev/null +++ b/mm/lowmem_dbg.c @@ -0,0 +1,125 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * mm/lowmem_dbg.c + * + * Copyright (c) 2020-2022 Huawei Technologies Co., Ltd. + */ +#define pr_fmt(fmt) "lowmem:" fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define LMK_PRT_TSK_RSS 10000 +#define LMK_INTERVAL 3 + +/* SERVICE_ADJ(5) * OOM_SCORE_ADJ_MAX / -OOM_DISABLE */ +#define LMK_SERVICE_ADJ 500 +/* defiine TASK STATE String */ +#define TASK_STATE_TO_CHAR_STR "RSDTtXZxKWPNn" + +static unsigned long long last_jiffs; +static const char state_to_char[] = TASK_STATE_TO_CHAR_STR; +static void lowmem_dump(struct work_struct *work); + +static DEFINE_MUTEX(lowmem_dump_mutex); +static DECLARE_WORK(lowmem_dbg_wk, lowmem_dump); +static DECLARE_WORK(lowmem_dbg_verbose_wk, lowmem_dump); + +static int task_state_char(unsigned long state) +{ + int bit = state ? __ffs(state) + 1 : 0; + + return bit < sizeof(state_to_char) - 1 ? state_to_char[bit] : '?'; +} + +static void tasks_dump(bool verbose) +{ + struct task_struct *p = NULL; + struct task_struct *task = NULL; + short tsk_oom_adj = 0; + unsigned long tsk_nr_ptes = 0; + char frozen_mark = ' '; + + pr_info("[ pid ] uid tgid total_vm rss nptes swap adj s name\n"); + + rcu_read_lock(); + for_each_process(p) { + task = find_lock_task_mm(p); + if (!task) { + /* + * This is a kthread or all of p's threads have already + * detached their mm's. There's no need to report + * them; they can't be oom killed anyway. + */ + continue; + } + + tsk_oom_adj = task->signal->oom_score_adj; + if (!verbose && tsk_oom_adj && + (tsk_oom_adj <= LMK_SERVICE_ADJ) && + (get_mm_rss(task->mm) < LMK_PRT_TSK_RSS)) { + task_unlock(task); + continue; + } + + tsk_nr_ptes = mm_pgtables_bytes(task->mm); + + frozen_mark = frozen(task) ? '*' : ' '; + + pr_info("[%5d] %5d %5d %8lu %6lu %5lu %5lu %5hd %c %s%c\n", + task->pid, from_kuid(&init_user_ns, task_uid(task)), + task->tgid, task->mm->total_vm, get_mm_rss(task->mm), + tsk_nr_ptes, + get_mm_counter(task->mm, MM_SWAPENTS), + tsk_oom_adj, + task_state_char(task->state), + task->comm, + frozen_mark); /*lint !e1058*/ + task_unlock(task); + } + rcu_read_unlock(); +} + +static void lowmem_dump(struct work_struct *work) +{ + bool verbose = (work == &lowmem_dbg_verbose_wk) ? true : false; + + mutex_lock(&lowmem_dump_mutex); +#if defined(SHOW_MEM_FILTER_PAGE_COUNT) + show_mem(SHOW_MEM_FILTER_NODES | + (verbose ? 0 : SHOW_MEM_FILTER_PAGE_COUNT)); +#else + show_mem(SHOW_MEM_FILTER_NODES, NULL); +#endif + tasks_dump(verbose); + mutex_unlock(&lowmem_dump_mutex); +} + +void lowmem_dbg(short oom_score_adj) +{ + unsigned long long jiffs = get_jiffies_64(); + + if (oom_score_adj == 0) { + schedule_work(&lowmem_dbg_verbose_wk); + } else if (time_after64(jiffs, (last_jiffs + LMK_INTERVAL * HZ))) { + last_jiffs = get_jiffies_64(); + schedule_work(&lowmem_dbg_wk); + } +} + -- Gitee From cbcfd09eae5aafe7a4c48d07252d06592762d1c6 Mon Sep 17 00:00:00 2001 From: rlfeng Date: Thu, 11 Sep 2025 01:58:22 +0000 Subject: [PATCH 2/3] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6=20incl?= =?UTF-8?q?ude/linux/lowmem=5Fdbg.h?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/linux/lowmem_dbg.h | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 include/linux/lowmem_dbg.h diff --git a/include/linux/lowmem_dbg.h b/include/linux/lowmem_dbg.h deleted file mode 100644 index be459bd18603..000000000000 --- a/include/linux/lowmem_dbg.h +++ /dev/null @@ -1,16 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * include/linux/lowmem_dbg.h - * - * Copyright (c) 2020-2022 Huawei Technologies Co., Ltd. - */ -#ifndef __LMK_DBG_H -#define __LMK_DBG_H - -#ifdef CONFIG_LOWMEM -void lowmem_dbg(short oom_score_adj); -#else -static inline void lowmem_dbg(short oom_score_adj) {} -#endif -#endif - -- Gitee From cbd268af4d86efefabc888db88caed09d158c045 Mon Sep 17 00:00:00 2001 From: rlfeng Date: Thu, 11 Sep 2025 11:16:42 +0800 Subject: [PATCH 3/3] mm --- mm/lmkd_dbg_trigger.c | 11 ----------- mm/lowmem_dbg.c | 30 +++++++----------------------- 2 files changed, 7 insertions(+), 34 deletions(-) diff --git a/mm/lmkd_dbg_trigger.c b/mm/lmkd_dbg_trigger.c index e845b14f5f02..1ebc3418bb2c 100644 --- a/mm/lmkd_dbg_trigger.c +++ b/mm/lmkd_dbg_trigger.c @@ -19,16 +19,6 @@ static int lmkd_oom_score_adj; static atomic64_t lmkd_no_cma_cnt = ATOMIC64_INIT(0); -void lmkd_inc_no_cma_cnt(void) -{ - atomic64_inc(&lmkd_no_cma_cnt); -} - -void lmkd_dec_no_cma_cnt(void) -{ - atomic64_dec(&lmkd_no_cma_cnt); -} - static int lmkd_dbg_trigger_proc_show(struct seq_file *m, void *v) { seq_printf(m, "lmkd_oom_score_adj: %d\n", lmkd_oom_score_adj); @@ -90,4 +80,3 @@ static int __init proc_lmkd_dbg_trigger_init(void) } fs_initcall(proc_lmkd_dbg_trigger_init); - diff --git a/mm/lowmem_dbg.c b/mm/lowmem_dbg.c index fc548ce78fd2..6262f4bf3df6 100644 --- a/mm/lowmem_dbg.c +++ b/mm/lowmem_dbg.c @@ -6,30 +6,21 @@ */ #define pr_fmt(fmt) "lowmem:" fmt -#include -#include #include #include -#include #include -#include #include -#include -#include -#include #include #include #include -#include -#include -#include #include +#include "internal.h" -#define LMK_PRT_TSK_RSS 10000 -#define LMK_INTERVAL 3 +#define LMK_PRT_TSK_RSS 0 +#define LMK_INTERVAL 15 /* SERVICE_ADJ(5) * OOM_SCORE_ADJ_MAX / -OOM_DISABLE */ -#define LMK_SERVICE_ADJ 500 +#define LMK_SERVICE_ADJ 1000 /* defiine TASK STATE String */ #define TASK_STATE_TO_CHAR_STR "RSDTtXZxKWPNn" @@ -38,7 +29,6 @@ static const char state_to_char[] = TASK_STATE_TO_CHAR_STR; static void lowmem_dump(struct work_struct *work); static DEFINE_MUTEX(lowmem_dump_mutex); -static DECLARE_WORK(lowmem_dbg_wk, lowmem_dump); static DECLARE_WORK(lowmem_dbg_verbose_wk, lowmem_dump); static int task_state_char(unsigned long state) @@ -88,7 +78,7 @@ static void tasks_dump(bool verbose) tsk_nr_ptes, get_mm_counter(task->mm, MM_SWAPENTS), tsk_oom_adj, - task_state_char(task->state), + task_state_char(task->__state), task->comm, frozen_mark); /*lint !e1058*/ task_unlock(task); @@ -101,12 +91,7 @@ static void lowmem_dump(struct work_struct *work) bool verbose = (work == &lowmem_dbg_verbose_wk) ? true : false; mutex_lock(&lowmem_dump_mutex); -#if defined(SHOW_MEM_FILTER_PAGE_COUNT) - show_mem(SHOW_MEM_FILTER_NODES | - (verbose ? 0 : SHOW_MEM_FILTER_PAGE_COUNT)); -#else - show_mem(SHOW_MEM_FILTER_NODES, NULL); -#endif + show_mem(); tasks_dump(verbose); mutex_unlock(&lowmem_dump_mutex); } @@ -119,7 +104,6 @@ void lowmem_dbg(short oom_score_adj) schedule_work(&lowmem_dbg_verbose_wk); } else if (time_after64(jiffs, (last_jiffs + LMK_INTERVAL * HZ))) { last_jiffs = get_jiffies_64(); - schedule_work(&lowmem_dbg_wk); + schedule_work(&lowmem_dbg_verbose_wk); } } - -- Gitee