diff options
author | Bob Liu <lliubbo@gmail.com> | 2012-12-11 19:00:37 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-11 20:22:22 -0500 |
commit | 6219049ae1ce32b89236646cccaec2a5fc6c4fd2 (patch) | |
tree | 551e8b1d53b8d237678c96cb9b442c746609cfcd /mm/huge_memory.c | |
parent | 344aa35c27acdf70d3c67b5aa7cb6aa8585f80c1 (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.c | 55 |
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) | |||
2363 | static void split_huge_page_address(struct mm_struct *mm, | 2338 | static 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 |