[PATCH linux dev-4.10] drivers: i2c: FSI: Prevent holding CPU for a long time

Eddie James eajames at linux.vnet.ibm.com
Thu Dec 14 03:57:03 AEDT 2017


From: "Edward A. James" <eajames at us.ibm.com>

During multiple messages, the FSI-attached I2C driver may continually
transfer data without allowing any cycles for the kernel or userspace to
run. This becomes a problem during large transfers (50k or more) since
the kernel or userspace watchdog doesn't get pinged, resulting in a
system reboot. Add some schedule time in between messages to prevent
this.

Signed-off-by: Edward A. James <eajames at us.ibm.com>
---
 drivers/i2c/busses/i2c-fsi.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/i2c/busses/i2c-fsi.c b/drivers/i2c/busses/i2c-fsi.c
index 1cb85f3..1e48c5c 100644
--- a/drivers/i2c/busses/i2c-fsi.c
+++ b/drivers/i2c/busses/i2c-fsi.c
@@ -137,7 +137,9 @@
 
 #define I2C_PORT_BUSY_RESET	0x80000000
 
-#define I2C_LOCAL_WAIT_TIMEOUT	2		/* jiffies */
+#define I2C_LOCAL_WAIT_TIMEOUT	msecs_to_jiffies(10)
+
+#define I2C_MSG_SCHED_TIMEOUT	msecs_to_jiffies(50)
 
 /* choose timeout length from legacy driver; it's well tested */
 #define I2C_ABORT_TIMEOUT	msecs_to_jiffies(100)
@@ -655,6 +657,19 @@ static int fsi_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
 				  adap->timeout - (jiffies - start_time));
 		if (rc)
 			goto unlock;
+
+		if (i && i != (num - 1)) {
+			/*
+			 * Release the CPU for a while if we're in the middle
+			 * of some large transfers. Otherwise, we could hold
+			 * the CPU for a very long and risk watchdog problems.
+			 */
+			set_current_state(TASK_INTERRUPTIBLE);
+			if (schedule_timeout(I2C_MSG_SCHED_TIMEOUT) > 0) {
+				rc = -EINTR;
+				goto unlock;
+			}
+		}
 	}
 
 unlock:
-- 
1.8.3.1



More information about the openbmc mailing list