RFC locking and rate limit updates for i2c?

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

 



Jean Delvare wrote:

>Hi Grant,
>
>  
>
>>Surveyed drivers/i2c/chips/*.c containing "_write_value(" and...
>>
>>The winner is lm85.c :o)
>>
>>driver          write lock taken status [0]
>>--------------  ---------------------------------------------------
>>adm1021.c       no, appears to not need it
>>    
>>
>
>Out of curiousity, I took a look. See what I found:
>
>	data->value = TEMP_TO_REG(temp);
>	adm1021_write_value(client, reg, data->value);
>
>As long as we don't hold update_lock here, it could happen that
>data->value is overwritten by an update right inbetween these two lines,
>right? Causing the write to become silently useless, which is no good.
>So, either the lock should be held even in this most simple write case,
>or we should use a temporary variable and put the lines the other way
>around:
>
>	w = TEMP_TO_REG(temp);
>	adm1021_write_value(client, reg, w);
>	data->value = w;
>
>This should be concurrent-update-safe as far as I can see. I don't know
>what is preferable, performance-wise. At least, locking is a general
>solution to the problem. Temporary variables might be fine for simple
>cases like the one above, but it might become a mess for more complex
>functions. Also, using locks make it clear to the user that a concurrent
>access issue exists. The trick of using local variables isn't as
>obvious, and future code cleanup attempts might break it. So all in all
>I believe that using the lock is better.
>
>  
>

I think both cases are problematic.  It doesn't matter which order you 
do the writes, if you attempt to cache the value written to the 
register, then you must do that atomically.  Otherwise, the following 
can potentially occur and lead to the wrong result:

    Thread A                Thread B
    Write first value
                            Write first value
                            Write second value
    Write second value

End result is second value is Thread A and first value is Thread B.

Without locking, this sort of sequence is possible.  As long as you have 
to update two values in different locations, you've got to have some 
kind of locking or synchronization.

:v)



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

  Powered by Linux