ipmi: Don't flush messages in sender() in run-to-completion mode
When flushing queued messages in run-to-completion mode, smi_event_handler() is recursively called. flush_messages() smi_event_handler() handle_transaction_done() deliver_recv_msg() ipmi_smi_msg_received() smi_recv_tasklet() sender() flush_messages() smi_event_handler() ... The depth of the recursive call depends on the number of queued messages, so it can cause a stack overflow if many messages have been queued. To solve this problem, this patch removes flush_messages() from sender()@ipmi_si_intf.c. Instead, add flush_messages() to caller side of sender() if needed. Additionally, to implement this, add new handler flush_messages to struct ipmi_smi_handlers. Signed-off-by: Hidehiro Kawai <hidehiro.kawai.ez@hitachi.com> Fixed up a comment and some spacing issues. Signed-off-by: Corey Minyard <cminyard@mvista.com>
This commit is contained in:
parent
e45361d733
commit
82802f968b
|
@ -4295,6 +4295,9 @@ static void ipmi_panic_request_and_wait(ipmi_smi_t intf,
|
||||||
0, 1); /* Don't retry, and don't wait. */
|
0, 1); /* Don't retry, and don't wait. */
|
||||||
if (rv)
|
if (rv)
|
||||||
atomic_sub(2, &panic_done_count);
|
atomic_sub(2, &panic_done_count);
|
||||||
|
else if (intf->handlers->flush_messages)
|
||||||
|
intf->handlers->flush_messages(intf->send_info);
|
||||||
|
|
||||||
while (atomic_read(&panic_done_count) != 0)
|
while (atomic_read(&panic_done_count) != 0)
|
||||||
ipmi_poll(intf);
|
ipmi_poll(intf);
|
||||||
}
|
}
|
||||||
|
|
|
@ -924,8 +924,9 @@ static void check_start_timer_thread(struct smi_info *smi_info)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void flush_messages(struct smi_info *smi_info)
|
static void flush_messages(void *send_info)
|
||||||
{
|
{
|
||||||
|
struct smi_info *smi_info = send_info;
|
||||||
enum si_sm_result result;
|
enum si_sm_result result;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -949,12 +950,10 @@ static void sender(void *send_info,
|
||||||
|
|
||||||
if (smi_info->run_to_completion) {
|
if (smi_info->run_to_completion) {
|
||||||
/*
|
/*
|
||||||
* If we are running to completion, start it and run
|
* If we are running to completion, start it. Upper
|
||||||
* transactions until everything is clear.
|
* layer will call flush_messages to clear it out.
|
||||||
*/
|
*/
|
||||||
smi_info->waiting_msg = msg;
|
smi_info->waiting_msg = msg;
|
||||||
|
|
||||||
flush_messages(smi_info);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1260,6 +1259,7 @@ static const struct ipmi_smi_handlers handlers = {
|
||||||
.set_need_watch = set_need_watch,
|
.set_need_watch = set_need_watch,
|
||||||
.set_maintenance_mode = set_maintenance_mode,
|
.set_maintenance_mode = set_maintenance_mode,
|
||||||
.set_run_to_completion = set_run_to_completion,
|
.set_run_to_completion = set_run_to_completion,
|
||||||
|
.flush_messages = flush_messages,
|
||||||
.poll = poll,
|
.poll = poll,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -115,6 +115,11 @@ struct ipmi_smi_handlers {
|
||||||
implement it. */
|
implement it. */
|
||||||
void (*set_need_watch)(void *send_info, bool enable);
|
void (*set_need_watch)(void *send_info, bool enable);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called when flushing all pending messages.
|
||||||
|
*/
|
||||||
|
void (*flush_messages)(void *send_info);
|
||||||
|
|
||||||
/* Called when the interface should go into "run to
|
/* Called when the interface should go into "run to
|
||||||
completion" mode. If this call sets the value to true, the
|
completion" mode. If this call sets the value to true, the
|
||||||
interface should make sure that all messages are flushed
|
interface should make sure that all messages are flushed
|
||||||
|
|
Loading…
Reference in New Issue