Skip to content

Commit

Permalink
hwmon: (acpi_power_meter) Fix uninitialized variables
Browse files Browse the repository at this point in the history
The 'power1_alarm' attribute uses the 'power' and 'cap' in the
acpi_power_meter_resource structure. Currently, these two fields are just
updated when user query 'power' and 'cap' attribute. If user directly query
the 'power1_alarm' attribute without queryng above two attributes, driver
will use uninitialized variables to judge.

So this patch adds the setting of alarm state and update 'cap' in the
notification callback and update 'power' and 'cap' if needed to show the
real alarm state.

Signed-off-by: Huisong Li <lihuisong@huawei.com>
Link: https://lore.kernel.org/r/20250109081708.27366-2-lihuisong@huawei.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
  • Loading branch information
Huisong Li authored and Guenter Roeck committed Jan 9, 2025
1 parent c909e68 commit 7532e68
Showing 1 changed file with 23 additions and 4 deletions.
27 changes: 23 additions & 4 deletions drivers/hwmon/acpi_power_meter.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ struct acpi_power_meter_resource {
u64 power;
u64 cap;
u64 avg_interval;
bool power_alarm;
int sensors_valid;
unsigned long sensors_last_updated;
struct sensor_device_attribute sensors[NUM_SENSORS];
Expand Down Expand Up @@ -396,6 +397,9 @@ static ssize_t show_val(struct device *dev,
struct acpi_device *acpi_dev = to_acpi_device(dev);
struct acpi_power_meter_resource *resource = acpi_dev->driver_data;
u64 val = 0;
int ret;

guard(mutex)(&resource->lock);

switch (attr->index) {
case 0:
Expand Down Expand Up @@ -423,10 +427,17 @@ static ssize_t show_val(struct device *dev,
val = 0;
break;
case 6:
if (resource->power > resource->cap)
val = 1;
else
val = 0;
ret = update_meter(resource);
if (ret)
return ret;
/* need to update cap if not to support the notification. */
if (!(resource->caps.flags & POWER_METER_CAN_NOTIFY)) {
ret = update_cap(resource);
if (ret)
return ret;
}
val = resource->power_alarm || resource->power > resource->cap;
resource->power_alarm = resource->power > resource->cap;
break;
case 7:
case 8:
Expand Down Expand Up @@ -847,12 +858,20 @@ static void acpi_power_meter_notify(struct acpi_device *device, u32 event)
sysfs_notify(&device->dev.kobj, NULL, POWER_AVERAGE_NAME);
break;
case METER_NOTIFY_CAP:
mutex_lock(&resource->lock);
res = update_cap(resource);
if (res)
dev_err_once(&device->dev, "update cap failed when capping value is changed.\n");
mutex_unlock(&resource->lock);
sysfs_notify(&device->dev.kobj, NULL, POWER_CAP_NAME);
break;
case METER_NOTIFY_INTERVAL:
sysfs_notify(&device->dev.kobj, NULL, POWER_AVG_INTERVAL_NAME);
break;
case METER_NOTIFY_CAPPING:
mutex_lock(&resource->lock);
resource->power_alarm = true;
mutex_unlock(&resource->lock);
sysfs_notify(&device->dev.kobj, NULL, POWER_ALARM_NAME);
dev_info(&device->dev, "Capping in progress.\n");
break;
Expand Down

0 comments on commit 7532e68

Please sign in to comment.