Skip to content

Commit 18f3962

Browse files
Qi Zhengakpm00
authored andcommitted
mm: hugetlb: kill set_huge_swap_pte_at()
Commit e5251fd ("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/[email protected] Signed-off-by: Qi Zheng <[email protected]> Acked-by: Muchun Song <[email protected]> Cc: Mike Kravetz <[email protected]> Cc: Catalin Marinas <[email protected]> Cc: Will Deacon <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent ade63b4 commit 18f3962

File tree

5 files changed

+23
-46
lines changed

5 files changed

+23
-46
lines changed

arch/arm64/include/asm/hugetlb.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,6 @@ extern void huge_pte_clear(struct mm_struct *mm, unsigned long addr,
4646
pte_t *ptep, unsigned long sz);
4747
#define __HAVE_ARCH_HUGE_PTEP_GET
4848
extern pte_t huge_ptep_get(pte_t *ptep);
49-
extern void set_huge_swap_pte_at(struct mm_struct *mm, unsigned long addr,
50-
pte_t *ptep, pte_t pte, unsigned long sz);
51-
#define set_huge_swap_pte_at set_huge_swap_pte_at
5249

5350
void __init arm64_hugetlb_cma_reserve(void);
5451

arch/arm64/mm/hugetlbpage.c

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,13 @@ static void clear_flush(struct mm_struct *mm,
238238
flush_tlb_range(&vma, saddr, addr);
239239
}
240240

241+
static inline struct folio *hugetlb_swap_entry_to_folio(swp_entry_t entry)
242+
{
243+
VM_BUG_ON(!is_migration_entry(entry) && !is_hwpoison_entry(entry));
244+
245+
return page_folio(pfn_to_page(swp_offset(entry)));
246+
}
247+
241248
void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
242249
pte_t *ptep, pte_t pte)
243250
{
@@ -247,11 +254,16 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
247254
unsigned long pfn, dpfn;
248255
pgprot_t hugeprot;
249256

250-
/*
251-
* Code needs to be expanded to handle huge swap and migration
252-
* entries. Needed for HUGETLB and MEMORY_FAILURE.
253-
*/
254-
WARN_ON(!pte_present(pte));
257+
if (!pte_present(pte)) {
258+
struct folio *folio;
259+
260+
folio = hugetlb_swap_entry_to_folio(pte_to_swp_entry(pte));
261+
ncontig = num_contig_ptes(folio_size(folio), &pgsize);
262+
263+
for (i = 0; i < ncontig; i++, ptep++)
264+
set_pte_at(mm, addr, ptep, pte);
265+
return;
266+
}
255267

256268
if (!pte_cont(pte)) {
257269
set_pte_at(mm, addr, ptep, pte);
@@ -269,18 +281,6 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
269281
set_pte_at(mm, addr, ptep, pfn_pte(pfn, hugeprot));
270282
}
271283

272-
void set_huge_swap_pte_at(struct mm_struct *mm, unsigned long addr,
273-
pte_t *ptep, pte_t pte, unsigned long sz)
274-
{
275-
int i, ncontig;
276-
size_t pgsize;
277-
278-
ncontig = num_contig_ptes(sz, &pgsize);
279-
280-
for (i = 0; i < ncontig; i++, ptep++)
281-
set_pte(ptep, pte);
282-
}
283-
284284
pte_t *huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma,
285285
unsigned long addr, unsigned long sz)
286286
{

include/linux/hugetlb.h

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -903,14 +903,6 @@ static inline void hugetlb_count_sub(long l, struct mm_struct *mm)
903903
atomic_long_sub(l, &mm->hugetlb_usage);
904904
}
905905

