Skip to content

Commit

Permalink
pagewalk: don't look up vma if walk->hugetlb_entry is unused
Browse files Browse the repository at this point in the history
Currently, walk_page_range() calls find_vma() every page table for walk
iteration.  but it's completely unnecessary if walk->hugetlb_entry is
unused.  And we don't have to assume find_vma() is a lightweight
operation.  So this patch checks the walk->hugetlb_entry and avoids the
find_vma() call if possible.

This patch also makes some cleanups.  1) remove ugly uninitialized_var()
and 2) #ifdef in function body.

Signed-off-by: KOSAKI Motohiro <[email protected]>
Cc: Naoya Horiguchi <[email protected]>
Cc: Hiroyuki Kamezawa <[email protected]>
Cc: Andrea Arcangeli <[email protected]>
Cc: Matt Mackall <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
kosaki authored and torvalds committed Jul 26, 2011
1 parent 4b6ddbf commit 6c6d528
Showing 1 changed file with 37 additions and 6 deletions.
43 changes: 37 additions & 6 deletions mm/pagewalk.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,39 @@ static int walk_hugetlb_range(struct vm_area_struct *vma,

return 0;
}
#endif

static struct vm_area_struct* hugetlb_vma(unsigned long addr, struct mm_walk *walk)
{
struct vm_area_struct *vma;

/* We don't need vma lookup at all. */
if (!walk->hugetlb_entry)
return NULL;

VM_BUG_ON(!rwsem_is_locked(&walk->mm->mmap_sem));
vma = find_vma(walk->mm, addr);
if (vma && vma->vm_start <= addr && is_vm_hugetlb_page(vma))
return vma;

return NULL;
}

#else /* CONFIG_HUGETLB_PAGE */
static struct vm_area_struct* hugetlb_vma(unsigned long addr, struct mm_walk *walk)
{
return NULL;
}

static int walk_hugetlb_range(struct vm_area_struct *vma,
unsigned long addr, unsigned long end,
struct mm_walk *walk)
{
return 0;
}

#endif /* CONFIG_HUGETLB_PAGE */



/**
* walk_page_range - walk a memory map's page tables with a callback
Expand Down Expand Up @@ -165,18 +197,17 @@ int walk_page_range(unsigned long addr, unsigned long end,

pgd = pgd_offset(walk->mm, addr);
do {
struct vm_area_struct *uninitialized_var(vma);
struct vm_area_struct *vma;

next = pgd_addr_end(addr, end);

#ifdef CONFIG_HUGETLB_PAGE
/*
* handle hugetlb vma individually because pagetable walk for
* the hugetlb page is dependent on the architecture and
* we can't handled it in the same manner as non-huge pages.
*/
vma = find_vma(walk->mm, addr);
if (vma && vma->vm_start <= addr && is_vm_hugetlb_page(vma)) {
vma = hugetlb_vma(addr, walk);
if (vma) {
if (vma->vm_end < next)
next = vma->vm_end;
/*
Expand All @@ -189,7 +220,7 @@ int walk_page_range(unsigned long addr, unsigned long end,
pgd = pgd_offset(walk->mm, next);
continue;
}
#endif

if (pgd_none_or_clear_bad(pgd)) {
if (walk->pte_hole)
err = walk->pte_hole(addr, next, walk);
Expand Down

0 comments on commit 6c6d528

Please sign in to comment.