Re: [PATCH] ACPI: sysfs: Release the table references taken during init
From: Rafael J. Wysocki (Intel)
Date: Fri Nov 13 2026 - 15:49:25 EST
On Tue, Nov 10, 2026 at 11:55 PM Jamie Nguyen <jamien@xxxxxxxxxx> wrote:
>
> acpi_tables_sysfs_init() gets each table with acpi_get_table_by_index()
> to create its file, and acpi_table_attr_init() gets the second instance
> of the table's signature with acpi_get_table() to decide whether the
> file name needs an instance number. Neither reference is ever released,
> so every table stays mapped. The file's read handler already gets and
> puts the table on each read.
>
> Release both references once the table is no longer used.
>
> Fixes: 174cc7187e6f ("ACPICA: Tables: Back port acpi_get_table_with_size() and early_acpi_os_unmap_memory() from Linux kernel")
> Signed-off-by: Jamie Nguyen <jamien@xxxxxxxxxx>
> ---
> Sashiko flagged this, as a pre-existing issue, in its review of a
> previous patch that I sent:
> https://sashiko.dev/#/patchset/20261013193900.1258808-1-jamien%40nvidia.com
>
> With the references released, a table that nothing else holds is
> unmapped after init, and each read of its file maps it again
> (acpi_table_show() already gets and puts the table).
>
> Tested on an arm64 server and in QEMU (x86_64), with a test-only change
> that prints each table's validation count after boot:
> - Every table's count is one lower, and the second SSDT's is two lower,
> since the instance check in acpi_table_attr_init() also held it.
> - All table files read back the same as without the patch, and
> repeated and parallel reads leave the counts unchanged.
> - The BERT and BDAT data files still match /dev/mem.
> - Loading and unloading SSDTs through ACPI configfs still works (QEMU).
>
> drivers/acpi/sysfs.c | 7 ++++++-
> 1 file changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c
> index 49a820b39c2917a..d1b57d1246aafb1 100644
> --- a/drivers/acpi/sysfs.c
> +++ b/drivers/acpi/sysfs.c
> @@ -372,6 +372,7 @@ static int acpi_table_attr_init(struct kobject *tables_obj,
> table_attr->instance);
> strcat(table_attr->filename, instance_str);
> }
> + acpi_put_table(header);
>
> table_attr->attr.size = table_header->length;
> table_attr->attr.read = acpi_table_show;
> @@ -593,15 +594,19 @@ static int acpi_tables_sysfs_init(void)
> continue;
>
> table_attr = kzalloc_obj(*table_attr);
> - if (!table_attr)
> + if (!table_attr) {
> + acpi_put_table(table_header);
> break;
> + }
>
> if (acpi_table_attr_init(tables_kobj, table_attr, table_header)) {
> kfree(table_attr);
> + acpi_put_table(table_header);
> break;
> }
> list_add_tail(&table_attr->node, &acpi_table_attr_list);
> acpi_table_data_init(table_header, table_attr);
> + acpi_put_table(table_header);
> }
>
> kobject_uevent(tables_kobj, KOBJ_ADD);
>
Applied as 7.5 material, thanks!