aboutsummaryrefslogtreecommitdiffstats
path: root/mm/huge_memory.c
diff options
context:
space:
mode:
authorBob Liu <lliubbo@gmail.com>2012-12-11 19:00:37 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-11 20:22:22 -0500
commit6219049ae1ce32b89236646cccaec2a5fc6c4fd2 (patch)
tree551e8b1d53b8d237678c96cb9b442c746609cfcd /mm/huge_memory.c
parent344aa35c27acdf70d3c67b5aa7cb6aa8585f80c1 (diff)
mm: introduce mm_find_pmd()
Several place need to find the pmd by(mm_struct, address), so introduce a function to simplify it. [akpm@linux-foundation.org: fix warning] Signed-off-by: Bob Liu <lliubbo@gmail.com> Cc: Andrea Arcangeli <aarcange@redhat.com> Cc: Michal Hocko <mhocko@suse.cz> Cc: Minchan Kim <minchan.kim@gmail.com> Cc: Ni zhan Chen <nizhan.chen@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/huge_memory.c')
-rw-r--r--mm/huge_memory.c55
1 files changed, 10 insertions, 45 deletions
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 6f022f505e88..9ae97242aa8d 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -1146,22 +1146,14 @@ pmd_t *page_check_address_pmd(struct page *page,
1146 unsigned long address, 1146 unsigned long address,
1147 enum page_check_address_pmd_flag flag) 1147 enum page_check_address_pmd_flag flag)
1148{ 1148{
1149 pgd_t *pgd;
1150 pud_t *pud;
1151 pmd_t *pmd, *ret = NULL; 1149 pmd_t *pmd, *ret = NULL;
1152 1150
1153 if (address & ~HPAGE_PMD_MASK) 1151 if (address & ~HPAGE_PMD_MASK)
1154 goto out; 1152 goto out;
1155 1153
1156 pgd = pgd_offset(mm, address); 1154 pmd = mm_find_pmd(mm, address);
1157 if (!pgd_present(*pgd)) 1155 if (!pmd)
1158 goto out; 1156 goto out;
1159
1160 pud = pud_offset(pgd, address);
1161 if (!pud_present(*pud))
1162 goto out;
1163
1164 pmd = pmd_offset(pud, address);
1165 if (pmd_none(*pmd)) 1157 if (pmd_none(*pmd))
1166 goto out; 1158 goto out;
1167 if (pmd_page(*pmd) != page) 1159 if (pmd_page(*pmd) != page)
@@ -1908,8 +1900,6 @@ static void collapse_huge_page(struct mm_struct *mm,
1908 struct vm_area_struct *vma, 1900 struct vm_area_struct *vma,
1909 int node) 1901 int node)
1910{ 1902{
1911 pgd_t *pgd;
1912 pud_t *pud;
1913 pmd_t *pmd, _pmd; 1903 pmd_t *pmd, _pmd;
1914 pte_t *pte; 1904 pte_t *pte;
1915 pgtable_t pgtable; 1905 pgtable_t pgtable;
@@ -1955,17 +1945,10 @@ static void collapse_huge_page(struct mm_struct *mm,
1955 goto out; 1945 goto out;
1956 VM_BUG_ON(vma->vm_flags & VM_NO_THP); 1946 VM_BUG_ON(vma->vm_flags & VM_NO_THP);
1957 1947
1958 pgd = pgd_offset(mm, address); 1948 pmd = mm_find_pmd(mm, address);
1959 if (!pgd_present(*pgd)) 1949 if (!pmd)
1960 goto out; 1950 goto out;
1961 1951 if (pmd_trans_huge(*pmd))
1962 pud = pud_offset(pgd, address);
1963 if (!pud_present(*pud))
1964 goto out;
1965
1966 pmd = pmd_offset(pud, address);
1967 /* pmd can't go away or become huge under us */
1968 if (!pmd_present(*pmd) || pmd_trans_huge(*pmd))
1969 goto out; 1952 goto out;
1970 1953
1971 anon_vma_lock(vma->anon_vma); 1954 anon_vma_lock(vma->anon_vma);
@@ -2048,8 +2031,6 @@ static int khugepaged_scan_pmd(struct mm_struct *mm,
2048 unsigned long address, 2031 unsigned long address,
2049 struct page **hpage) 2032 struct page **hpage)
2050{ 2033{
2051 pgd_t *pgd;
2052 pud_t *pud;
2053 pmd_t *pmd; 2034 pmd_t *pmd;
2054 pte_t *pte, *_pte; 2035 pte_t *pte, *_pte;
2055 int ret = 0, referenced = 0, none = 0; 2036 int ret = 0, referenced = 0, none = 0;
@@ -2060,16 +2041,10 @@ static int khugepaged_scan_pmd(struct mm_struct *mm,
2060 2041
2061 VM_BUG_ON(address & ~HPAGE_PMD_MASK); 2042 VM_BUG_ON(address & ~HPAGE_PMD_MASK);
2062 2043
2063 pgd = pgd_offset(mm, address); 2044 pmd = mm_find_pmd(mm, address);
2064 if (!pgd_present(*pgd)) 2045 if (!pmd)
2065 goto out; 2046 goto out;
2066 2047 if (pmd_trans_huge(*pmd))
2067 pud = pud_offset(pgd, address);
2068 if (!pud_present(*pud))
2069 goto out;
2070
2071 pmd = pmd_offset(pud, address);
2072 if (!pmd_present(*pmd) || pmd_trans_huge(*pmd))
2073 goto out; 2048 goto out;
2074 2049
2075 pte = pte_offset_map_lock(mm, pmd, address, &ptl); 2050 pte = pte_offset_map_lock(mm, pmd, address, &ptl);
@@ -2363,22 +2338,12 @@ void __split_huge_page_pmd(struct mm_struct *mm, pmd_t *pmd)
2363static void split_huge_page_address(struct mm_struct *mm, 2338static void split_huge_page_address(struct mm_struct *mm,
2364 unsigned long address) 2339 unsigned long address)
2365{ 2340{
2366 pgd_t *pgd;
2367 pud_t *pud;
2368 pmd_t *pmd; 2341 pmd_t *pmd;
2369 2342
2370 VM_BUG_ON(!(address & ~HPAGE_PMD_MASK)); 2343 VM_BUG_ON(!(address & ~HPAGE_PMD_MASK));
2371 2344
2372 pgd = pgd_offset(mm, address); 2345 pmd = mm_find_pmd(mm, address);
2373 if (!pgd_present(*pgd)) 2346 if (!pmd)
2374 return;
2375
2376 pud = pud_offset(pgd, address);
2377 if (!pud_present(*pud))
2378 return;
2379
2380 pmd = pmd_offset(pud, address);
2381 if (!pmd_present(*pmd))
2382 return; 2347 return;
2383 /* 2348 /*
2384 * Caller holds the mmap_sem write mode, so a huge pmd cannot 2349 * Caller holds the mmap_sem write mode, so a huge pmd cannot