Skip to content

Commit e180377

Browse files
kiryltorvalds
authored andcommitted
thp: change split_huge_page_pmd() interface
Pass vma instead of mm and add address parameter. In most cases we already have vma on the stack. We provides split_huge_page_pmd_mm() for few cases when we have mm, but not vma. This change is preparation to huge zero pmd splitting implementation. Signed-off-by: Kirill A. Shutemov <[email protected]> Cc: Andrea Arcangeli <[email protected]> Cc: Andi Kleen <[email protected]> Cc: "H. Peter Anvin" <[email protected]> Cc: Mel Gorman <[email protected]> Cc: David Rientjes <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent cad7f61 commit e180377

File tree

10 files changed

+37
-16
lines changed

10 files changed

+37
-16
lines changed

Documentation/vm/transhuge.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ unaffected. libhugetlbfs will also work fine as usual.
276276
== Graceful fallback ==
277277

278278
Code walking pagetables but unware about huge pmds can simply call
279-
split_huge_page_pmd(mm, pmd) where the pmd is the one returned by
279+
split_huge_page_pmd(vma, addr, pmd) where the pmd is the one returned by
280280
pmd_offset. It's trivial to make the code transparent hugepage aware
281281
by just grepping for "pmd_offset" and adding split_huge_page_pmd where
282282
missing after pmd_offset returns the pmd. Thanks to the graceful
@@ -299,7 +299,7 @@ diff --git a/mm/mremap.c b/mm/mremap.c
299299
return NULL;
300300

301301
pmd = pmd_offset(pud, addr);
302-
+ split_huge_page_pmd(mm, pmd);
302+
+ split_huge_page_pmd(vma, addr, pmd);
303303
if (pmd_none_or_clear_bad(pmd))
304304
return NULL;
305305

arch/x86/kernel/vm86_32.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ static void mark_screen_rdonly(struct mm_struct *mm)
182182
if (pud_none_or_clear_bad(pud))
183183
goto out;
184184
pmd = pmd_offset(pud, 0xA0000);
185-
split_huge_page_pmd(mm, pmd);
185+
split_huge_page_pmd_mm(mm, 0xA0000, pmd);
186186
if (pmd_none_or_clear_bad(pmd))
187187
goto out;
188188
pte = pte_offset_map_lock(mm, pmd, 0xA0000, &ptl);

fs/proc/task_mmu.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -643,7 +643,7 @@ static int clear_refs_pte_range(pmd_t *pmd, unsigned long addr,
643643
spinlock_t *ptl;
644644
struct page *page;
645645

646-
split_huge_page_pmd(walk->mm, pmd);
646+
split_huge_page_pmd(vma, addr, pmd);
647647
if (pmd_trans_unstable(pmd))
648648
return 0;
649649

include/linux/huge_mm.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,14 @@ extern int handle_pte_fault(struct mm_struct *mm,
9595
struct vm_area_struct *vma, unsigned long address,
9696
pte_t *pte, pmd_t *pmd, unsigned int flags);
9797
extern int split_huge_page(struct page *page);
98-
extern void __split_huge_page_pmd(struct mm_struct *mm, pmd_t *pmd);
99-
#define split_huge_page_pmd(__mm, __pmd) \
98+
extern void __split_huge_page_pmd(struct vm_area_struct *vma,
99+
unsigned long address, pmd_t *pmd);
100+
#define split_huge_page_pmd(__vma, __address, __pmd) \
100101
do { \
101102
pmd_t *____pmd = (__pmd); \
102103
if (unlikely(pmd_trans_huge(*____pmd))) \
103-
__split_huge_page_pmd(__mm, ____pmd); \
104+
__split_huge_page_pmd(__vma, __address, \
105+
____pmd); \
104106
} while (0)
105107
#define wait_split_huge_page(__anon_vma, __pmd) \
106108
do { \
@@ -110,6 +112,8 @@ extern void __split_huge_page_pmd(struct mm_struct *mm, pmd_t *pmd);
110112
BUG_ON(pmd_trans_splitting(*____pmd) || \
111113
pmd_trans_huge(*____pmd)); \
112114
} while (0)
115+
extern void split_huge_page_pmd_mm(struct mm_struct *mm, unsigned long address,
116+
pmd_t *pmd);
113117
#if HPAGE_PMD_ORDER > MAX_ORDER
114118
#error "hugepages can't be allocated by the buddy allocator"
115119
#endif
@@ -177,10 +181,12 @@ static inline int split_huge_page(struct page *page)
177181
{
178182
return 0;
179183
}
180-
#define split_huge_page_pmd(__mm, __pmd) \
184+
#define split_huge_page_pmd(__vma, __address, __pmd) \
181185
do { } while (0)
182186
#define wait_split_huge_page(__anon_vma, __pmd) \
183187
do { } while (0)
188+
#define split_huge_page_pmd_mm(__mm, __address, __pmd) \
189+
do { } while (0)
184190
#define compound_trans_head(page) compound_head(page)
185191
static inline int hugepage_madvise(struct vm_area_struct *vma,
186192
unsigned long *vm_flags, int advice)

mm/huge_memory.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2475,9 +2475,14 @@ static int khugepaged(void *none)
24752475
return 0;
24762476
}
24772477

