diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2023-09-27 13:17:25 -0700 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2023-09-29 12:40:35 +0200 |
commit | 2e57d10a6591560724b80a628235559571f4cb8d (patch) | |
tree | 9ea4fa8e8e9ff7a4c1a075511cddd767497ac3b0 /drivers/acpi/thermal.c | |
parent | 3e7d6f396d74a3e40c390bb53947938957426097 (diff) | |
download | linux-2e57d10a6591560724b80a628235559571f4cb8d.tar.gz linux-2e57d10a6591560724b80a628235559571f4cb8d.tar.bz2 linux-2e57d10a6591560724b80a628235559571f4cb8d.zip |
ACPI: utils: Dynamically determine acpi_handle_list size
Address a long-standing "TBD" comment in the ACPI headers regarding the
number of handles in struct acpi_handle_list.
The number 10, which along with the comment dates back to 2.4.23, seems
like it may have been arbitrarily chosen and isn't sufficient in all
cases [1].
Finally change the code to dynamically determine the size of the handles
table in struct acpi_handle_list and allocate it accordingly.
Update the users of to struct acpi_handle_list to take the additional
dynamic allocation into account.
Link: https://lore.kernel.org/linux-acpi/20230809094451.15473-1-ivan.hu@canonical.com # [1]
Co-developed-by: Vicki Pfau <vi@endrift.com>
Signed-off-by: Vicki Pfau <vi@endrift.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/acpi/thermal.c')
-rw-r--r-- | drivers/acpi/thermal.c | 28 |
1 files changed, 21 insertions, 7 deletions
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index c303688ead71..42a3df9d625d 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -208,7 +208,7 @@ static bool update_trip_devices(struct acpi_thermal *tz, struct acpi_thermal_trip *acpi_trip, int index, bool compare) { - struct acpi_handle_list devices; + struct acpi_handle_list devices = { 0 }; char method[] = "_PSL"; acpi_status status; @@ -218,18 +218,21 @@ static bool update_trip_devices(struct acpi_thermal *tz, method[3] = '0' + index; } - memset(&devices, 0, sizeof(devices)); - status = acpi_evaluate_reference(tz->device->handle, method, NULL, &devices); if (ACPI_FAILURE(status)) { acpi_handle_info(tz->device->handle, "%s evaluation failure\n", method); return false; } - if (compare && memcmp(&acpi_trip->devices, &devices, sizeof(devices))) + if (acpi_handle_list_equal(&acpi_trip->devices, &devices)) { + acpi_handle_list_free(&devices); + return true; + } + + if (compare) ACPI_THERMAL_TRIPS_EXCEPTION(tz, "device"); - memcpy(&acpi_trip->devices, &devices, sizeof(devices)); + acpi_handle_list_replace(&acpi_trip->devices, &devices); return true; } @@ -842,6 +845,17 @@ static void acpi_thermal_check_fn(struct work_struct *work) mutex_unlock(&tz->thermal_check_lock); } +static void acpi_thermal_free_thermal_zone(struct acpi_thermal *tz) +{ + int i; + + acpi_handle_list_free(&tz->trips.passive.trip.devices); + for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) + acpi_handle_list_free(&tz->trips.active[i].trip.devices); + + kfree(tz); +} + static int acpi_thermal_add(struct acpi_device *device) { struct acpi_thermal_trip *acpi_trip; @@ -968,7 +982,7 @@ flush_wq: free_trips: kfree(tz->trip_table); free_memory: - kfree(tz); + acpi_thermal_free_thermal_zone(tz); return result; } @@ -988,7 +1002,7 @@ static void acpi_thermal_remove(struct acpi_device *device) flush_workqueue(acpi_thermal_pm_queue); acpi_thermal_unregister_thermal_zone(tz); - kfree(tz); + acpi_thermal_free_thermal_zone(tz); } #ifdef CONFIG_PM_SLEEP |