Skip to content

Commit 7fbc5e2

Browse files
committed
memblock: extract page freeing from free_reserved_area() into a helper
There are two functions that release pages to the buddy allocator late in the boot: free_reserved_area() and memblock_free_late(). Currently they are using different underlying functionality, free_reserved_area() runs each page being freed via free_reserved_page() and memblock_free_late() uses memblock_free_pages() -> __free_pages_core(), but in the end they both boil down to a loop that frees a range page by page. Extract the loop frees pages from free_reserved_area() into a helper and use that helper in memblock_free_late(). Link: https://patch.msgid.link/20260323074836.3653702-7-rppt@kernel.org Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
1 parent b8de957 commit 7fbc5e2

1 file changed

Lines changed: 29 additions & 26 deletions

File tree

mm/memblock.c

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -894,26 +894,12 @@ int __init_memblock memblock_remove(phys_addr_t base, phys_addr_t size)
894894
return memblock_remove_range(&memblock.memory, base, size);
895895
}
896896

897-
unsigned long free_reserved_area(void *start, void *end, int poison, const char *s)
897+
static unsigned long __free_reserved_area(phys_addr_t start, phys_addr_t end,
898+
int poison)
898899
{
899-
phys_addr_t start_pa, end_pa;
900900
unsigned long pages = 0, pfn;
901901

902-
/*
903-
* end is the first address past the region and it may be beyond what
904-
* __pa() or __pa_symbol() can handle.
905-
* Use the address included in the range for the conversion and add
906-
* back 1 afterwards.
907-
*/
908-
if (__is_kernel((unsigned long)start)) {
909-
start_pa = __pa_symbol(start);
910-
end_pa = __pa_symbol(end - 1) + 1;
911-
} else {
912-
start_pa = __pa(start);
913-
end_pa = __pa(end - 1) + 1;
914-
}
915-
916-
for_each_valid_pfn(pfn, PFN_UP(start_pa), PFN_DOWN(end_pa)) {
902+
for_each_valid_pfn(pfn, PFN_UP(start), PFN_DOWN(end)) {
917903
struct page *page = pfn_to_page(pfn);
918904
void *direct_map_addr;
919905

@@ -935,7 +921,29 @@ unsigned long free_reserved_area(void *start, void *end, int poison, const char
935921
free_reserved_page(page);
936922
pages++;
937923
}
924+
return pages;
925+
}
926+
927+
unsigned long free_reserved_area(void *start, void *end, int poison, const char *s)
928+
{
929+
phys_addr_t start_pa, end_pa;
930+
unsigned long pages;
931+
932+
/*
933+
* end is the first address past the region and it may be beyond what
934+
* __pa() or __pa_symbol() can handle.
935+
* Use the address included in the range for the conversion and add back
936+
* 1 afterwards.
937+
*/
938+
if (__is_kernel((unsigned long)start)) {
939+
start_pa = __pa_symbol(start);
940+
end_pa = __pa_symbol(end - 1) + 1;
941+
} else {
942+
start_pa = __pa(start);
943+
end_pa = __pa(end - 1) + 1;
944+
}
938945

946+
pages = __free_reserved_area(start_pa, end_pa, poison);
939947
if (pages && s)
940948
pr_info("Freeing %s memory: %ldK\n", s, K(pages));
941949

@@ -1811,20 +1819,15 @@ void *__init __memblock_alloc_or_panic(phys_addr_t size, phys_addr_t align,
18111819
*/
18121820
void __init memblock_free_late(phys_addr_t base, phys_addr_t size)
18131821
{
1814-
phys_addr_t cursor, end;
1822+
phys_addr_t end = base + size - 1;
18151823

1816-
end = base + size - 1;
18171824
memblock_dbg("%s: [%pa-%pa] %pS\n",
18181825
__func__, &base, &end, (void *)_RET_IP_);
1819-
kmemleak_free_part_phys(base, size);
1820-
cursor = PFN_UP(base);
1821-
end = PFN_DOWN(base + size);
18221826

1823-
for (; cursor < end; cursor++) {
1824-
memblock_free_pages(cursor, 0);
1825-
totalram_pages_inc();
1826-
}
1827+
kmemleak_free_part_phys(base, size);
1828+
__free_reserved_area(base, base + size, -1);
18271829
}
1830+
18281831
/*
18291832
* Remaining API functions
18301833
*/

0 commit comments

Comments
 (0)