[Skiboot] [PATCH] p8-i2c: Fix race between OCC interrupt and recovery timer

Oliver O'Halloran oohall at gmail.com
Thu Oct 12 18:03:09 AEDT 2017

When we request ownership of an I2C bus from the OCC we wait until the
OCC notifies us the bus is available with an interrupt. The wait time is
limited by the recovery timer duration which will cancel the pending
transaction if the OCC takes too long to hand ownership of the bus to

There is a race between the timeout function and the OCC interrupt
handler which can result in a deadlock when the two are run
concurrently. If both are running and the OCC interrupt aquires
the I2C master lock first it will wait attempt to cancel the recovery
timer which waits for the timeout handler function to finish if it's
already running. The problem is that the recovery handler will also
attempt to aquire the I2C master lock which results in both threads
waiting for each other to finish.

Fix this by using cancel_timer_async() which doesn not wait for the
timeout handle function to finish running.

Reported-by: Anton Blanchard <anton at samba.org>
Signed-off-by: Oliver O'Halloran <oohall at gmail.com>
 hw/p8-i2c.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/p8-i2c.c b/hw/p8-i2c.c
index ffbace936a9f..0defe7b2a2d2 100644
--- a/hw/p8-i2c.c
+++ b/hw/p8-i2c.c
@@ -1307,7 +1307,7 @@ void p9_i2c_bus_owner_change(u32 chip_id)
 			goto done;
 		/* clear the existing wait timer */
-		cancel_timer(&master->recovery);
+		cancel_timer_async(&master->recovery);
 		/* re-start the request now that we own the master */
 		master->state = state_idle;

More information about the Skiboot mailing list