i2c: Prevent priority inversion on top of bus lock
Low priority thread holding the i2c bus mutex could block higher priority threads to access the bus resulting in unacceptable latencies. Change the mutex type to rt_mutex preventing priority inversion. Tested-by: Peter Ujfalusi <peter.ujfalusi@nokia.com> Signed-off-by: Mika Kuoppala <mika.kuoppala@nokia.com> Signed-off-by: Jean Delvare <khali@linux-fr.org>
This commit is contained in:
committed by
Jean Delvare
parent
a0c11cdd6a
commit
194684e596
@@ -584,7 +584,7 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
|
||||
goto out_list;
|
||||
}
|
||||
|
||||
mutex_init(&adap->bus_lock);
|
||||
rt_mutex_init(&adap->bus_lock);
|
||||
|
||||
/* Set default timeout to 1 second if not already set */
|
||||
if (adap->timeout == 0)
|
||||
@@ -1092,12 +1092,12 @@ int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
|
||||
#endif
|
||||
|
||||
if (in_atomic() || irqs_disabled()) {
|
||||
ret = mutex_trylock(&adap->bus_lock);
|
||||
ret = rt_mutex_trylock(&adap->bus_lock);
|
||||
if (!ret)
|
||||
/* I2C activity is ongoing. */
|
||||
return -EAGAIN;
|
||||
} else {
|
||||
mutex_lock_nested(&adap->bus_lock, adap->level);
|
||||
rt_mutex_lock(&adap->bus_lock);
|
||||
}
|
||||
|
||||
/* Retry automatically on arbitration loss */
|
||||
@@ -1109,7 +1109,7 @@ int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
|
||||
if (time_after(jiffies, orig_jiffies + adap->timeout))
|
||||
break;
|
||||
}
|
||||
mutex_unlock(&adap->bus_lock);
|
||||
rt_mutex_unlock(&adap->bus_lock);
|
||||
|
||||
return ret;
|
||||
} else {
|
||||
@@ -1913,7 +1913,7 @@ s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags,
|
||||
flags &= I2C_M_TEN | I2C_CLIENT_PEC;
|
||||
|
||||
if (adapter->algo->smbus_xfer) {
|
||||
mutex_lock(&adapter->bus_lock);
|
||||
rt_mutex_lock(&adapter->bus_lock);
|
||||
|
||||
/* Retry automatically on arbitration loss */
|
||||
orig_jiffies = jiffies;
|
||||
@@ -1927,7 +1927,7 @@ s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags,
|
||||
orig_jiffies + adapter->timeout))
|
||||
break;
|
||||
}
|
||||
mutex_unlock(&adapter->bus_lock);
|
||||
rt_mutex_unlock(&adapter->bus_lock);
|
||||
} else
|
||||
res = i2c_smbus_xfer_emulated(adapter,addr,flags,read_write,
|
||||
command, protocol, data);
|
||||
|
Reference in New Issue
Block a user