aboutsummaryrefslogtreecommitdiffstats
path: root/mm/memory.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/memory.c')
-rw-r--r--mm/memory.c32
1 files changed, 15 insertions, 17 deletions
diff --git a/mm/memory.c b/mm/memory.c
index 153a54b2013c..e5628a5fd678 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -134,11 +134,9 @@ void pmd_clear_bad(pmd_t *pmd)
134 */ 134 */
135static void free_pte_range(struct mmu_gather *tlb, pmd_t *pmd) 135static void free_pte_range(struct mmu_gather *tlb, pmd_t *pmd)
136{ 136{
137 struct page *page = pmd_page(*pmd); 137 pgtable_t token = pmd_pgtable(*pmd);
138 pmd_clear(pmd); 138 pmd_clear(pmd);
139 pte_lock_deinit(page); 139 pte_free_tlb(tlb, token);
140 pte_free_tlb(tlb, page);
141 dec_zone_page_state(page, NR_PAGETABLE);
142 tlb->mm->nr_ptes--; 140 tlb->mm->nr_ptes--;
143} 141}
144 142
@@ -309,21 +307,19 @@ void free_pgtables(struct mmu_gather **tlb, struct vm_area_struct *vma,
309 307
310int __pte_alloc(struct mm_struct *mm, pmd_t *pmd, unsigned long address) 308int __pte_alloc(struct mm_struct *mm, pmd_t *pmd, unsigned long address)
311{ 309{
312 struct page *new = pte_alloc_one(mm, address); 310 pgtable_t new = pte_alloc_one(mm, address);
313 if (!new) 311 if (!new)
314 return -ENOMEM; 312 return -ENOMEM;
315 313
316 pte_lock_init(new);
317 spin_lock(&mm->page_table_lock); 314 spin_lock(&mm->page_table_lock);
318 if (pmd_present(*pmd)) { /* Another has populated it */ 315 if (!pmd_present(*pmd)) { /* Has another populated it ? */
319 pte_lock_deinit(new);
320 pte_free(mm, new);
321 } else {
322 mm->nr_ptes++; 316 mm->nr_ptes++;
323 inc_zone_page_state(new, NR_PAGETABLE);
324 pmd_populate(mm, pmd, new); 317 pmd_populate(mm, pmd, new);
318 new = NULL;
325 } 319 }
326 spin_unlock(&mm->page_table_lock); 320 spin_unlock(&mm->page_table_lock);
321 if (new)
322 pte_free(mm, new);
327 return 0; 323 return 0;
328} 324}
329 325
@@ -334,11 +330,13 @@ int __pte_alloc_kernel(pmd_t *pmd, unsigned long address)
334 return -ENOMEM; 330 return -ENOMEM;
335 331
336 spin_lock(&init_mm.page_table_lock); 332 spin_lock(&init_mm.page_table_lock);
337 if (pmd_present(*pmd)) /* Another has populated it */ 333 if (!pmd_present(*pmd)) { /* Has another populated it ? */
338 pte_free_kernel(&init_mm, new);
339 else
340 pmd_populate_kernel(&init_mm, pmd, new); 334 pmd_populate_kernel(&init_mm, pmd, new);
335 new = NULL;
336 }
341 spin_unlock(&init_mm.page_table_lock); 337 spin_unlock(&init_mm.page_table_lock);
338 if (new)
339 pte_free_kernel(&init_mm, new);
342 return 0; 340 return 0;
343} 341}
344 342
@@ -1390,7 +1388,7 @@ static int apply_to_pte_range(struct mm_struct *mm, pmd_t *pmd,
1390{ 1388{
1391 pte_t *pte; 1389 pte_t *pte;
1392 int err; 1390 int err;
1393 struct page *pmd_page; 1391 pgtable_t token;
1394 spinlock_t *uninitialized_var(ptl); 1392 spinlock_t *uninitialized_var(ptl);
1395 1393
1396 pte = (mm == &init_mm) ? 1394 pte = (mm == &init_mm) ?
@@ -1401,10 +1399,10 @@ static int apply_to_pte_range(struct mm_struct *mm, pmd_t *pmd,
1401 1399
1402 BUG_ON(pmd_huge(*pmd)); 1400 BUG_ON(pmd_huge(*pmd));
1403 1401
1404 pmd_page = pmd_page(*pmd); 1402 token = pmd_pgtable(*pmd);
1405 1403
1406 do { 1404 do {
1407 err = fn(pte, pmd_page, addr, data); 1405 err = fn(pte, token, addr, data);
1408 if (err) 1406 if (err)
1409 break; 1407 break;
1410 } while (pte++, addr += PAGE_SIZE, addr != end); 1408 } while (pte++, addr += PAGE_SIZE, addr != end);