Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 230812
b: refs/heads/master
c: 60ab324
h: refs/heads/master
v: v3
  • Loading branch information
Andrea Arcangeli authored and Linus Torvalds committed Jan 14, 2011
1 parent aa1a7fa commit a20e586
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 8 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a664b2d8555c659127bf8fe049a58449d394a707
refs/heads/master: 60ab3244ec85c44276c585a2a20d3750402e1cf4
6 changes: 4 additions & 2 deletions trunk/include/linux/huge_mm.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ extern void __split_huge_page_pmd(struct mm_struct *mm, pmd_t *pmd);
#if HPAGE_PMD_ORDER > MAX_ORDER
#error "hugepages can't be allocated by the buddy allocator"
#endif
extern int hugepage_madvise(unsigned long *vm_flags, int advice);
extern int hugepage_madvise(struct vm_area_struct *vma,
unsigned long *vm_flags, int advice);
extern void __vma_adjust_trans_huge(struct vm_area_struct *vma,
unsigned long start,
unsigned long end,
Expand Down Expand Up @@ -143,7 +144,8 @@ static inline int split_huge_page(struct page *page)
do { } while (0)
#define wait_split_huge_page(__anon_vma, __pmd) \
do { } while (0)
static inline int hugepage_madvise(unsigned long *vm_flags, int advice)
static inline int hugepage_madvise(struct vm_area_struct *vma,
unsigned long *vm_flags, int advice)
{
BUG();
return 0;
Expand Down
23 changes: 19 additions & 4 deletions trunk/mm/huge_memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -1389,7 +1389,8 @@ int split_huge_page(struct page *page)
return ret;
}

int hugepage_madvise(unsigned long *vm_flags, int advice)
int hugepage_madvise(struct vm_area_struct *vma,
unsigned long *vm_flags, int advice)
{
switch (advice) {
case MADV_HUGEPAGE:
Expand All @@ -1404,6 +1405,13 @@ int hugepage_madvise(unsigned long *vm_flags, int advice)
return -EINVAL;
*vm_flags &= ~VM_NOHUGEPAGE;
*vm_flags |= VM_HUGEPAGE;
/*
* If the vma become good for khugepaged to scan,
* register it here without waiting a page fault that
* may not happen any time soon.
*/
if (unlikely(khugepaged_enter_vma_merge(vma)))
return -ENOMEM;
break;
case MADV_NOHUGEPAGE:
/*
Expand All @@ -1417,6 +1425,11 @@ int hugepage_madvise(unsigned long *vm_flags, int advice)
return -EINVAL;
*vm_flags &= ~VM_HUGEPAGE;
*vm_flags |= VM_NOHUGEPAGE;
/*
* Setting VM_NOHUGEPAGE will prevent khugepaged from scanning
* this vma even if we leave the mm registered in khugepaged if
* it got registered before VM_NOHUGEPAGE was set.
*/
break;
}

Expand Down Expand Up @@ -1784,7 +1797,8 @@ static void collapse_huge_page(struct mm_struct *mm,
if (address < hstart || address + HPAGE_PMD_SIZE > hend)
goto out;

if (!(vma->vm_flags & VM_HUGEPAGE) && !khugepaged_always())
if ((!(vma->vm_flags & VM_HUGEPAGE) && !khugepaged_always()) ||
(vma->vm_flags & VM_NOHUGEPAGE))
goto out;

/* VM_PFNMAP vmas may have vm_ops null but vm_file set */
Expand Down Expand Up @@ -2007,8 +2021,9 @@ static unsigned int khugepaged_scan_mm_slot(unsigned int pages,
break;
}

if (!(vma->vm_flags & VM_HUGEPAGE) &&
!khugepaged_always()) {
if ((!(vma->vm_flags & VM_HUGEPAGE) &&
!khugepaged_always()) ||
(vma->vm_flags & VM_NOHUGEPAGE)) {
progress++;
continue;
}
Expand Down
2 changes: 1 addition & 1 deletion trunk/mm/madvise.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ static long madvise_behavior(struct vm_area_struct * vma,
break;
case MADV_HUGEPAGE:
case MADV_NOHUGEPAGE:
error = hugepage_madvise(&new_flags, behavior);
error = hugepage_madvise(vma, &new_flags, behavior);
if (error)
goto out;
break;
Expand Down

0 comments on commit a20e586

Please sign in to comment.