Re: [PATCH] ACPI: NVS: replace __get_free_page() with kmalloc()

From: Rafael J. Wysocki (Intel)

Date: Tue Jul 21 2026 - 08:24:56 EST


On Tue, Jun 30, 2026 at 12:56 PM Mike Rapoport (Microsoft)
<rppt@xxxxxxxxxx> wrote:
>
> suspend_nvs_alloc() allocates shadow pages for saving and restoring
> ACPI Non-Volatile Storage regions across suspend/resume.
>
> These buffers can be allocated with kmalloc() as there's nothing special
> about them to go directly to the page allocator.
>
> kmalloc() provides a better API that does not require ugly casts and
> kfree() does not need to know the size of the freed object.
>
> Performance difference between kmalloc() and __get_free_pages() is not
> measurable as both allocators take an object/page from a per-CPU list for
> fast path allocations.
>
> For the slow path the performance is anyway determined by the amount of
> reclaim involved rather than by what allocator is used.
>
> Replace use of __get_free_page() with kmalloc() and free_page() with
> kfree().
>
> Link: https://lore.kernel.org/all/635405e4-9423-4a25-a6e7-e03c8ea0bcbe@xxxxxxxxxx
> Signed-off-by: Mike Rapoport (Microsoft) <rppt@xxxxxxxxxx>
> ---
> This is a (tiny) part of larger work of replacing page allocator calls
> with kmalloc:
>
> My initial intention a few month ago was to remove ugly casts [1], but then
> willy pointed out that Linus objected to something like this [2] and it
> looks like more than a decade old technical debt.
>
> [1] https://lore.kernel.org/all/20251018093002.3660549-1-rppt@xxxxxxxxxx/
> [2] https://lore.kernel.org/all/CA+55aFwp4iy4rtX2gE2WjBGFL=NxMVnoFeHqYa2j1dYOMMGqxg@xxxxxxxxxxxxxx/
>
> Also in git:
> https://git.kernel.org/pub/scm/linux/kernel/git/rppt/linux.git gfp-to-kmalloc/acpi
> ---
> drivers/acpi/nvs.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/acpi/nvs.c b/drivers/acpi/nvs.c
> index 6eaad7dd0241..12aee4102696 100644
> --- a/drivers/acpi/nvs.c
> +++ b/drivers/acpi/nvs.c
> @@ -133,7 +133,7 @@ void suspend_nvs_free(void)
>
> list_for_each_entry(entry, &nvs_list, node)
> if (entry->data) {
> - free_page((unsigned long)entry->data);
> + kfree(entry->data);
> entry->data = NULL;
> if (entry->kaddr) {
> if (entry->unmap) {
> @@ -156,7 +156,7 @@ int suspend_nvs_alloc(void)
> struct nvs_page *entry;
>
> list_for_each_entry(entry, &nvs_list, node) {
> - entry->data = (void *)__get_free_page(GFP_KERNEL);
> + entry->data = kmalloc(PAGE_SIZE, GFP_KERNEL);
> if (!entry->data) {
> suspend_nvs_free();
> return -ENOMEM;
>
> ---

Applied as 7.3 material, thanks!