[Skiboot] [PATCH] hw/bt: Fix bt_msg_del locking

Alistair Popple alistair at popple.id.au
Thu Jun 18 16:11:48 AEST 2015


bt_msg_del() calls ipmi_cmd_done() to free the message and process any
error callbacks. However it should drop the lock prior to calling
ipmi_cmd_done() as some error callbacks may try to queue ipmi messages
leading to a dead lock.

Signed-off-by: Alistair Popple <alistair at popple.id.au>
---
 hw/bt.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/hw/bt.c b/hw/bt.c
index da59b14..7913249 100644
--- a/hw/bt.c
+++ b/hw/bt.c
@@ -133,12 +133,15 @@ static inline void bt_set_state(enum bt_states next_state)
 	bt.state = next_state;
 }
 
+/* Must be called with bt.lock held */
 static void bt_msg_del(struct bt_msg *bt_msg)
 {
 	list_del(&bt_msg->link);
 	bt.queue_len--;
+	unlock(&bt.lock);
 	ipmi_cmd_done(bt_msg->ipmi_msg.cmd, bt_msg->ipmi_msg.netfn + (1 << 2),
 		      IPMI_TIMEOUT_ERR, &bt_msg->ipmi_msg);
+	lock(&bt.lock);
 }
 
 static void bt_init_interface(void)
@@ -363,11 +366,12 @@ static void bt_poll(struct timer *t __unused, void *data __unused)
 	/* If we can't get the lock assume someone else will notice
 	 * the new message and process it. */
 	lock(&bt.lock);
-	bt_ctrl = bt_inb(BT_CTRL);
 
 	print_debug_queue_info();
 	bt_expire_old_msg();
 
+	bt_ctrl = bt_inb(BT_CTRL);
+
 	/* Is there a response waiting for us? */
 	if (bt.state == BT_STATE_RESP_WAIT &&
 	    (bt_ctrl & BT_CTRL_B2H_ATN))
-- 
1.8.3.2



More information about the Skiboot mailing list