From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
free_reserved_area() is related to memblock as it frees reserved memory
back to the buddy allocator, similar to what memblock_free_late() does.
Move free_reserved_area() to mm/memblock.c to prepare for further
consolidation of the functions that free reserved memory.
No functional changes.
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
mm/memblock.c | 37 ++++++++++++++++++++++++++++++++++++-
mm/page_alloc.c | 36 ------------------------------------
2 files changed, 36 insertions(+), 37 deletions(-)
diff --git a/mm/memblock.c b/mm/memblock.c
index b3ddfdec7a80..8f3010dddc58 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -893,6 +893,42 @@ int __init_memblock memblock_remove(phys_addr_t base, phys_addr_t size)
return memblock_remove_range(&memblock.memory, base, size);
}
+unsigned long free_reserved_area(void *start, void *end, int poison, const char *s)
+{
+ void *pos;
+ unsigned long pages = 0;
+
+ start = (void *)PAGE_ALIGN((unsigned long)start);
+ end = (void *)((unsigned long)end & PAGE_MASK);
+ for (pos = start; pos < end; pos += PAGE_SIZE, pages++) {
+ struct page *page = virt_to_page(pos);
+ void *direct_map_addr;
+
+ /*
+ * 'direct_map_addr' might be different from 'pos'
+ * because some architectures' virt_to_page()
+ * work with aliases. Getting the direct map
+ * address ensures that we get a _writeable_
+ * alias for the memset().
+ */
+ direct_map_addr = page_address(page);
+ /*
+ * Perform a kasan-unchecked memset() since this memory
+ * has not been initialized.
+ */
+ direct_map_addr = kasan_reset_tag(direct_map_addr);
+ if ((unsigned int)poison <= 0xFF)
+ memset(direct_map_addr, poison, PAGE_SIZE);
+
+ free_reserved_page(page);
+ }
+
+ if (pages && s)
+ pr_info("Freeing %s memory: %ldK\n", s, K(pages));
+
+ return pages;
+}
+
/**
* memblock_free - free boot memory allocation
* @ptr: starting address of the boot memory allocation
@@ -1776,7 +1812,6 @@ void __init memblock_free_late(phys_addr_t base, phys_addr_t size)
totalram_pages_inc();
}
}
-
/*
* Remaining API functions
*/
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 2d4b6f1a554e..df3d61253001 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -6234,42 +6234,6 @@ void adjust_managed_page_count(struct page *page, long count)
}
EXPORT_SYMBOL(adjust_managed_page_count);
-unsigned long free_reserved_area(void *start, void *end, int poison, const char *s)
-{
- void *pos;
- unsigned long pages = 0;
-
- start = (void *)PAGE_ALIGN((unsigned long)start);
- end = (void *)((unsigned long)end & PAGE_MASK);
- for (pos = start; pos < end; pos += PAGE_SIZE, pages++) {
- struct page *page = virt_to_page(pos);
- void *direct_map_addr;
-
- /*
- * 'direct_map_addr' might be different from 'pos'
- * because some architectures' virt_to_page()
- * work with aliases. Getting the direct map
- * address ensures that we get a _writeable_
- * alias for the memset().
- */
- direct_map_addr = page_address(page);
- /*
- * Perform a kasan-unchecked memset() since this memory
- * has not been initialized.
- */
- direct_map_addr = kasan_reset_tag(direct_map_addr);
- if ((unsigned int)poison <= 0xFF)
- memset(direct_map_addr, poison, PAGE_SIZE);
-
- free_reserved_page(page);
- }
-
- if (pages && s)
- pr_info("Freeing %s memory: %ldK\n", s, K(pages));
-
- return pages;
-}
-
void free_reserved_page(struct page *page)
{
clear_page_tag_ref(page);
--
2.51.0
On 3/18/26 11:58, Mike Rapoport wrote:
> From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
>
> free_reserved_area() is related to memblock as it frees reserved memory
> back to the buddy allocator, similar to what memblock_free_late() does.
>
> Move free_reserved_area() to mm/memblock.c to prepare for further
> consolidation of the functions that free reserved memory.
>
> No functional changes.
>
> Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Acked-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>
> ---
> mm/memblock.c | 37 ++++++++++++++++++++++++++++++++++++-
> mm/page_alloc.c | 36 ------------------------------------
> 2 files changed, 36 insertions(+), 37 deletions(-)
>
> diff --git a/mm/memblock.c b/mm/memblock.c
> index b3ddfdec7a80..8f3010dddc58 100644
> --- a/mm/memblock.c
> +++ b/mm/memblock.c
> @@ -893,6 +893,42 @@ int __init_memblock memblock_remove(phys_addr_t base, phys_addr_t size)
> return memblock_remove_range(&memblock.memory, base, size);
> }
>
> +unsigned long free_reserved_area(void *start, void *end, int poison, const char *s)
> +{
> + void *pos;
> + unsigned long pages = 0;
> +
> + start = (void *)PAGE_ALIGN((unsigned long)start);
> + end = (void *)((unsigned long)end & PAGE_MASK);
> + for (pos = start; pos < end; pos += PAGE_SIZE, pages++) {
> + struct page *page = virt_to_page(pos);
> + void *direct_map_addr;
> +
> + /*
> + * 'direct_map_addr' might be different from 'pos'
> + * because some architectures' virt_to_page()
> + * work with aliases. Getting the direct map
> + * address ensures that we get a _writeable_
> + * alias for the memset().
> + */
> + direct_map_addr = page_address(page);
> + /*
> + * Perform a kasan-unchecked memset() since this memory
> + * has not been initialized.
> + */
> + direct_map_addr = kasan_reset_tag(direct_map_addr);
> + if ((unsigned int)poison <= 0xFF)
> + memset(direct_map_addr, poison, PAGE_SIZE);
> +
> + free_reserved_page(page);
> + }
> +
> + if (pages && s)
> + pr_info("Freeing %s memory: %ldK\n", s, K(pages));
> +
> + return pages;
> +}
> +
> /**
> * memblock_free - free boot memory allocation
> * @ptr: starting address of the boot memory allocation
> @@ -1776,7 +1812,6 @@ void __init memblock_free_late(phys_addr_t base, phys_addr_t size)
> totalram_pages_inc();
> }
> }
> -
> /*
> * Remaining API functions
> */
> diff --git a/mm/page_alloc.c b/mm/page_alloc.c
> index 2d4b6f1a554e..df3d61253001 100644
> --- a/mm/page_alloc.c
> +++ b/mm/page_alloc.c
> @@ -6234,42 +6234,6 @@ void adjust_managed_page_count(struct page *page, long count)
> }
> EXPORT_SYMBOL(adjust_managed_page_count);
>
> -unsigned long free_reserved_area(void *start, void *end, int poison, const char *s)
> -{
> - void *pos;
> - unsigned long pages = 0;
> -
> - start = (void *)PAGE_ALIGN((unsigned long)start);
> - end = (void *)((unsigned long)end & PAGE_MASK);
> - for (pos = start; pos < end; pos += PAGE_SIZE, pages++) {
> - struct page *page = virt_to_page(pos);
> - void *direct_map_addr;
> -
> - /*
> - * 'direct_map_addr' might be different from 'pos'
> - * because some architectures' virt_to_page()
> - * work with aliases. Getting the direct map
> - * address ensures that we get a _writeable_
> - * alias for the memset().
> - */
> - direct_map_addr = page_address(page);
> - /*
> - * Perform a kasan-unchecked memset() since this memory
> - * has not been initialized.
> - */
> - direct_map_addr = kasan_reset_tag(direct_map_addr);
> - if ((unsigned int)poison <= 0xFF)
> - memset(direct_map_addr, poison, PAGE_SIZE);
> -
> - free_reserved_page(page);
> - }
> -
> - if (pages && s)
> - pr_info("Freeing %s memory: %ldK\n", s, K(pages));
> -
> - return pages;
> -}
> -
> void free_reserved_page(struct page *page)
> {
> clear_page_tag_ref(page);
© 2016 - 2026 Red Hat, Inc.