提交 de0b4009 编写于 作者: L liubo 提交者: Zheng Zengkai

memig: add memig-swap feature to openEuler

euleros inclusion
category: feature
feature: add memig swap feature patch to openEuler kernel
bugzilla: 48246

-------------------------------------------------

reason:This patch is used to add memig swap feature to openEuler system.
memig_swap.ko is used to transfer the address
passed in the user state for page migration
Signed-off-by: Nyanxiaodan <yanxiaodan@huawei.com>
Signed-off-by: Nlinmiaohe <linmiaohe@huawei.com>
Signed-off-by: Nlouhongxiang <louhongxiang@huawei.com>
Signed-off-by: Nliubo <liubo254@huawei.com>
Signed-off-by: Ngeruijun <geruijun@huawei.com>
Signed-off-by: Nliangchenshu <liangchenshu@huawei.com>
Reviewed-by: NJing Xiangfeng <jingxiangfeng@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 f10ba9e3
...@@ -7098,3 +7098,4 @@ CONFIG_CC_HAS_SANCOV_TRACE_PC=y ...@@ -7098,3 +7098,4 @@ CONFIG_CC_HAS_SANCOV_TRACE_PC=y
# end of Kernel Testing and Coverage # end of Kernel Testing and Coverage
# end of Kernel hacking # end of Kernel hacking
CONFIG_MEMIG_SCAN_MODULE=m CONFIG_MEMIG_SCAN_MODULE=m
CONFIG_MEMIG_SWAP_MODULE=m
...@@ -8490,3 +8490,4 @@ CONFIG_ARCH_HAS_KCOV=y ...@@ -8490,3 +8490,4 @@ CONFIG_ARCH_HAS_KCOV=y
# end of Kernel Testing and Coverage # end of Kernel Testing and Coverage
# end of Kernel hacking # end of Kernel hacking
CONFIG_MEMIG_SCAN_MODULE=m CONFIG_MEMIG_SCAN_MODULE=m
CONFIG_MEMIG_SWAP_MODULE=m
...@@ -35,3 +35,4 @@ proc-$(CONFIG_PRINTK) += kmsg.o ...@@ -35,3 +35,4 @@ proc-$(CONFIG_PRINTK) += kmsg.o
proc-$(CONFIG_PROC_PAGE_MONITOR) += page.o proc-$(CONFIG_PROC_PAGE_MONITOR) += page.o
proc-$(CONFIG_BOOT_CONFIG) += bootconfig.o proc-$(CONFIG_BOOT_CONFIG) += bootconfig.o
obj-$(CONFIG_MEMIG_SCAN_MODULE) += memig_scan.o obj-$(CONFIG_MEMIG_SCAN_MODULE) += memig_scan.o
obj-$(CONFIG_MEMIG_SWAP_MODULE) += memig_swap.o
...@@ -3219,6 +3219,7 @@ static const struct pid_entry tgid_base_stuff[] = { ...@@ -3219,6 +3219,7 @@ static const struct pid_entry tgid_base_stuff[] = {
REG("smaps_rollup", S_IRUGO, proc_pid_smaps_rollup_operations), REG("smaps_rollup", S_IRUGO, proc_pid_smaps_rollup_operations),
REG("pagemap", S_IRUSR, proc_pagemap_operations), REG("pagemap", S_IRUSR, proc_pagemap_operations),
REG("idle_pages", S_IRUSR|S_IWUSR, proc_mm_idle_operations), REG("idle_pages", S_IRUSR|S_IWUSR, proc_mm_idle_operations),
REG("swap_pages", S_IWUSR, proc_mm_swap_operations),
#endif #endif
#ifdef CONFIG_SECURITY #ifdef CONFIG_SECURITY
DIR("attr", S_IRUGO|S_IXUGO, proc_attr_dir_inode_operations, proc_attr_dir_operations), DIR("attr", S_IRUGO|S_IXUGO, proc_attr_dir_inode_operations, proc_attr_dir_operations),
...@@ -3559,6 +3560,7 @@ static const struct pid_entry tid_base_stuff[] = { ...@@ -3559,6 +3560,7 @@ static const struct pid_entry tid_base_stuff[] = {
REG("smaps_rollup", S_IRUGO, proc_pid_smaps_rollup_operations), REG("smaps_rollup", S_IRUGO, proc_pid_smaps_rollup_operations),
REG("pagemap", S_IRUSR, proc_pagemap_operations), REG("pagemap", S_IRUSR, proc_pagemap_operations),
REG("idle_pages", S_IRUSR|S_IWUSR, proc_mm_idle_operations), REG("idle_pages", S_IRUSR|S_IWUSR, proc_mm_idle_operations),
REG("swap_pages", S_IWUSR, proc_mm_swap_operations),
#endif #endif
#ifdef CONFIG_SECURITY #ifdef CONFIG_SECURITY
DIR("attr", S_IRUGO|S_IXUGO, proc_attr_dir_inode_operations, proc_attr_dir_operations), DIR("attr", S_IRUGO|S_IXUGO, proc_attr_dir_inode_operations, proc_attr_dir_operations),
......
...@@ -305,6 +305,7 @@ extern const struct file_operations proc_pid_smaps_rollup_operations; ...@@ -305,6 +305,7 @@ extern const struct file_operations proc_pid_smaps_rollup_operations;
extern const struct file_operations proc_clear_refs_operations; extern const struct file_operations proc_clear_refs_operations;
extern const struct file_operations proc_pagemap_operations; extern const struct file_operations proc_pagemap_operations;
extern const struct file_operations proc_mm_idle_operations; extern const struct file_operations proc_mm_idle_operations;
extern const struct file_operations proc_mm_swap_operations;
extern unsigned long task_vsize(struct mm_struct *); extern unsigned long task_vsize(struct mm_struct *);
extern unsigned long task_statm(struct mm_struct *, extern unsigned long task_statm(struct mm_struct *,
......
// SPDX-License-Identifier: GPL-2.0
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/proc_fs.h>
#include <linux/sched/mm.h>
#include <linux/mm.h>
#include <linux/swap.h>
#include <linux/mempolicy.h>
#include <linux/uaccess.h>
#include <linux/delay.h>
static ssize_t swap_pages_write(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
char *p, *data, *data_ptr_res;
unsigned long vaddr;
struct mm_struct *mm = file->private_data;
struct page *page;
LIST_HEAD(pagelist);
int ret = 0;
if (!mm || !mmget_not_zero(mm)) {
ret = -ESRCH;
goto out;
}
if (count < 0) {
ret = -EOPNOTSUPP;
goto out_mm;
}
data = memdup_user_nul(buf, count);
if (IS_ERR(data)) {
ret = PTR_ERR(data);
goto out_mm;
}
data_ptr_res = data;
while ((p = strsep(&data, "\n")) != NULL) {
if (!*p)
continue;
ret = kstrtoul(p, 16, &vaddr);
if (ret != 0)
continue;
/*If get page struct failed, ignore it, get next page*/
page = get_page_from_vaddr(mm, vaddr);
if (!page)
continue;
add_page_for_swap(page, &pagelist);
}
if (!list_empty(&pagelist))
reclaim_pages(&pagelist);
ret = count;
kfree(data_ptr_res);
out_mm:
mmput(mm);
out:
return ret;
}
static int swap_pages_open(struct inode *inode, struct file *file)
{
if (!try_module_get(THIS_MODULE))
return -EBUSY;
return 0;
}
static int swap_pages_release(struct inode *inode, struct file *file)
{
module_put(THIS_MODULE);
return 0;
}
extern struct file_operations proc_swap_pages_operations;
static int swap_pages_entry(void)
{
proc_swap_pages_operations.owner = THIS_MODULE;
proc_swap_pages_operations.write = swap_pages_write;
proc_swap_pages_operations.open = swap_pages_open;
proc_swap_pages_operations.release = swap_pages_release;
return 0;
}
static void swap_pages_exit(void)
{
memset(&proc_swap_pages_operations, 0,
sizeof(proc_swap_pages_operations));
}
MODULE_LICENSE("GPL");
module_init(swap_pages_entry);
module_exit(swap_pages_exit);
...@@ -1752,7 +1752,58 @@ const struct file_operations proc_mm_idle_operations = { ...@@ -1752,7 +1752,58 @@ const struct file_operations proc_mm_idle_operations = {
.release = mm_idle_release, .release = mm_idle_release,
}; };
/*swap pages*/
struct file_operations proc_swap_pages_operations = {
};
EXPORT_SYMBOL_GPL(proc_swap_pages_operations);
static ssize_t mm_swap_write(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
if (proc_swap_pages_operations.write)
return proc_swap_pages_operations.write(file, buf, count, ppos);
return -1;
}
static int mm_swap_open(struct inode *inode, struct file *file)
{
struct mm_struct *mm = NULL;
if (!file_ns_capable(file, &init_user_ns, CAP_SYS_ADMIN))
return -EPERM;
mm = proc_mem_open(inode, PTRACE_MODE_READ);
if (IS_ERR(mm))
return PTR_ERR(mm);
file->private_data = mm;
if (proc_swap_pages_operations.open)
return proc_swap_pages_operations.open(inode, file);
return 0;
}
static int mm_swap_release(struct inode *inode, struct file *file)
{
struct mm_struct *mm = file->private_data;
if (mm)
mmdrop(mm);
if (proc_swap_pages_operations.release)
return proc_swap_pages_operations.release(inode, file);
return 0;
}
const struct file_operations proc_mm_swap_operations = {
.llseek = mem_lseek,
.write = mm_swap_write,
.open = mm_swap_open,
.release = mm_swap_release,
};
#endif /* CONFIG_PROC_PAGE_MONITOR */ #endif /* CONFIG_PROC_PAGE_MONITOR */
#ifdef CONFIG_NUMA #ifdef CONFIG_NUMA
......
...@@ -372,6 +372,9 @@ extern int vm_swappiness; ...@@ -372,6 +372,9 @@ extern int vm_swappiness;
extern int remove_mapping(struct address_space *mapping, struct page *page); extern int remove_mapping(struct address_space *mapping, struct page *page);
extern unsigned long reclaim_pages(struct list_head *page_list); extern unsigned long reclaim_pages(struct list_head *page_list);
extern int add_page_for_swap(struct page *page, struct list_head *pagelist);
extern struct page *get_page_from_vaddr(struct mm_struct *mm,
unsigned long vaddr);
#ifdef CONFIG_NUMA #ifdef CONFIG_NUMA
extern int node_reclaim_mode; extern int node_reclaim_mode;
extern int sysctl_min_unmapped_ratio; extern int sysctl_min_unmapped_ratio;
......
...@@ -666,6 +666,11 @@ config MEMIG_SCAN_MODULE ...@@ -666,6 +666,11 @@ config MEMIG_SCAN_MODULE
memig page scan feature memig page scan feature
used to scan the virtual address of the target process used to scan the virtual address of the target process
config MEMIG_SWAP_MODULE
tristate "module: memig page swap for memig support"
help
memig page swap feature
config STRING_SELFTEST config STRING_SELFTEST
tristate "Test string functions" tristate "Test string functions"
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include <linux/topology.h> #include <linux/topology.h>
#include <linux/cpu.h> #include <linux/cpu.h>
#include <linux/cpuset.h> #include <linux/cpuset.h>
#include <linux/mempolicy.h>
#include <linux/compaction.h> #include <linux/compaction.h>
#include <linux/notifier.h> #include <linux/notifier.h>
#include <linux/rwsem.h> #include <linux/rwsem.h>
...@@ -2154,6 +2155,7 @@ unsigned long reclaim_pages(struct list_head *page_list) ...@@ -2154,6 +2155,7 @@ unsigned long reclaim_pages(struct list_head *page_list)
return nr_reclaimed; return nr_reclaimed;
} }
EXPORT_SYMBOL_GPL(reclaim_pages);
static unsigned long shrink_list(enum lru_list lru, unsigned long nr_to_scan, static unsigned long shrink_list(enum lru_list lru, unsigned long nr_to_scan,
struct lruvec *lruvec, struct scan_control *sc) struct lruvec *lruvec, struct scan_control *sc)
...@@ -4306,3 +4308,58 @@ void check_move_unevictable_pages(struct pagevec *pvec) ...@@ -4306,3 +4308,58 @@ void check_move_unevictable_pages(struct pagevec *pvec)
} }
} }
EXPORT_SYMBOL_GPL(check_move_unevictable_pages); EXPORT_SYMBOL_GPL(check_move_unevictable_pages);
int add_page_for_swap(struct page *page, struct list_head *pagelist)
{
int err = -EBUSY;
struct page *head;
/*If the page is mapped by more than one process, do not swap it */
if (page_mapcount(page) > 1)
return -EACCES;
if (PageHuge(page))
return -EACCES;
head = compound_head(page);
err = isolate_lru_page(head);
if (err) {
put_page(page);
return err;
}
put_page(page);
if (PageUnevictable(page))
putback_lru_page(page);
else
list_add_tail(&head->lru, pagelist);
err = 0;
return err;
}
EXPORT_SYMBOL_GPL(add_page_for_swap);
struct page *get_page_from_vaddr(struct mm_struct *mm, unsigned long vaddr)
{
struct page *page;
struct vm_area_struct *vma;
unsigned int follflags;
down_read(&mm->mmap_lock);
vma = find_vma(mm, vaddr);
if (!vma || vaddr < vma->vm_start || !vma_migratable(vma)) {
up_read(&mm->mmap_lock);
return NULL;
}
follflags = FOLL_GET | FOLL_DUMP;
page = follow_page(vma, vaddr, follflags);
if (IS_ERR(page) || !page) {
up_read(&mm->mmap_lock);
return NULL;
}
up_read(&mm->mmap_lock);
return page;
}
EXPORT_SYMBOL_GPL(get_page_from_vaddr);
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册