mm: hugetlb: kill set_huge_swap_pte_at()

Commit e5251fd430 ("mm/hugetlb: introduce set_huge_swap_pte_at()
helper") add set_huge_swap_pte_at() to handle swap entries on
architectures that support hugepages consisting of contiguous ptes.  And
currently the set_huge_swap_pte_at() is only overridden by arm64.

set_huge_swap_pte_at() provide a sz parameter to help determine the number
of entries to be updated.  But in fact, all hugetlb swap entries contain
pfn information, so we can find the corresponding folio through the pfn
recorded in the swap entry, then the folio_size() is the number of entries
that need to be updated.

And considering that users will easily cause bugs by ignoring the
difference between set_huge_swap_pte_at() and set_huge_pte_at().  Let's
handle swap entries in set_huge_pte_at() and remove the
set_huge_swap_pte_at(), then we can call set_huge_pte_at() anywhere, which
simplifies our coding.

Link: https://lkml.kernel.org/r/20220626145717.53572-1-zhengqi.arch@bytedance.com
Signed-off-by: Qi Zheng <zhengqi.arch@bytedance.com>
Acked-by: Muchun Song <songmuchun@bytedance.com>
Cc: Mike Kravetz <mike.kravetz@oracle.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
Qi Zheng 2022-06-26 22:57:17 +08:00 committed by akpm
parent ade63b419c
commit 18f3962953
5 changed files with 23 additions and 46 deletions

View File

@ -46,9 +46,6 @@ extern void huge_pte_clear(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, unsigned long sz); pte_t *ptep, unsigned long sz);
#define __HAVE_ARCH_HUGE_PTEP_GET #define __HAVE_ARCH_HUGE_PTEP_GET
extern pte_t huge_ptep_get(pte_t *ptep); extern pte_t huge_ptep_get(pte_t *ptep);
extern void set_huge_swap_pte_at(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t pte, unsigned long sz);
#define set_huge_swap_pte_at set_huge_swap_pte_at
void __init arm64_hugetlb_cma_reserve(void); void __init arm64_hugetlb_cma_reserve(void);

View File

