Skip to content

Commit 18e8db7

Browse files
robhancocksedgroeck
authored andcommitted
hwmon: (pmbus) Add mutex locking for sysfs reads
As part of commit a919ba0 ("hwmon: (pmbus) Stop caching register values"), the update of the sensor value is now triggered directly by the sensor attribute value being read from sysfs. This created (or at least made much more likely) a locking issue, since nothing protected the device page selection from being unexpectedly modified by concurrent reads. If sensor values on different pages on the same device were being concurrently read by multiple threads, this could cause spurious read errors due to the page register not reading back the same value last written, or sensor values being read from the incorrect page. Add locking of the update_lock mutex in pmbus_show_sensor and pmbus_show_samples so that these cannot result in concurrent reads from the underlying device. Fixes: a919ba0 ("hwmon: (pmbus) Stop caching register values") Signed-off-by: Robert Hancock <robert.hancock@calian.com> Reviewed-by: Alex Qiu <xqiu@google.com> Link: https://lore.kernel.org/r/20201103193315.3011800-1-robert.hancock@calian.com Signed-off-by: Guenter Roeck <linux@roeck-us.net>
1 parent 402dab5 commit 18e8db7

1 file changed

Lines changed: 10 additions & 3 deletions

File tree

drivers/hwmon/pmbus/pmbus_core.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -941,12 +941,16 @@ static ssize_t pmbus_show_sensor(struct device *dev,
941941
struct i2c_client *client = to_i2c_client(dev->parent);
942942
struct pmbus_sensor *sensor = to_pmbus_sensor(devattr);
943943
struct pmbus_data *data = i2c_get_clientdata(client);
944+
ssize_t ret;
944945

946+
mutex_lock(&data->update_lock);
945947
pmbus_update_sensor_data(client, sensor);
946948
if (sensor->data < 0)
947-
return sensor->data;
948-
949-
return snprintf(buf, PAGE_SIZE, "%lld\n", pmbus_reg2data(data, sensor));
949+
ret = sensor->data;
950+
else
951+
ret = snprintf(buf, PAGE_SIZE, "%lld\n", pmbus_reg2data(data, sensor));
952+
mutex_unlock(&data->update_lock);
953+
return ret;
950954
}
951955

952956
static ssize_t pmbus_set_sensor(struct device *dev,
@@ -2012,8 +2016,11 @@ static ssize_t pmbus_show_samples(struct device *dev,
20122016
int val;
20132017
struct i2c_client *client = to_i2c_client(dev->parent);
20142018
struct pmbus_samples_reg *reg = to_samples_reg(devattr);
2019+
struct pmbus_data *data = i2c_get_clientdata(client);
20152020

2021+
mutex_lock(&data->update_lock);
20162022
val = _pmbus_read_word_data(client, reg->page, 0xff, reg->attr->reg);
2023+
mutex_unlock(&data->update_lock);
20172024
if (val < 0)
20182025
return val;
20192026

0 commit comments

Comments
 (0)