[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