diff --git a/fs/proc/meminfo.c b/fs/proc/meminfo.c index 55de0309b4b0ad53a8df4cd266b240eb589e86ae..f20ed52c78c27df0639c36ba867689786620990c 100644 --- a/fs/proc/meminfo.c +++ b/fs/proc/meminfo.c @@ -41,12 +41,10 @@ static int meminfo_proc_show(struct seq_file *m, void *v) unsigned long pages[NR_LRU_LISTS]; unsigned long sreclaimable, sunreclaim; int lru; - unsigned long nr_purgeable_active = 0; - unsigned long nr_purgeable_inactive = 0; + unsigned long nr_purg_active = 0; + unsigned long nr_purg_inactive = 0; #ifdef CONFIG_MEM_PURGEABLE - unsigned long nr_purgeable_pined = 0; - - purg_pages_info(NULL, &nr_purgeable_pined); + unsigned long nr_purg_pined = 0; #endif si_meminfo(&i); @@ -62,8 +60,10 @@ static int meminfo_proc_show(struct seq_file *m, void *v) pages[lru] = global_node_page_state(NR_LRU_BASE + lru); #ifdef CONFIG_MEM_PURGEABLE - nr_purgeable_active = pages[LRU_ACTIVE_PURGEABLE]; - nr_purgeable_inactive = pages[LRU_INACTIVE_PURGEABLE]; + nr_purg_active = pages[LRU_ACTIVE_PURGEABLE]; + nr_purg_inactive = pages[LRU_INACTIVE_PURGEABLE]; + purg_pages_info(NULL, &nr_purg_pined); + nr_purg_pined = min(nr_purg_pined, nr_purg_active + nr_purg_inactive); #endif available = si_mem_available(); @@ -78,18 +78,18 @@ static int meminfo_proc_show(struct seq_file *m, void *v) show_val_kb(m, "SwapCached: ", total_swapcache_pages()); show_val_kb(m, "Active: ", pages[LRU_ACTIVE_ANON] + pages[LRU_ACTIVE_FILE] + - nr_purgeable_active); + nr_purg_active); show_val_kb(m, "Inactive: ", pages[LRU_INACTIVE_ANON] + pages[LRU_INACTIVE_FILE] + - nr_purgeable_inactive); + nr_purg_inactive); show_val_kb(m, "Active(anon): ", pages[LRU_ACTIVE_ANON]); show_val_kb(m, "Inactive(anon): ", pages[LRU_INACTIVE_ANON]); show_val_kb(m, "Active(file): ", pages[LRU_ACTIVE_FILE]); show_val_kb(m, "Inactive(file): ", pages[LRU_INACTIVE_FILE]); #ifdef CONFIG_MEM_PURGEABLE - show_val_kb(m, "Active(purgeable): ", nr_purgeable_active); - show_val_kb(m, "Inactive(purgeable): ", nr_purgeable_inactive); - show_val_kb(m, "Pined(purgeable): ", nr_purgeable_pined); + show_val_kb(m, "Active(purg): ", nr_purg_active); + show_val_kb(m, "Inactive(purg): ", nr_purg_inactive); + show_val_kb(m, "Pined(purg): ", nr_purg_pined); #endif show_val_kb(m, "Unevictable: ", pages[LRU_UNEVICTABLE]); show_val_kb(m, "Mlocked: ", global_zone_page_state(NR_MLOCK)); diff --git a/mm/Kconfig b/mm/Kconfig index ad8cd862359ef9d0268c8a3aaca2dd1e1cac85a1..c39f868947e3e3dc198b8af8d8782c744e089d96 100644 --- a/mm/Kconfig +++ b/mm/Kconfig @@ -961,7 +961,7 @@ config RSS_THRESHOLD config MEM_PURGEABLE bool "Purgeable memory feature" default n - depends on ARCH_USES_HIGH_VMA_FLAGS + select ARCH_USES_HIGH_VMA_FLAGS help Support purgeable pages for process diff --git a/mm/memory.c b/mm/memory.c index 73231717b75c95cb8ea7c2592162308f5339d5b9..582776bec124c28348589b933b79df0e0737e371 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -2916,6 +2916,11 @@ static vm_fault_t wp_page_copy(struct vm_fault *vmf) */ ptep_clear_flush_notify(vma, vmf->address, vmf->pte); page_add_new_anon_rmap(new_page, vma, vmf->address, false); + if (vma->vm_flags & VM_PURGEABLE) { + pr_info("set wp new page %lx purgeable\n", page_to_pfn(new_page)); + SetPagePurgeable(new_page); + uxpte_set_present(vma, vmf->address); + } lru_cache_add_inactive_or_unevictable(new_page, vma); /* * We call the notify macro here because, when using secondary @@ -3633,12 +3638,14 @@ static vm_fault_t do_anonymous_page(struct vm_fault *vmf) inc_mm_counter_fast(vma->vm_mm, MM_ANONPAGES); page_add_new_anon_rmap(page, vma, vmf->address, false); - if (vma->vm_flags & VM_PURGEABLE) { + if (vma->vm_flags & VM_PURGEABLE) SetPagePurgeable(page); - uxpte_set_present(vma, vmf->address); - } + lru_cache_add_inactive_or_unevictable(page, vma); setpte: + if (vma->vm_flags & VM_PURGEABLE) + uxpte_set_present(vma, vmf->address); + set_pte_at(vma->vm_mm, vmf->address, vmf->pte, entry); /* No need to invalidate - it was non-present before */