Skip to content

Commit

Permalink
i2c-algo-bit: Fix spurious SCL timeouts under heavy load
Browse files Browse the repository at this point in the history
commit 8ee161c upstream.

When the system is under heavy load, there can be a significant delay
between the getscl() and time_after() calls inside sclhi(). That delay
may cause the time_after() check to trigger after SCL has gone high,
causing sclhi() to return -ETIMEDOUT.

To fix the problem, double check that SCL is still low after the
timeout has been reached, before deciding to return -ETIMEDOUT.

Signed-off-by: Ville Syrjala <syrjala@sci.fi>
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Ville Syrjala authored and Greg Kroah-Hartman committed Mar 19, 2012
1 parent 90b7d65 commit 35f6801
Showing 1 changed file with 7 additions and 1 deletion.
8 changes: 7 additions & 1 deletion drivers/i2c/algos/i2c-algo-bit.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,14 @@ static int sclhi(struct i2c_algo_bit_data *adap)
* chips may hold it low ("clock stretching") while they
* are processing data internally.
*/
if (time_after(jiffies, start + adap->timeout))
if (time_after(jiffies, start + adap->timeout)) {
/* Test one last time, as we may have been preempted
* between last check and timeout test.
*/
if (getscl(adap))
break;
return -ETIMEDOUT;
}
cond_resched();
}
#ifdef DEBUG
Expand Down

0 comments on commit 35f6801

Please sign in to comment.