> On Jun 22, 2019, at 10:48 PM, Song Liu <songliubraving@xxxxxx> wrote: > > khugepaged needs exclusive mmap_sem to access page table. When it fails > to lock mmap_sem, the page will fault in as pte-mapped THP. As the page > is already a THP, khugepaged will not handle this pmd again. > > This patch enables the khugepaged to retry retract_page_tables(). > > A new flag AS_COLLAPSE_PMD is introduced to show the address_space may > contain pte-mapped THPs. When khugepaged fails to trylock the mmap_sem, > it sets AS_COLLAPSE_PMD. Then, at a later time, khugepaged will retry > compound pages in this address_space. > > Since collapse may happen at an later time, some pages may already fault > in. To handle these pages properly, it is necessary to prepare the pmd > before collapsing. prepare_pmd_for_collapse() is introduced to prepare > the pmd by removing rmap, adjusting refcount and mm_counter. > > prepare_pmd_for_collapse() also double checks whether all ptes in this > pmd are mapping to the same THP. This is necessary because some subpage > of the THP may be replaced, for example by uprobe. In such cases, it > is not possible to collapse the pmd, so we fall back. > > Signed-off-by: Song Liu <songliubraving@xxxxxx> > --- > include/linux/pagemap.h | 1 + > mm/khugepaged.c | 69 +++++++++++++++++++++++++++++++++++------ > 2 files changed, 60 insertions(+), 10 deletions(-) > > diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h > index 9ec3544baee2..eac881de2a46 100644 > --- a/include/linux/pagemap.h > +++ b/include/linux/pagemap.h > @@ -29,6 +29,7 @@ enum mapping_flags { > AS_EXITING = 4, /* final truncate in progress */ > /* writeback related tags are not used */ > AS_NO_WRITEBACK_TAGS = 5, > + AS_COLLAPSE_PMD = 6, /* try collapse pmd for THP */ > }; > > /** > diff --git a/mm/khugepaged.c b/mm/khugepaged.c > index a4f90a1b06f5..9b980327fd9b 100644 > --- a/mm/khugepaged.c > +++ b/mm/khugepaged.c > @@ -1254,7 +1254,47 @@ static void collect_mm_slot(struct mm_slot *mm_slot) > } > > #if defined(CONFIG_SHMEM) && defined(CONFIG_TRANSPARENT_HUGE_PAGECACHE) > -static void retract_page_tables(struct address_space *mapping, pgoff_t pgoff) > + > +/* return whether the pmd is ready for collapse */ > +bool prepare_pmd_for_collapse(struct vm_area_struct *vma, pgoff_t pgoff, > + struct page *hpage, pmd_t *pmd) kbuild test robot reported I missed "static" here. But I am holding off a newer version that just fixes this. Thanks, Song