Skip to content

Commit

Permalink
ipmi: Don't flush messages in sender() in run-to-completion mode
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Hidehiro Kawai authored and Corey Minyard committed Sep 3, 2015
1 parent e45361d commit 82802f9
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 5 deletions.
3 changes: 3 additions & 0 deletions drivers/char/ipmi/ipmi_msghandler.c
Original file line number Diff line number Diff line change
Expand Up @@ -4295,6 +4295,9 @@ static void ipmi_panic_request_and_wait(ipmi_smi_t intf,
0, 1); /* Don't retry, and don't wait. */
if (rv)
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)
ipmi_poll(intf);
}
Expand Down
10 changes: 5 additions & 5 deletions drivers/char/ipmi/ipmi_si_intf.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/*
Expand All @@ -949,12 +950,10 @@ static void sender(void *send_info,

if (smi_info->run_to_completion) {
/*
* If we are running to completion, start it and run
* transactions until everything is clear.
* If we are running to completion, start it. Upper
* layer will call flush_messages to clear it out.
*/
smi_info->waiting_msg = msg;

flush_messages(smi_info);
return;
}

Expand Down Expand Up @@ -1260,6 +1259,7 @@ static const struct ipmi_smi_handlers handlers = {
.set_need_watch = set_need_watch,
.set_maintenance_mode = set_maintenance_mode,
.set_run_to_completion = set_run_to_completion,
.flush_messages = flush_messages,
.poll = poll,
};

Expand Down
5 changes: 5 additions & 0 deletions include/linux/ipmi_smi.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,11 @@ struct ipmi_smi_handlers {
implement it. */
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
completion" mode. If this call sets the value to true, the
interface should make sure that all messages are flushed
Expand Down

0 comments on commit 82802f9

Please sign in to comment.