Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 344792
b: refs/heads/master
c: 4daae3b
h: refs/heads/master
v: v3
  • Loading branch information
Mel Gorman committed Dec 11, 2012
1 parent 9e71691 commit 8a7be32
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 13 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: 149c33e1c98f83050870514f380902dc6d617bd5
refs/heads/master: 4daae3b4b9e49b7e0935499a352f1c59d90287d2
9 changes: 5 additions & 4 deletions trunk/include/linux/huge_mm.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,8 @@ static inline struct page *compound_trans_head(struct page *page)
return page;
}

extern int do_huge_pmd_numa_page(struct mm_struct *mm, unsigned long addr,
pmd_t pmd, pmd_t *pmdp);
extern int do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
unsigned long addr, pmd_t pmd, pmd_t *pmdp);

#else /* CONFIG_TRANSPARENT_HUGEPAGE */
#define HPAGE_PMD_SHIFT ({ BUILD_BUG(); 0; })
Expand Down Expand Up @@ -200,9 +200,10 @@ static inline int pmd_trans_huge_lock(pmd_t *pmd,
return 0;
}

static inline int do_huge_pmd_numa_page(struct mm_struct *mm, unsigned long addr,
pmd_t pmd, pmd_t *pmdp)
static inline int do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
unsigned long addr, pmd_t pmd, pmd_t *pmdp)
{
return 0;
}

#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
Expand Down
31 changes: 28 additions & 3 deletions trunk/mm/huge_memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <linux/freezer.h>
#include <linux/mman.h>
#include <linux/pagemap.h>
#include <linux/migrate.h>
#include <asm/tlb.h>
#include <asm/pgalloc.h>
#include "internal.h"
Expand Down Expand Up @@ -1019,24 +1020,48 @@ struct page *follow_trans_huge_pmd(struct vm_area_struct *vma,
}

/* NUMA hinting page fault entry point for trans huge pmds */
int do_huge_pmd_numa_page(struct mm_struct *mm, unsigned long addr,
pmd_t pmd, pmd_t *pmdp)
int do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
unsigned long addr, pmd_t pmd, pmd_t *pmdp)
{
struct page *page;
struct page *page = NULL;
unsigned long haddr = addr & HPAGE_PMD_MASK;
int target_nid;

spin_lock(&mm->page_table_lock);
if (unlikely(!pmd_same(pmd, *pmdp)))
goto out_unlock;

page = pmd_page(pmd);
get_page(page);
spin_unlock(&mm->page_table_lock);

target_nid = mpol_misplaced(page, vma, haddr);
if (target_nid == -1)
goto clear_pmdnuma;

/*
* Due to lacking code to migrate thp pages, we'll split
* (which preserves the special PROT_NONE) and re-take the
* fault on the normal pages.
*/
split_huge_page(page);
put_page(page);
return 0;

clear_pmdnuma:
spin_lock(&mm->page_table_lock);
if (unlikely(!pmd_same(pmd, *pmdp)))
goto out_unlock;

pmd = pmd_mknonnuma(pmd);
set_pmd_at(mm, haddr, pmdp, pmd);
VM_BUG_ON(pmd_numa(*pmdp));
update_mmu_cache_pmd(vma, addr, pmdp);

out_unlock:
spin_unlock(&mm->page_table_lock);
if (page)
put_page(page);
return 0;
}

Expand Down
32 changes: 27 additions & 5 deletions trunk/mm/memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
#include <linux/swapops.h>
#include <linux/elf.h>
#include <linux/gfp.h>
#include <linux/migrate.h>

#include <asm/io.h>
#include <asm/pgalloc.h>
Expand Down Expand Up @@ -3451,8 +3452,9 @@ static int do_nonlinear_fault(struct mm_struct *mm, struct vm_area_struct *vma,
int do_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
unsigned long addr, pte_t pte, pte_t *ptep, pmd_t *pmd)
{
struct page *page;
struct page *page = NULL;
spinlock_t *ptl;
int current_nid, target_nid;

/*
* The "pte" at this point cannot be used safely without
Expand All @@ -3465,8 +3467,11 @@ int do_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
*/
ptl = pte_lockptr(mm, pmd);
spin_lock(ptl);
if (unlikely(!pte_same(*ptep, pte)))
goto out_unlock;
if (unlikely(!pte_same(*ptep, pte))) {
pte_unmap_unlock(ptep, ptl);
goto out;
}

pte = pte_mknonnuma(pte);
set_pte_at(mm, addr, ptep, pte);
update_mmu_cache(vma, addr, ptep);
Expand All @@ -3477,8 +3482,25 @@ int do_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
return 0;
}

out_unlock:
get_page(page);
current_nid = page_to_nid(page);
target_nid = mpol_misplaced(page, vma, addr);
pte_unmap_unlock(ptep, ptl);
if (target_nid == -1) {
/*
* Account for the fault against the current node if it not
* being replaced regardless of where the page is located.
*/
current_nid = numa_node_id();
put_page(page);
goto out;
}

/* Migrate to the requested node */
if (migrate_misplaced_page(page, target_nid))
current_nid = target_nid;

out:
return 0;
}

Expand Down Expand Up @@ -3655,7 +3677,7 @@ int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma,
barrier();
if (pmd_trans_huge(orig_pmd)) {
if (pmd_numa(*pmd))
return do_huge_pmd_numa_page(mm, address,
return do_huge_pmd_numa_page(mm, vma, address,
orig_pmd, pmd);

if ((flags & FAULT_FLAG_WRITE) && !pmd_write(orig_pmd)) {
Expand Down

0 comments on commit 8a7be32

Please sign in to comment.