mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-04 01:24:12 +08:00
powerpc/mm: Refactor the floor/ceiling check in hugetlb range freeing functions
All hugetlb range freeing functions have a verification like the following, which only differs by the mask used, depending on the page table level. start &= MASK; if (start < floor) return; if (ceiling) { ceiling &= MASK; if (! ceiling) return; } if (end - 1 > ceiling - 1) return; Refactor that into a helper function which takes the mask as an argument, returning true when [start;end[ is not fully contained inside [floor;ceiling[ Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> Reviewed-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/16a571bb32eb6e8cd44bda484c8d81cd8a25e6d7.1604668827.git.christophe.leroy@csgroup.eu
This commit is contained in:
parent
5f1888a077
commit
7bfe54b5f1
@ -294,6 +294,21 @@ static void hugepd_free(struct mmu_gather *tlb, void *hugepte)
|
||||
static inline void hugepd_free(struct mmu_gather *tlb, void *hugepte) {}
|
||||
#endif
|
||||
|
||||
/* Return true when the entry to be freed maps more than the area being freed */
|
||||
static bool range_is_outside_limits(unsigned long start, unsigned long end,
|
||||
unsigned long floor, unsigned long ceiling,
|
||||
unsigned long mask)
|
||||
{
|
||||
if ((start & mask) < floor)
|
||||
return true;
|
||||
if (ceiling) {
|
||||
ceiling &= mask;
|
||||
if (!ceiling)
|
||||
return true;
|
||||
}
|
||||
return end - 1 > ceiling - 1;
|
||||
}
|
||||
|
||||
static void free_hugepd_range(struct mmu_gather *tlb, hugepd_t *hpdp, int pdshift,
|
||||
unsigned long start, unsigned long end,
|
||||
unsigned long floor, unsigned long ceiling)
|
||||
@ -309,15 +324,7 @@ static void free_hugepd_range(struct mmu_gather *tlb, hugepd_t *hpdp, int pdshif
|
||||
if (shift > pdshift)
|
||||
num_hugepd = 1 << (shift - pdshift);
|
||||
|
||||
start &= pdmask;
|
||||
if (start < floor)
|
||||
return;
|
||||
if (ceiling) {
|
||||
ceiling &= pdmask;
|
||||
if (! ceiling)
|
||||
return;
|
||||
}
|
||||
if (end - 1 > ceiling - 1)
|
||||
if (range_is_outside_limits(start, end, floor, ceiling, pdmask))
|
||||
return;
|
||||
|
||||
for (i = 0; i < num_hugepd; i++, hpdp++)
|
||||
@ -334,18 +341,9 @@ static void hugetlb_free_pte_range(struct mmu_gather *tlb, pmd_t *pmd,
|
||||
unsigned long addr, unsigned long end,
|
||||
unsigned long floor, unsigned long ceiling)
|
||||
{
|
||||
unsigned long start = addr;
|
||||
pgtable_t token = pmd_pgtable(*pmd);
|
||||
|
||||
start &= PMD_MASK;
|
||||
if (start < floor)
|
||||
return;
|
||||
if (ceiling) {
|
||||
ceiling &= PMD_MASK;
|
||||
if (!ceiling)
|
||||
return;
|
||||
}
|
||||
if (end - 1 > ceiling - 1)
|
||||
if (range_is_outside_limits(addr, end, floor, ceiling, PMD_MASK))
|
||||
return;
|
||||
|
||||
pmd_clear(pmd);
|
||||
@ -395,15 +393,7 @@ static void hugetlb_free_pmd_range(struct mmu_gather *tlb, pud_t *pud,
|
||||
addr, next, floor, ceiling);
|
||||
} while (addr = next, addr != end);
|
||||
|
||||
start &= PUD_MASK;
|
||||
if (start < floor)
|
||||
return;
|
||||
if (ceiling) {
|
||||
ceiling &= PUD_MASK;
|
||||
if (!ceiling)
|
||||
return;
|
||||
}
|
||||
if (end - 1 > ceiling - 1)
|
||||
if (range_is_outside_limits(start, end, floor, ceiling, PUD_MASK))
|
||||
return;
|
||||
|
||||
pmd = pmd_offset(pud, start);
|
||||
@ -446,15 +436,7 @@ static void hugetlb_free_pud_range(struct mmu_gather *tlb, p4d_t *p4d,
|
||||
}
|
||||
} while (addr = next, addr != end);
|
||||
|
||||
start &= PGDIR_MASK;
|
||||
if (start < floor)
|
||||
return;
|
||||
if (ceiling) {
|
||||
ceiling &= PGDIR_MASK;
|
||||
if (!ceiling)
|
||||
return;
|
||||
}
|
||||
if (end - 1 > ceiling - 1)
|
||||
if (range_is_outside_limits(start, end, floor, ceiling, PGDIR_MASK))
|
||||
return;
|
||||
|
||||
pud = pud_offset(p4d, start);
|
||||
|
Loading…
Reference in New Issue
Block a user