@ -238,6 +238,13 @@ static void clear_flush(struct mm_struct *mm,
flush_tlb_range(&vma, saddr, addr); flush_tlb_range(&vma, saddr, addr);
} }
static inline struct folio *hugetlb_swap_entry_to_folio(swp_entry_t entry)
{
VM_BUG_ON(!is_migration_entry(entry) && !is_hwpoison_entry(entry));
return page_folio(pfn_to_page(swp_offset(entry)));
}
void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t pte) pte_t *ptep, pte_t pte)
{ {
@ -247,11 +254,16 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
unsigned long pfn, dpfn; unsigned long pfn, dpfn;
pgprot_t hugeprot; pgprot_t hugeprot;
/* if (!pte_present(pte)) {
* Code needs to be expanded to handle huge swap and migration struct folio *folio;
* entries. Needed for HUGETLB and MEMORY_FAILURE.
*/ folio = hugetlb_swap_entry_to_folio(pte_to_swp_entry(pte));
WARN_ON(!pte_present(pte)); ncontig = num_contig_ptes(folio_size(folio), &pgsize);
for (i = 0; i < ncontig; i++, ptep++)
set_pte_at(mm, addr, ptep, pte);
return;
}
if (!pte_cont(pte)) { if (!pte_cont(pte)) {
set_pte_at(mm, addr, ptep, pte); set_pte_at(mm, addr, ptep, pte);
@ -269,18 +281,6 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
set_pte_at(mm, addr, ptep, pfn_pte(pfn, hugeprot)); set_pte_at(mm, addr, ptep, pfn_pte(pfn, hugeprot));
} }
void set_huge_swap_pte_at(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t pte, unsigned long sz)
{
int i, ncontig;
size_t pgsize;
ncontig = num_contig_ptes(sz, &pgsize);
for (i = 0; i < ncontig; i++, ptep++)
set_pte(ptep, pte);
}
pte_t *huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma, pte_t *huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma,
unsigned long addr, unsigned long sz) unsigned long addr, unsigned long sz)
{ {

View File

@ -903,14 +903,6 @@ static inline void hugetlb_count_sub(long l, struct mm_struct *mm)
atomic_long_sub(l, &mm->hugetlb_usage); atomic_long_sub(l, &mm->hugetlb_usage);
} }
#ifndef set_huge_swap_pte_at
static inline void set_huge_swap_pte_at(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t pte, unsigned long sz)
{
set_huge_pte_at(mm, addr, ptep, pte);
}
#endif
#ifndef huge_ptep_modify_prot_start #ifndef huge_ptep_modify_prot_start
#define huge_ptep_modify_prot_start huge_ptep_modify_prot_start #define huge_ptep_modify_prot_start huge_ptep_modify_prot_start
static inline pte_t huge_ptep_modify_prot_start(struct vm_area_struct *vma, static inline pte_t huge_ptep_modify_prot_start(struct vm_area_struct *vma,
@ -1094,11 +1086,6 @@ static inline void hugetlb_count_sub(long l, struct mm_struct *mm)
{ {
} }
static inline void set_huge_swap_pte_at(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t pte, unsigned long sz)
{
}
static inline pte_t huge_ptep_clear_flush(struct vm_area_struct *vma, static inline pte_t huge_ptep_clear_flush(struct vm_area_struct *vma,
unsigned long addr, pte_t *ptep) unsigned long addr, pte_t *ptep)
{ {

View File

@ -4798,12 +4798,11 @@ again:
entry = swp_entry_to_pte(swp_entry); entry = swp_entry_to_pte(swp_entry);
if (userfaultfd_wp(src_vma) && uffd_wp) if (userfaultfd_wp(src_vma) && uffd_wp)
entry = huge_pte_mkuffd_wp(entry); entry = huge_pte_mkuffd_wp(entry);
set_huge_swap_pte_at(src, addr, src_pte, set_huge_pte_at(src, addr, src_pte, entry);
entry, sz);
} }
if (!userfaultfd_wp(dst_vma) && uffd_wp) if (!userfaultfd_wp(dst_vma) && uffd_wp)
entry = huge_pte_clear_uffd_wp(entry); entry = huge_pte_clear_uffd_wp(entry);
set_huge_swap_pte_at(dst, addr, dst_pte, entry, sz); set_huge_pte_at(dst, addr, dst_pte, entry);
} else if (unlikely(is_pte_marker(entry))) { } else if (unlikely(is_pte_marker(entry))) {
/* /*
* We copy the pte marker only if the dst vma has * We copy the pte marker only if the dst vma has
@ -6344,8 +6343,7 @@ unsigned long hugetlb_change_protection(struct vm_area_struct *vma,
newpte = pte_swp_mkuffd_wp(newpte); newpte = pte_swp_mkuffd_wp(newpte);
else if (uffd_wp_resolve) else if (uffd_wp_resolve)
newpte = pte_swp_clear_uffd_wp(newpte); newpte = pte_swp_clear_uffd_wp(newpte);
set_huge_swap_pte_at(mm, address, ptep, set_huge_pte_at(mm, address, ptep, newpte);
newpte, psize);
pages++; pages++;
} }
spin_unlock(ptl); spin_unlock(ptl);

View File

@ -1618,9 +1618,7 @@ static bool try_to_unmap_one(struct folio *folio, struct vm_area_struct *vma,
pteval = swp_entry_to_pte(make_hwpoison_entry(subpage)); pteval = swp_entry_to_pte(make_hwpoison_entry(subpage));
if (folio_test_hugetlb(folio)) { if (folio_test_hugetlb(folio)) {
hugetlb_count_sub(folio_nr_pages(folio), mm); hugetlb_count_sub(folio_nr_pages(folio), mm);
set_huge_swap_pte_at(mm, address, set_huge_pte_at(mm, address, pvmw.pte, pteval);
pvmw.pte, pteval,
vma_mmu_pagesize(vma));
} else { } else {
dec_mm_counter(mm, mm_counter(&folio->page)); dec_mm_counter(mm, mm_counter(&folio->page));
set_pte_at(mm, address, pvmw.pte, pteval); set_pte_at(mm, address, pvmw.pte, pteval);
@ -2004,9 +2002,7 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma,
pteval = swp_entry_to_pte(make_hwpoison_entry(subpage)); pteval = swp_entry_to_pte(make_hwpoison_entry(subpage));
if (folio_test_hugetlb(folio)) { if (folio_test_hugetlb(folio)) {
hugetlb_count_sub(folio_nr_pages(folio), mm); hugetlb_count_sub(folio_nr_pages(folio), mm);
set_huge_swap_pte_at(mm, address, set_huge_pte_at(mm, address, pvmw.pte, pteval);
pvmw.pte, pteval,
vma_mmu_pagesize(vma));
} else { } else {
dec_mm_counter(mm, mm_counter(&folio->page)); dec_mm_counter(mm, mm_counter(&folio->page));
set_pte_at(mm, address, pvmw.pte, pteval); set_pte_at(mm, address, pvmw.pte, pteval);
@ -2074,8 +2070,7 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma,
if (pte_uffd_wp(pteval)) if (pte_uffd_wp(pteval))
swp_pte = pte_swp_mkuffd_wp(swp_pte); swp_pte = pte_swp_mkuffd_wp(swp_pte);
if (folio_test_hugetlb(folio)) if (folio_test_hugetlb(folio))
set_huge_swap_pte_at(mm, address, pvmw.pte, set_huge_pte_at(mm, address, pvmw.pte, swp_pte);
swp_pte, vma_mmu_pagesize(vma));
else else
set_pte_at(mm, address, pvmw.pte, swp_pte); set_pte_at(mm, address, pvmw.pte, swp_pte);
trace_set_migration_pte(address, pte_val(swp_pte), trace_set_migration_pte(address, pte_val(swp_pte),