Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 82802f96 authored by Hidehiro Kawai's avatar Hidehiro Kawai Committed by Corey Minyard
Browse files

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: default avatarHidehiro Kawai <hidehiro.kawai.ez@hitachi.com>

Fixed up a comment and some spacing issues.

Signed-off-by: default avatarCorey Minyard <cminyard@mvista.com>
parent e45361d7
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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);
}
+5 −5
Original line number Diff line number Diff line
@@ -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;

	/*
@@ -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;
	}

@@ -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,
};

+5 −0
Original line number Diff line number Diff line
@@ -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