hugetlbpage.c (ee01c4d72adffb7d424535adf630f2955748fa8b) hugetlbpage.c (2fb4706057bcf8261b3b0521ec7a62b54b82ce48)
1/*
2 * PPC Huge TLB Page Support for Kernel.
3 *
4 * Copyright (C) 2003 David Gibson, IBM Corporation.
5 * Copyright (C) 2011 Becky Bruce, Freescale Semiconductor
6 *
7 * Based on the IA-32 version:
8 * Copyright (C) 2002, Rohit Seth <rohit.seth@intel.com>

--- 105 unchanged lines hidden (view full) ---

114
115/*
116 * At this point we do the placement change only for BOOK3S 64. This would
117 * possibly work on other subarchs.
118 */
119pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr, unsigned long sz)
120{
121 pgd_t *pg;
1/*
2 * PPC Huge TLB Page Support for Kernel.
3 *
4 * Copyright (C) 2003 David Gibson, IBM Corporation.
5 * Copyright (C) 2011 Becky Bruce, Freescale Semiconductor
6 *
7 * Based on the IA-32 version:
8 * Copyright (C) 2002, Rohit Seth <rohit.seth@intel.com>

--- 105 unchanged lines hidden (view full) ---

114
115/*
116 * At this point we do the placement change only for BOOK3S 64. This would
117 * possibly work on other subarchs.
118 */
119pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr, unsigned long sz)
120{
121 pgd_t *pg;
122 p4d_t *p4;
122 pud_t *pu;
123 pmd_t *pm;
124 hugepd_t *hpdp = NULL;
125 unsigned pshift = __ffs(sz);
126 unsigned pdshift = PGDIR_SHIFT;
127 spinlock_t *ptl;
128
129 addr &= ~(sz-1);
130 pg = pgd_offset(mm, addr);
123 pud_t *pu;
124 pmd_t *pm;
125 hugepd_t *hpdp = NULL;
126 unsigned pshift = __ffs(sz);
127 unsigned pdshift = PGDIR_SHIFT;
128 spinlock_t *ptl;
129
130 addr &= ~(sz-1);
131 pg = pgd_offset(mm, addr);
132 p4 = p4d_offset(pg, addr);
131
132#ifdef CONFIG_PPC_BOOK3S_64
133 if (pshift == PGDIR_SHIFT)
134 /* 16GB huge page */
133
134#ifdef CONFIG_PPC_BOOK3S_64
135 if (pshift == PGDIR_SHIFT)
136 /* 16GB huge page */
135 return (pte_t *) pg;
137 return (pte_t *) p4;
136 else if (pshift > PUD_SHIFT) {
137 /*
138 * We need to use hugepd table
139 */
140 ptl = &mm->page_table_lock;
138 else if (pshift > PUD_SHIFT) {
139 /*
140 * We need to use hugepd table
141 */
142 ptl = &mm->page_table_lock;
141 hpdp = (hugepd_t *)pg;
143 hpdp = (hugepd_t *)p4;
142 } else {
143 pdshift = PUD_SHIFT;
144 } else {
145 pdshift = PUD_SHIFT;
144 pu = pud_alloc(mm, pg, addr);
146 pu = pud_alloc(mm, p4, addr);
145 if (!pu)
146 return NULL;
147 if (pshift == PUD_SHIFT)
148 return (pte_t *)pu;
149 else if (pshift > PMD_SHIFT) {
150 ptl = pud_lockptr(mm, pu);
151 hpdp = (hugepd_t *)pu;
152 } else {

--- 8 unchanged lines hidden (view full) ---

161 ptl = pmd_lockptr(mm, pm);
162 hpdp = (hugepd_t *)pm;
163 }
164 }
165 }
166#else
167 if (pshift >= PGDIR_SHIFT) {
168 ptl = &mm->page_table_lock;
147 if (!pu)
148 return NULL;
149 if (pshift == PUD_SHIFT)
150 return (pte_t *)pu;
151 else if (pshift > PMD_SHIFT) {
152 ptl = pud_lockptr(mm, pu);
153 hpdp = (hugepd_t *)pu;
154 } else {

--- 8 unchanged lines hidden (view full) ---

163 ptl = pmd_lockptr(mm, pm);
164 hpdp = (hugepd_t *)pm;
165 }
166 }
167 }
168#else
169 if (pshift >= PGDIR_SHIFT) {
170 ptl = &mm->page_table_lock;
169 hpdp = (hugepd_t *)pg;
171 hpdp = (hugepd_t *)p4;
170 } else {
171 pdshift = PUD_SHIFT;
172 } else {
173 pdshift = PUD_SHIFT;
172 pu = pud_alloc(mm, pg, addr);
174 pu = pud_alloc(mm, p4, addr);
173 if (!pu)
174 return NULL;
175 if (pshift >= PUD_SHIFT) {
176 ptl = pud_lockptr(mm, pu);
177 hpdp = (hugepd_t *)pu;
178 } else {
179 pdshift = PMD_SHIFT;
180 pm = pmd_alloc(mm, pu, addr);

--- 204 unchanged lines hidden (view full) ---

385 return;
386
387 pmd = pmd_offset(pud, start);
388 pud_clear(pud);
389 pmd_free_tlb(tlb, pmd, start);
390 mm_dec_nr_pmds(tlb->mm);
391}
392
175 if (!pu)
176 return NULL;
177 if (pshift >= PUD_SHIFT) {
178 ptl = pud_lockptr(mm, pu);
179 hpdp = (hugepd_t *)pu;
180 } else {
181 pdshift = PMD_SHIFT;
182 pm = pmd_alloc(mm, pu, addr);

--- 204 unchanged lines hidden (view full) ---

387 return;
388
389 pmd = pmd_offset(pud, start);
390 pud_clear(pud);
391 pmd_free_tlb(tlb, pmd, start);
392 mm_dec_nr_pmds(tlb->mm);
393}
394
393static void hugetlb_free_pud_range(struct mmu_gather *tlb, pgd_t *pgd,
395static void hugetlb_free_pud_range(struct mmu_gather *tlb, p4d_t *p4d,
394 unsigned long addr, unsigned long end,
395 unsigned long floor, unsigned long ceiling)
396{
397 pud_t *pud;
398 unsigned long next;
399 unsigned long start;
400
401 start = addr;
402 do {
396 unsigned long addr, unsigned long end,
397 unsigned long floor, unsigned long ceiling)
398{
399 pud_t *pud;
400 unsigned long next;
401 unsigned long start;
402
403 start = addr;
404 do {
403 pud = pud_offset(pgd, addr);
405 pud = pud_offset(p4d, addr);
404 next = pud_addr_end(addr, end);
405 if (!is_hugepd(__hugepd(pud_val(*pud)))) {
406 if (pud_none_or_clear_bad(pud))
407 continue;
408 hugetlb_free_pmd_range(tlb, pud, addr, next, floor,
409 ceiling);
410 } else {
411 unsigned long more;

--- 18 unchanged lines hidden (view full) ---

430 if (ceiling) {
431 ceiling &= PGDIR_MASK;
432 if (!ceiling)
433 return;
434 }
435 if (end - 1 > ceiling - 1)
436 return;
437
406 next = pud_addr_end(addr, end);
407 if (!is_hugepd(__hugepd(pud_val(*pud)))) {
408 if (pud_none_or_clear_bad(pud))
409 continue;
410 hugetlb_free_pmd_range(tlb, pud, addr, next, floor,
411 ceiling);
412 } else {
413 unsigned long more;

--- 18 unchanged lines hidden (view full) ---

432 if (ceiling) {
433 ceiling &= PGDIR_MASK;
434 if (!ceiling)
435 return;
436 }
437 if (end - 1 > ceiling - 1)
438 return;
439
438 pud = pud_offset(pgd, start);
439 pgd_clear(pgd);
440 pud = pud_offset(p4d, start);
441 p4d_clear(p4d);
440 pud_free_tlb(tlb, pud, start);
441 mm_dec_nr_puds(tlb->mm);
442}
443
444/*
445 * This function frees user-level page tables of a process.
446 */
447void hugetlb_free_pgd_range(struct mmu_gather *tlb,
448 unsigned long addr, unsigned long end,
449 unsigned long floor, unsigned long ceiling)
450{
451 pgd_t *pgd;
442 pud_free_tlb(tlb, pud, start);
443 mm_dec_nr_puds(tlb->mm);
444}
445
446/*
447 * This function frees user-level page tables of a process.
448 */
449void hugetlb_free_pgd_range(struct mmu_gather *tlb,
450 unsigned long addr, unsigned long end,
451 unsigned long floor, unsigned long ceiling)
452{
453 pgd_t *pgd;
454 p4d_t *p4d;
452 unsigned long next;
453
454 /*
455 * Because there are a number of different possible pagetable
456 * layouts for hugepage ranges, we limit knowledge of how
457 * things should be laid out to the allocation path
458 * (huge_pte_alloc(), above). Everything else works out the
459 * structure as it goes from information in the hugepd

--- 6 unchanged lines hidden (view full) ---

466 * To make sense of this, you should probably go read the big
467 * block comment at the top of the normal free_pgd_range(),
468 * too.
469 */
470
471 do {
472 next = pgd_addr_end(addr, end);
473 pgd = pgd_offset(tlb->mm, addr);
455 unsigned long next;
456
457 /*
458 * Because there are a number of different possible pagetable
459 * layouts for hugepage ranges, we limit knowledge of how
460 * things should be laid out to the allocation path
461 * (huge_pte_alloc(), above). Everything else works out the
462 * structure as it goes from information in the hugepd

--- 6 unchanged lines hidden (view full) ---

469 * To make sense of this, you should probably go read the big
470 * block comment at the top of the normal free_pgd_range(),
471 * too.
472 */
473
474 do {
475 next = pgd_addr_end(addr, end);
476 pgd = pgd_offset(tlb->mm, addr);
477 p4d = p4d_offset(pgd, addr);
474 if (!is_hugepd(__hugepd(pgd_val(*pgd)))) {
478 if (!is_hugepd(__hugepd(pgd_val(*pgd)))) {
475 if (pgd_none_or_clear_bad(pgd))
479 if (p4d_none_or_clear_bad(p4d))
476 continue;
480 continue;
477 hugetlb_free_pud_range(tlb, pgd, addr, next, floor, ceiling);
481 hugetlb_free_pud_range(tlb, p4d, addr, next, floor, ceiling);
478 } else {
479 unsigned long more;
480 /*
481 * Increment next by the size of the huge mapping since
482 * there may be more than one entry at the pgd level
483 * for a single hugepage, but all of them point to the
484 * same kmem cache that holds the hugepte.
485 */
486 more = addr + (1 << hugepd_shift(*(hugepd_t *)pgd));
487 if (more > next)
488 next = more;
489
482 } else {
483 unsigned long more;
484 /*
485 * Increment next by the size of the huge mapping since
486 * there may be more than one entry at the pgd level
487 * for a single hugepage, but all of them point to the
488 * same kmem cache that holds the hugepte.
489 */
490 more = addr + (1 << hugepd_shift(*(hugepd_t *)pgd));
491 if (more > next)
492 next = more;
493
490 free_hugepd_range(tlb, (hugepd_t *)pgd, PGDIR_SHIFT,
494 free_hugepd_range(tlb, (hugepd_t *)p4d, PGDIR_SHIFT,
491 addr, next, floor, ceiling);
492 }
493 } while (addr = next, addr != end);
494}
495
496struct page *follow_huge_pd(struct vm_area_struct *vma,
497 unsigned long address, hugepd_t hpd,
498 int flags, int pdshift)

--- 178 unchanged lines hidden ---
495 addr, next, floor, ceiling);
496 }
497 } while (addr = next, addr != end);
498}
499
500struct page *follow_huge_pd(struct vm_area_struct *vma,
501 unsigned long address, hugepd_t hpd,
502 int flags, int pdshift)

--- 178 unchanged lines hidden ---