Skip to content

Commit

Permalink
powerpc/mm: Refactor the floor/ceiling check in hugetlb range freeing…
Browse files Browse the repository at this point in the history
… 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
  • Loading branch information
Christophe Leroy authored and Michael Ellerman committed Dec 9, 2020
1 parent 5f1888a commit 7bfe54b
Showing 1 changed file with 19 additions and 37 deletions.
56 changes: 19 additions & 37 deletions arch/powerpc/mm/hugetlbpage.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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++)
Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 7bfe54b

Please sign in to comment.