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 Original line 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. */
			    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);
}
}
+5 −5
Original line number Original line 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;
	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,
};
};


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