2478-
void __split_huge_page_pmd(struct mm_struct *mm, pmd_t *pmd)
2478+
void __split_huge_page_pmd(struct vm_area_struct *vma, unsigned long address,
2479+
pmd_t *pmd)
24792480
{
24802481
struct page *page;
2482+
unsigned long haddr = address & HPAGE_PMD_MASK;
2483+
struct mm_struct *mm = vma->vm_mm;
2484+
2485+
BUG_ON(vma->vm_start > haddr || vma->vm_end < haddr + HPAGE_PMD_SIZE);
24812486

24822487
spin_lock(&mm->page_table_lock);
24832488
if (unlikely(!pmd_trans_huge(*pmd))) {
@@ -2495,6 +2500,16 @@ void __split_huge_page_pmd(struct mm_struct *mm, pmd_t *pmd)
24952500
BUG_ON(pmd_trans_huge(*pmd));
24962501
}
24972502

2503+
void split_huge_page_pmd_mm(struct mm_struct *mm, unsigned long address,
2504+
pmd_t *pmd)
2505+
{
2506+
struct vm_area_struct *vma;
2507+
2508+
vma = find_vma(mm, address);
2509+
BUG_ON(vma == NULL);
2510+
split_huge_page_pmd(vma, address, pmd);
2511+
}
2512+
24982513
static void split_huge_page_address(struct mm_struct *mm,
24992514
unsigned long address)
25002515
{
@@ -2509,7 +2524,7 @@ static void split_huge_page_address(struct mm_struct *mm,
25092524
* Caller holds the mmap_sem write mode, so a huge pmd cannot
25102525
* materialize from under us.
25112526
*/
2512-
split_huge_page_pmd(mm, pmd);
2527+
split_huge_page_pmd_mm(mm, address, pmd);
25132528
}
25142529

25152530
void __vma_adjust_trans_huge(struct vm_area_struct *vma,

mm/memory.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,7 +1243,7 @@ static inline unsigned long zap_pmd_range(struct mmu_gather *tlb,
12431243
BUG();
12441244
}
12451245
#endif
1246-
split_huge_page_pmd(vma->vm_mm, pmd);
1246+
split_huge_page_pmd(vma, addr, pmd);
12471247
} else if (zap_huge_pmd(tlb, vma, pmd, addr))
12481248
goto next;
12491249
/* fall through */
@@ -1512,7 +1512,7 @@ struct page *follow_page(struct vm_area_struct *vma, unsigned long address,
15121512
}
15131513
if (pmd_trans_huge(*pmd)) {
15141514
if (flags & FOLL_SPLIT) {
1515-
split_huge_page_pmd(mm, pmd);
1515+
split_huge_page_pmd(vma, address, pmd);
15161516
goto split_fallthrough;
15171517
}
15181518
spin_lock(&mm->page_table_lock);

mm/mempolicy.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,7 @@ static inline int check_pmd_range(struct vm_area_struct *vma, pud_t *pud,
511511
pmd = pmd_offset(pud, addr);
512512
do {
513513
next = pmd_addr_end(addr, end);
514-
split_huge_page_pmd(vma->vm_mm, pmd);
514+
split_huge_page_pmd(vma, addr, pmd);
515515
if (pmd_none_or_trans_huge_or_clear_bad(pmd))
516516
continue;
517517
if (check_pte_range(vma, pmd, addr, next, nodes,

mm/mprotect.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ static inline void change_pmd_range(struct vm_area_struct *vma, pud_t *pud,
9090
next = pmd_addr_end(addr, end);
9191
if (pmd_trans_huge(*pmd)) {
9292
if (next - addr != HPAGE_PMD_SIZE)
93-
split_huge_page_pmd(vma->vm_mm, pmd);
93+
split_huge_page_pmd(vma, addr, pmd);
9494
else if (change_huge_pmd(vma, pmd, addr, newprot))
9595
continue;
9696
/* fall through */

mm/mremap.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ unsigned long move_page_tables(struct vm_area_struct *vma,
182182
need_flush = true;
183183
continue;
184184
} else if (!err) {
185-
split_huge_page_pmd(vma->vm_mm, old_pmd);
185+
split_huge_page_pmd(vma, old_addr, old_pmd);
186186
}
187187
VM_BUG_ON(pmd_trans_huge(*old_pmd));
188188
}

mm/pagewalk.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ static int walk_pmd_range(pud_t *pud, unsigned long addr, unsigned long end,
5858
if (!walk->pte_entry)
5959
continue;
6060

61-
split_huge_page_pmd(walk->mm, pmd);
61+
split_huge_page_pmd_mm(walk->mm, addr, pmd);
6262
if (pmd_none_or_trans_huge_or_clear_bad(pmd))
6363
goto again;
6464
err = walk_pte_range(pmd, addr, next, walk);

0 commit comments

Comments
 (0)