diff options
author | Anton Blanchard <anton@samba.org> | 2017-10-13 01:01:59 +1100 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2017-10-15 20:07:36 -0500 |
commit | 4466a6ec89bf39afeb98b92d03bbf7fc30c55afe (patch) | |
tree | 4e8b12187f18f1614e86ac18c3565266f02d8b9d /hw/p8-i2c.c | |
parent | c29df9d7d8a97225f675337e7dd3f283520f6c21 (diff) | |
download | skiboot-4466a6ec89bf39afeb98b92d03bbf7fc30c55afe.zip skiboot-4466a6ec89bf39afeb98b92d03bbf7fc30c55afe.tar.gz skiboot-4466a6ec89bf39afeb98b92d03bbf7fc30c55afe.tar.bz2 |
hw/p8-i2c: Fix deadlock in p9_i2c_bus_owner_change
When debugging a system where Linux was taking soft lockup errors, I
noticed two CPUs were stuck in OPAL:
CPU0
lock
p8_i2c_recover
opal_handle_interrupt
CPU1
sync_timer
cancel_timer
p9_i2c_bus_owner_change
occ_p9_interrupt
xive_source_interrupt
opal_handle_interrupt
p8_i2c_recover() is a timer, and is stuck trying to take master->lock.
p9_i2c_bus_owner_change() has taken master->lock, but then is stuck waiting
for all timers to complete. We deadlock.
Fix this by using cancel_timer_async(), as suggested by Oliver.
Fixes: 201fd50f208d ("hw/p8-i2c: Fix OCC locking")
Suggested-by: Oliver O'Halloran <oohall@gmail.com>
Signed-off-by: Anton Blanchard <anton@samba.org>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'hw/p8-i2c.c')
-rw-r--r-- | hw/p8-i2c.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/hw/p8-i2c.c b/hw/p8-i2c.c index ffbace9..0defe7b 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; |