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

memig: add memig-scan feature to openEuler

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

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

reason:This patch is used to add memig scan feature to openEuler system.
memig_scan.ko is used to scan the virtual address of the target process
and return the address access information to
the user mode for grading cold and hot pages.
Signed-off-by: NFengguang Wu <fengguang.wu@intel.com>
Signed-off-by: Nyanxiaodan <yanxiaodan@huawei.com>
Signed-off-by: NFeilong Lin <linfeilong@huawei.com>
Signed-off-by: Ngeruijun <geruijun@huawei.com>
Signed-off-by: Nliubo <liubo254@huawei.com>
Reviewed-by: NJing Xiangfeng <jingxiangfeng@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 efd5d632
......@@ -7098,3 +7098,4 @@ CONFIG_CC_HAS_SANCOV_TRACE_PC=y
CONFIG_MPAM=y
CONFIG_RESCTRL=y
CONFIG_ACPI_MPAM=y
CONFIG_MEMIG_SCAN_MODULE=m
......@@ -8489,3 +8489,4 @@ CONFIG_ARCH_HAS_KCOV=y
# CONFIG_HYPERV_TESTING is not set
# end of Kernel Testing and Coverage
# end of Kernel hacking
CONFIG_MEMIG_SCAN_MODULE=m
......@@ -34,3 +34,4 @@ proc-$(CONFIG_PROC_VMCORE) += vmcore.o
proc-$(CONFIG_PRINTK) += kmsg.o
proc-$(CONFIG_PROC_PAGE_MONITOR) += page.o
proc-$(CONFIG_BOOT_CONFIG) += bootconfig.o
obj-$(CONFIG_MEMIG_SCAN_MODULE) += memig_scan.o
......@@ -3218,6 +3218,7 @@ static const struct pid_entry tgid_base_stuff[] = {
REG("smaps", S_IRUGO, proc_pid_smaps_operations),
REG("smaps_rollup", S_IRUGO, proc_pid_smaps_rollup_operations),
REG("pagemap", S_IRUSR, proc_pagemap_operations),
REG("idle_pages", S_IRUSR|S_IWUSR, proc_mm_idle_operations),
#endif
#ifdef CONFIG_SECURITY
DIR("attr", S_IRUGO|S_IXUGO, proc_attr_dir_inode_operations, proc_attr_dir_operations),
......@@ -3557,6 +3558,7 @@ static const struct pid_entry tid_base_stuff[] = {
REG("smaps", S_IRUGO, proc_pid_smaps_operations),
REG("smaps_rollup", S_IRUGO, proc_pid_smaps_rollup_operations),
REG("pagemap", S_IRUSR, proc_pagemap_operations),
REG("idle_pages", S_IRUSR|S_IWUSR, proc_mm_idle_operations),
#endif
#ifdef CONFIG_SECURITY
DIR("attr", S_IRUGO|S_IXUGO, proc_attr_dir_inode_operations, proc_attr_dir_operations),
......
......@@ -304,6 +304,7 @@ extern const struct file_operations proc_pid_smaps_operations;
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_pagemap_operations;
extern const struct file_operations proc_mm_idle_operations;
extern unsigned long task_vsize(struct mm_struct *);
extern unsigned long task_statm(struct mm_struct *,
......
此差异已折叠。
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _PAGE_IDLE_H
#define _PAGE_IDLE_H
#define SCAN_HUGE_PAGE O_NONBLOCK /* only huge page */
#define SCAN_SKIM_IDLE O_NOFOLLOW /* stop on PMD_IDLE_PTES */
#define SCAN_DIRTY_PAGE O_NOATIME /* report pte/pmd dirty bit */
enum ProcIdlePageType {
PTE_ACCESSED, /* 4k page */
PMD_ACCESSED, /* 2M page */
PUD_PRESENT, /* 1G page */
PTE_DIRTY_M,
PMD_DIRTY_M,
PTE_IDLE,
PMD_IDLE,
PMD_IDLE_PTES, /* all PTE idle */
PTE_HOLE,
PMD_HOLE,
PIP_CMD,
IDLE_PAGE_TYPE_MAX
};
#define PIP_TYPE(a) (0xf & (a >> 4))
#define PIP_SIZE(a) (0xf & a)
#define PIP_COMPOSE(type, nr) ((type << 4) | nr)
#define PIP_CMD_SET_HVA PIP_COMPOSE(PIP_CMD, 0)
#ifndef INVALID_PAGE
#define INVALID_PAGE ~0UL
#endif
#ifdef CONFIG_ARM64
#define _PAGE_MM_BIT_ACCESSED 10
#else
#define _PAGE_MM_BIT_ACCESSED _PAGE_BIT_ACCESSED
#endif
#ifdef CONFIG_X86_64
#define _PAGE_BIT_EPT_ACCESSED 8
#define _PAGE_BIT_EPT_DIRTY 9
#define _PAGE_EPT_ACCESSED (_AT(pteval_t, 1) << _PAGE_BIT_EPT_ACCESSED)
#define _PAGE_EPT_DIRTY (_AT(pteval_t, 1) << _PAGE_BIT_EPT_DIRTY)
#define _PAGE_EPT_PRESENT (_AT(pteval_t, 7))
static inline int ept_pte_present(pte_t a)
{
return pte_flags(a) & _PAGE_EPT_PRESENT;
}
static inline int ept_pmd_present(pmd_t a)
{
return pmd_flags(a) & _PAGE_EPT_PRESENT;
}
static inline int ept_pud_present(pud_t a)
{
return pud_flags(a) & _PAGE_EPT_PRESENT;
}
static inline int ept_p4d_present(p4d_t a)
{
return p4d_flags(a) & _PAGE_EPT_PRESENT;
}
static inline int ept_pgd_present(pgd_t a)
{
return pgd_flags(a) & _PAGE_EPT_PRESENT;
}
static inline int ept_pte_accessed(pte_t a)
{
return pte_flags(a) & _PAGE_EPT_ACCESSED;
}
static inline int ept_pmd_accessed(pmd_t a)
{
return pmd_flags(a) & _PAGE_EPT_ACCESSED;
}
static inline int ept_pud_accessed(pud_t a)
{
return pud_flags(a) & _PAGE_EPT_ACCESSED;
}
static inline int ept_p4d_accessed(p4d_t a)
{
return p4d_flags(a) & _PAGE_EPT_ACCESSED;
}
static inline int ept_pgd_accessed(pgd_t a)
{
return pgd_flags(a) & _PAGE_EPT_ACCESSED;
}
#endif
extern struct file_operations proc_page_scan_operations;
#define PAGE_IDLE_KBUF_FULL 1
#define PAGE_IDLE_BUF_FULL 2
#define PAGE_IDLE_BUF_MIN (sizeof(uint64_t) * 2 + 3)
#define PAGE_IDLE_KBUF_SIZE 8000
struct page_idle_ctrl {
struct mm_struct *mm;
struct kvm *kvm;
uint8_t kpie[PAGE_IDLE_KBUF_SIZE];
int pie_read;
int pie_read_max;
void __user *buf;
int buf_size;
int bytes_copied;
unsigned long next_hva; /* GPA for EPT; VA for PT */
unsigned long gpa_to_hva;
unsigned long restart_gpa;
unsigned long last_va;
unsigned int flags;
};
#endif
......@@ -1688,6 +1688,72 @@ const struct file_operations proc_pagemap_operations = {
.open = pagemap_open,
.release = pagemap_release,
};
/* will be filled when kvm_ept_idle module loads */
struct file_operations proc_page_scan_operations = {
};
EXPORT_SYMBOL_GPL(proc_page_scan_operations);
static ssize_t mm_idle_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
struct mm_struct *mm = file->private_data;
int ret = 0;
if (!mm || !mmget_not_zero(mm)) {
ret = -ESRCH;
return ret;
}
if (proc_page_scan_operations.read)
ret = proc_page_scan_operations.read(file, buf, count, ppos);
mmput(mm);
return ret;
}
static int mm_idle_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_page_scan_operations.open)
return proc_page_scan_operations.open(inode, file);
return 0;
}
static int mm_idle_release(struct inode *inode, struct file *file)
{
struct mm_struct *mm = file->private_data;
if (mm) {
if (!mm_kvm(mm))
flush_tlb_mm(mm);
mmdrop(mm);
}
if (proc_page_scan_operations.release)
return proc_page_scan_operations.release(inode, file);
return 0;
}
const struct file_operations proc_mm_idle_operations = {
.llseek = mem_lseek, /* borrow this */
.read = mm_idle_read,
.open = mm_idle_open,
.release = mm_idle_release,
};
#endif /* CONFIG_PROC_PAGE_MONITOR */
#ifdef CONFIG_NUMA
......
......@@ -26,7 +26,7 @@
struct address_space;
struct mem_cgroup;
struct kvm;
/*
* Each physical page in the system has a struct page associated with
* it to keep track of whatever it is we are using the page for at the
......@@ -566,6 +566,10 @@ struct mm_struct {
#endif
} __randomize_layout;
#if IS_ENABLED(CONFIG_KVM) && !defined(__GENKSYMS__)
struct kvm *kvm;
#endif
/*
* The mm_cpumask needs to be at the end of mm_struct, because it
* is dynamically sized based on nr_cpu_ids.
......@@ -575,6 +579,18 @@ struct mm_struct {
extern struct mm_struct init_mm;
#if IS_ENABLED(CONFIG_KVM)
static inline struct kvm *mm_kvm(struct mm_struct *mm)
{
return mm->kvm;
}
#else
static inline struct kvm *mm_kvm(struct mm_struct *mm)
{
return NULL;
}
#endif
/* Pointer magic because the dynamic array size confuses some compilers. */
static inline void mm_init_cpumask(struct mm_struct *mm)
{
......
......@@ -660,6 +660,12 @@ config PARMAN
config OBJAGG
tristate "objagg" if COMPILE_TEST
config MEMIG_SCAN_MODULE
tristate "module: memig page scan for memig support"
help
memig page scan feature
used to scan the virtual address of the target process
config STRING_SELFTEST
tristate "Test string functions"
......
......@@ -1911,6 +1911,7 @@ spinlock_t *__pud_trans_huge_lock(pud_t *pud, struct vm_area_struct *vma)
spin_unlock(ptl);
return NULL;
}
EXPORT_SYMBOL_GPL(__pud_trans_huge_lock);
#ifdef CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD
int zap_huge_pud(struct mmu_gather *tlb, struct vm_area_struct *vma,
......
......@@ -430,7 +430,7 @@ int walk_page_range(struct mm_struct *mm, unsigned long start,
} while (start = next, start < end);
return err;
}
EXPORT_SYMBOL_GPL(walk_page_range);
/*
* Similar to walk_page_range() but can walk any page tables even if they are
* not backed by VMAs. Because 'unusual' entries may be walked this function
......
......@@ -856,6 +856,9 @@ static void kvm_destroy_vm(struct kvm *kvm)
struct mm_struct *mm = kvm->mm;
kvm_uevent_notify_change(KVM_EVENT_DESTROY_VM, kvm);
#if IS_ENABLED(CONFIG_KVM)
mm->kvm = NULL;
#endif
kvm_destroy_vm_debugfs(kvm);
kvm_arch_sync_events(kvm);
mutex_lock(&kvm_lock);
......@@ -3962,6 +3965,9 @@ static int kvm_dev_ioctl_create_vm(unsigned long type)
fput(file);
return -ENOMEM;
}
#if IS_ENABLED(CONFIG_KVM)
kvm->mm->kvm = kvm;
#endif
kvm_uevent_notify_change(KVM_EVENT_CREATE_VM, kvm);
fd_install(r, file);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册