Skip to content

Commit

Permalink
mm/madvise: add file and shmem support to MADV_COLLAPSE
Browse files Browse the repository at this point in the history
Add support for MADV_COLLAPSE to collapse shmem-backed and file-backed
memory into THPs (requires CONFIG_READ_ONLY_THP_FOR_FS=y).

On success, the backing memory will be a hugepage.  For the memory range
and process provided, the page tables will synchronously have a huge pmd
installed, mapping the THP.  Other mappings of the file extent mapped by
the memory range may be added to a set of entries that khugepaged will
later process and attempt update their page tables to map the THP by a pmd.

This functionality unlocks two important uses:

(1)	Immediately back executable text by THPs.  Current support provided
	by CONFIG_READ_ONLY_THP_FOR_FS may take a long time on a large
	system which might impair services from serving at their full rated
	load after (re)starting.  Tricks like mremap(2)'ing text onto
	anonymous memory to immediately realize iTLB performance prevents
	page sharing and demand paging, both of which increase steady state
	memory footprint.  Now, we can have the best of both worlds: Peak
	upfront performance and lower RAM footprints.

(2)	userfaultfd-based live migration of virtual machines satisfy UFFD
	faults by fetching native-sized pages over the network (to avoid
	latency of transferring an entire hugepage).  However, after guest
	memory has been fully copied to the new host, MADV_COLLAPSE can
	be used to immediately increase guest performance.

Signed-off-by: Zach O'Keefe <zokeefe@google.com>
  • Loading branch information
zokeefe authored and intel-lab-lkp committed Aug 12, 2022
1 parent 6e0bd17 commit dff0874
Show file tree
Hide file tree
Showing 4 changed files with 198 additions and 59 deletions.
11 changes: 6 additions & 5 deletions include/linux/khugepaged.h
Expand Up @@ -16,10 +16,11 @@ extern void khugepaged_enter_vma(struct vm_area_struct *vma,
unsigned long vm_flags);
extern void khugepaged_min_free_kbytes_update(void);
#ifdef CONFIG_SHMEM
extern void collapse_pte_mapped_thp(struct mm_struct *mm, unsigned long addr);
extern int collapse_pte_mapped_thp(struct mm_struct *mm, unsigned long addr,
bool install_pmd);
#else
static inline void collapse_pte_mapped_thp(struct mm_struct *mm,
unsigned long addr)
static inline int collapse_pte_mapped_thp(struct mm_struct *mm,
unsigned long addr, bool install_pmd)
{
}
#endif
Expand All @@ -46,8 +47,8 @@ static inline void khugepaged_enter_vma(struct vm_area_struct *vma,
unsigned long vm_flags)
{
}
static inline void collapse_pte_mapped_thp(struct mm_struct *mm,
unsigned long addr)
static inline int collapse_pte_mapped_thp(struct mm_struct *mm,
unsigned long addr, bool install_pmd)
{
}

Expand Down
1 change: 1 addition & 0 deletions include/trace/events/huge_memory.h
Expand Up @@ -11,6 +11,7 @@
EM( SCAN_FAIL, "failed") \
EM( SCAN_SUCCEED, "succeeded") \
EM( SCAN_PMD_NULL, "pmd_null") \
EM( SCAN_PMD_NON_PRESENT, "pmd_non_present") \
EM( SCAN_PMD_MAPPED, "page_pmd_mapped") \
EM( SCAN_EXCEED_NONE_PTE, "exceed_none_pte") \
EM( SCAN_EXCEED_SWAP_PTE, "exceed_swap_pte") \
Expand Down
2 changes: 1 addition & 1 deletion kernel/events/uprobes.c
Expand Up @@ -552,7 +552,7 @@ int uprobe_write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm,

/* try collapse pmd for compound page */
if (!ret && orig_page_huge)
collapse_pte_mapped_thp(mm, vaddr);
collapse_pte_mapped_thp(mm, vaddr, false);

return ret;
}
Expand Down

0 comments on commit dff0874

Please sign in to comment.