906-
#ifndef set_huge_swap_pte_at
907-
static inline void set_huge_swap_pte_at(struct mm_struct *mm, unsigned long addr,
908-
pte_t *ptep, pte_t pte, unsigned long sz)
909-
{
910-
set_huge_pte_at(mm, addr, ptep, pte);
911-
}
912-
#endif
913-
914906
#ifndef huge_ptep_modify_prot_start
915907
#define huge_ptep_modify_prot_start huge_ptep_modify_prot_start
916908
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)
10941086
{
10951087
}
10961088

1097-
static inline void set_huge_swap_pte_at(struct mm_struct *mm, unsigned long addr,
1098-
pte_t *ptep, pte_t pte, unsigned long sz)
1099-
{
1100-
}
1101-
11021089
static inline pte_t huge_ptep_clear_flush(struct vm_area_struct *vma,
11031090
unsigned long addr, pte_t *ptep)
11041091
{

mm/hugetlb.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4798,12 +4798,11 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
47984798
entry = swp_entry_to_pte(swp_entry);
47994799
if (userfaultfd_wp(src_vma) && uffd_wp)
48004800
entry = huge_pte_mkuffd_wp(entry);
4801-
set_huge_swap_pte_at(src, addr, src_pte,
4802-
entry, sz);
4801+
set_huge_pte_at(src, addr, src_pte, entry);
48034802
}
48044803
if (!userfaultfd_wp(dst_vma) && uffd_wp)
48054804
entry = huge_pte_clear_uffd_wp(entry);
4806-
set_huge_swap_pte_at(dst, addr, dst_pte, entry, sz);
4805+
set_huge_pte_at(dst, addr, dst_pte, entry);
48074806
} else if (unlikely(is_pte_marker(entry))) {
48084807
/*
48094808
* 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,
63446343
newpte = pte_swp_mkuffd_wp(newpte);
63456344
else if (uffd_wp_resolve)
63466345
newpte = pte_swp_clear_uffd_wp(newpte);
6347-
set_huge_swap_pte_at(mm, address, ptep,
6348-
newpte, psize);
6346+
set_huge_pte_at(mm, address, ptep, newpte);
63496347
pages++;
63506348
}
63516349
spin_unlock(ptl);

mm/rmap.c

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1618,9 +1618,7 @@ static bool try_to_unmap_one(struct folio *folio, struct vm_area_struct *vma,
16181618
pteval = swp_entry_to_pte(make_hwpoison_entry(subpage));
16191619
if (folio_test_hugetlb(folio)) {
16201620
hugetlb_count_sub(folio_nr_pages(folio), mm);
1621-
set_huge_swap_pte_at(mm, address,
1622-
pvmw.pte, pteval,
1623-
vma_mmu_pagesize(vma));
1621+
set_huge_pte_at(mm, address, pvmw.pte, pteval);
16241622
} else {
16251623
dec_mm_counter(mm, mm_counter(&folio->page));
16261624
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,
20042002
pteval = swp_entry_to_pte(make_hwpoison_entry(subpage));
20052003
if (folio_test_hugetlb(folio)) {
20062004
hugetlb_count_sub(folio_nr_pages(folio), mm);
2007-
set_huge_swap_pte_at(mm, address,
2008-
pvmw.pte, pteval,
2009-
vma_mmu_pagesize(vma));
2005+
set_huge_pte_at(mm, address, pvmw.pte, pteval);
20102006
} else {
20112007
dec_mm_counter(mm, mm_counter(&folio->page));
20122008
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,
20742070
if (pte_uffd_wp(pteval))
20752071
swp_pte = pte_swp_mkuffd_wp(swp_pte);
20762072
if (folio_test_hugetlb(folio))
2077-
set_huge_swap_pte_at(mm, address, pvmw.pte,
2078-
swp_pte, vma_mmu_pagesize(vma));
2073+
set_huge_pte_at(mm, address, pvmw.pte, swp_pte);
20792074
else
20802075
set_pte_at(mm, address, pvmw.pte, swp_pte);
20812076
trace_set_migration_pte(address, pte_val(swp_pte),

0 commit comments

Comments
 (0)