[PATCH 1/2] hwmon: Add driver tmp421 for TI's TMP421/422/423 sensor chips

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




On 06/16/2009 09:58 AM, Andre Prendel wrote:
> On Mon, Jun 15, 2009 at 10:52:24PM +0200, Jean Delvare wrote:
>> Hi Andre,
>
> Hi again,
>
> There is one remaining question, see below.
>

See below for my answer.

<snip>

>>> +static ssize_t show_temp_value(struct device *dev,
>>> +			       struct device_attribute *devattr, char *buf)
>>> +{
>>> +	int index = to_sensor_dev_attr(devattr)->index;
>>> +	struct tmp421_data *data = tmp421_update_device(dev);
>>> +	int temp;
>>> +
>>> +	if (data->config&  TMP421_CONFIG_RANGE)
>>> +		temp = temp_from_u16(data->temp[index]);
>>> +	else
>>> +		temp = temp_from_s16(data->temp[index]);
>> This lacks protection: you have no guarantee that data->config and
>> data->temp[index] belong to the same read cycle.
>
> The *data pointer comes from tmp421_update_device(dev). So this should
> be from the same cycle, shouldn't be. I don't know how to
> protect. Hardware access is protected in tmp421_update_device(). Maybe
> I misunderstood something.
>

Yes, but 2 sysfs attributes can be read (by different processes / threads) at
the same time, this could lead to the following:

Proc 1:
Read temp1_value
tmp421_update_device() does not do anything as it isn't time yet
Check data->config
<task switch>

Proc 2:
Read temp1_value
tmp421_update_device() reads the entire chip
Calculate temp and return to userspace
<task switch>

Proc 1:
Read data->temp[index] and do calulation.
return temp to userspace

Now Proc 1 has used data->config and data->temp from 2
different read cycles. Since data->config should never
change this is a bit of a theoretical problem here. But
still you should protect against it, even if for no other reason
as to be good example code for people looking for an example.

The way to protect against this is like this:

	mutex_lock(&data->update_lock);
	if (data->config&  TMP421_CONFIG_RANGE)
		temp = temp_from_u16(data->temp[index]);
	else
		temp = temp_from_s16(data->temp[index]);
	mutex_unlock(&data->update_lock);


<snip>

Regards,

Hans



[Index of Archives]     [Linux Kernel]     [Linux Hardware Monitoring]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux