18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * mm/lmkd_dbg_trigger.c 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (c) 2020-2022 Huawei Technologies Co., Ltd. 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci#include <linux/atomic.h> 88c2ecf20Sopenharmony_ci#include <linux/fs.h> 98c2ecf20Sopenharmony_ci#include <linux/init.h> 108c2ecf20Sopenharmony_ci#include <linux/kernel.h> 118c2ecf20Sopenharmony_ci#include <linux/module.h> 128c2ecf20Sopenharmony_ci#include <linux/oom.h> 138c2ecf20Sopenharmony_ci#include <linux/proc_fs.h> 148c2ecf20Sopenharmony_ci#include <linux/seq_file.h> 158c2ecf20Sopenharmony_ci#include <linux/uaccess.h> 168c2ecf20Sopenharmony_ci#include <linux/lowmem_dbg.h> 178c2ecf20Sopenharmony_ci#define PROC_NUMBUF 8 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_cistatic int lmkd_oom_score_adj; 208c2ecf20Sopenharmony_cistatic atomic64_t lmkd_no_cma_cnt = ATOMIC64_INIT(0); 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_cistatic int lmkd_dbg_trigger_proc_show(struct seq_file *m, void *v) 238c2ecf20Sopenharmony_ci{ 248c2ecf20Sopenharmony_ci seq_printf(m, "lmkd_oom_score_adj: %d\n", lmkd_oom_score_adj); 258c2ecf20Sopenharmony_ci seq_printf(m, "lmkd_no_cma_cnt: %lld\n", 268c2ecf20Sopenharmony_ci atomic64_read(&lmkd_no_cma_cnt)); 278c2ecf20Sopenharmony_ci return 0; 288c2ecf20Sopenharmony_ci} 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_cistatic int lmkd_dbg_trigger_proc_open(struct inode *inode, struct file *file) 318c2ecf20Sopenharmony_ci{ 328c2ecf20Sopenharmony_ci return single_open(file, lmkd_dbg_trigger_proc_show, NULL); 338c2ecf20Sopenharmony_ci} 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_cistatic ssize_t lmkd_dbg_trigger_write(struct file *file, const char __user *buf, 368c2ecf20Sopenharmony_ci size_t count, loff_t *ppos) 378c2ecf20Sopenharmony_ci{ 388c2ecf20Sopenharmony_ci char buffer[PROC_NUMBUF]; 398c2ecf20Sopenharmony_ci int oom_score_adj; 408c2ecf20Sopenharmony_ci int err; 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci memset(buffer, 0, sizeof(buffer)); 438c2ecf20Sopenharmony_ci if (count > sizeof(buffer) - 1) 448c2ecf20Sopenharmony_ci count = sizeof(buffer) - 1; 458c2ecf20Sopenharmony_ci if (copy_from_user(buffer, buf, count)) { 468c2ecf20Sopenharmony_ci err = -EFAULT; 478c2ecf20Sopenharmony_ci goto out; 488c2ecf20Sopenharmony_ci } 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci err = kstrtoint(strstrip(buffer), 0, &oom_score_adj); 518c2ecf20Sopenharmony_ci if (err) 528c2ecf20Sopenharmony_ci goto out; 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ci if (oom_score_adj < OOM_SCORE_ADJ_MIN || 558c2ecf20Sopenharmony_ci oom_score_adj > OOM_SCORE_ADJ_MAX) { 568c2ecf20Sopenharmony_ci err = -EINVAL; 578c2ecf20Sopenharmony_ci goto out; 588c2ecf20Sopenharmony_ci } 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_ci lmkd_oom_score_adj = oom_score_adj; 618c2ecf20Sopenharmony_ci lowmem_dbg(oom_score_adj); 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ciout: 648c2ecf20Sopenharmony_ci return err < 0 ? err : count; 658c2ecf20Sopenharmony_ci} 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_cistatic const struct proc_ops lmkd_dbg_trigger_proc_fops = { 688c2ecf20Sopenharmony_ci .proc_open = lmkd_dbg_trigger_proc_open, 698c2ecf20Sopenharmony_ci .proc_read = seq_read, 708c2ecf20Sopenharmony_ci .proc_lseek = seq_lseek, 718c2ecf20Sopenharmony_ci .proc_release = single_release, 728c2ecf20Sopenharmony_ci .proc_write = lmkd_dbg_trigger_write, 738c2ecf20Sopenharmony_ci}; 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_cistatic int __init proc_lmkd_dbg_trigger_init(void) 768c2ecf20Sopenharmony_ci{ 778c2ecf20Sopenharmony_ci proc_create("lmkd_dbg_trigger", 0660, NULL, 788c2ecf20Sopenharmony_ci &lmkd_dbg_trigger_proc_fops); 798c2ecf20Sopenharmony_ci return 0; 808c2ecf20Sopenharmony_ci} 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_cifs_initcall(proc_lmkd_dbg_trigger_init); 838c2ecf20Sopenharmony_ci 84