Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

authored by

Christophe Leroy and committed by
Michael Ellerman
7bfe54b5 5f1888a0

+19 -37
+19 -37
arch/powerpc/mm/hugetlbpage.c
··· 294 294 static inline void hugepd_free(struct mmu_gather *tlb, void *hugepte) {} 295 295 #endif 296 296 297 + /* Return true when the entry to be freed maps more than the area being freed */ 298 + static bool range_is_outside_limits(unsigned long start, unsigned long end, 299 + unsigned long floor, unsigned long ceiling, 300 + unsigned long mask) 301 + { 302 + if ((start & mask) < floor) 303 + return true; 304 + if (ceiling) { 305 + ceiling &= mask; 306 + if (!ceiling) 307 + return true; 308 + } 309 + return end - 1 > ceiling - 1; 310 + } 311 + 297 312 static void free_hugepd_range(struct mmu_gather *tlb, hugepd_t *hpdp, int pdshift, 298 313 unsigned long start, unsigned long end, 299 314 unsigned long floor, unsigned long ceiling) ··· 324 309 if (shift > pdshift) 325 310 num_hugepd = 1 << (shift - pdshift); 326 311 327 - start &= pdmask; 328 - if (start < floor) 329 - return; 330 - if (ceiling) { 331 - ceiling &= pdmask; 332 - if (! ceiling) 333 - return; 334 - } 335 - if (end - 1 > ceiling - 1) 312 + if (range_is_outside_limits(start, end, floor, ceiling, pdmask)) 336 313 return; 337 314 338 315 for (i = 0; i < num_hugepd; i++, hpdp++) ··· 341 334 unsigned long addr, unsigned long end, 342 335 unsigned long floor, unsigned long ceiling) 343 336 { 344 - unsigned long start = addr; 345 337 pgtable_t token = pmd_pgtable(*pmd); 346 338 347 - start &= PMD_MASK; 348 - if (start < floor) 349 - return; 350 - if (ceiling) { 351 - ceiling &= PMD_MASK; 352 - if (!ceiling) 353 - return; 354 - } 355 - if (end - 1 > ceiling - 1) 339 + if (range_is_outside_limits(addr, end, floor, ceiling, PMD_MASK)) 356 340 return; 357 341 358 342 pmd_clear(pmd); ··· 393 395 addr, next, floor, ceiling); 394 396 } while (addr = next, addr != end); 395 397 396 - start &= PUD_MASK; 397 - if (start < floor) 398 - return; 399 - if (ceiling) { 400 - ceiling &= PUD_MASK; 401 - if (!ceiling) 402 - return; 403 - } 404 - if (end - 1 > ceiling - 1) 398 + if (range_is_outside_limits(start, end, floor, ceiling, PUD_MASK)) 405 399 return; 406 400 407 401 pmd = pmd_offset(pud, start); ··· 436 446 } 437 447 } while (addr = next, addr != end); 438 448 439 - start &= PGDIR_MASK; 440 - if (start < floor) 441 - return; 442 - if (ceiling) { 443 - ceiling &= PGDIR_MASK; 444 - if (!ceiling) 445 - return; 446 - } 447 - if (end - 1 > ceiling - 1) 449 + if (range_is_outside_limits(start, end, floor, ceiling, PGDIR_MASK)) 448 450 return; 449 451 450 452 pud = pud_offset(p4d, start);