[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 Tue, Jun 16, 2009 at 10:10:27AM +0200, Jean Delvare wrote:
> On Tue, 16 Jun 2009 09:58:31 +0200, Andre Prendel wrote:
> > On Mon, Jun 15, 2009 at 10:52:24PM +0200, Jean Delvare wrote:
> > > On Mon, 15 Jun 2009 09:43:20 +0200, Andre Prendel wrote:
> > > > +static int temp_from_s16(s16 reg)
> > > > +{
> > > > +	int temp = reg;
> > > > +
> > > > +	return (temp * 1000 + 128) / 256;
> > > > +}
> > > > +
> > > > +static int temp_from_u16(u16 reg)
> > > > +{
> > > > +	int temp = reg;
> > > > +
> > > > +	/* Add offset for extended temperature range. */
> > > > +	temp -= 64 * 256;
> > > > +
> > > > +	return (temp * 1000 + 128) / 256;
> > > > +}
> > > > +
> > > > +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.
> 
> You can have concurrent accesses to the sysfs attribute files. Let's
> say you have two files being accessed, the first access when the cache
> is still valid (tmp421_update_device is a no-op) and the second when
> the cache just wore off and needs to be refreshed (tmp421_update_device
> reads from registers).
> 
> The first access will test data->config based on the cached value. At
> this point, the second access could cause the cache to be refreshed. I
> agree this is all highly unlikely, but in theory this could still
> happen. Then the first access will use data->temp[index], from the
> refreshed cache. If data->config changed meanwhile, then you just
> called the wrong conversion function for the temperature value.
> 
> It's pretty easy to fix:
> 
> 	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);
> 
> This is sufficient to prevent a cache update while you're using the
> cached values.

Hans, Jean, thanks for the explanation. I'll fix it too.

Andre

> 
> -- 
> Jean Delvare



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

  Powered by Linux