aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHidehiro Kawai <hidehiro.kawai.ez@hitachi.com>2015-07-27 01:55:16 -0400
committerCorey Minyard <cminyard@mvista.com>2015-09-03 16:02:28 -0400
commit82802f968bd3118af04eaeb3814c21d9813be527 (patch)
treedd26a8d2a0d96b013938814083144654bf30db71
parente45361d733d0a1432b0f6307375045e66ac02489 (diff)
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>
-rw-r--r--drivers/char/ipmi/ipmi_msghandler.c3
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c10
-rw-r--r--include/linux/ipmi_smi.h5
3 files changed, 13 insertions, 5 deletions
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index 5e31c339062e..6e191ff910e6 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -4295,6 +4295,9 @@ static void ipmi_panic_request_and_wait(ipmi_smi_t intf,
4295 0, 1); /* Don't retry, and don't wait. */ 4295 0, 1); /* Don't retry, and don't wait. */
4296 if (rv) 4296 if (rv)
4297 atomic_sub(2, &panic_done_count); 4297 atomic_sub(2, &panic_done_count);
4298 else if (intf->handlers->flush_messages)
4299 intf->handlers->flush_messages(intf->send_info);
4300
4298 while (atomic_read(&panic_done_count) != 0) 4301 while (atomic_read(&panic_done_count) != 0)
4299 ipmi_poll(intf); 4302 ipmi_poll(intf);
4300} 4303}
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index 5bd6d5b974cd..2f4cf6e78f72 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -924,8 +924,9 @@ static void check_start_timer_thread(struct smi_info *smi_info)
924 } 924 }
925} 925}
926 926
927static void flush_messages(struct smi_info *smi_info) 927static void flush_messages(void *send_info)
928{ 928{
929 struct smi_info *smi_info = send_info;
929 enum si_sm_result result; 930 enum si_sm_result result;
930 931
931 /* 932 /*
@@ -949,12 +950,10 @@ static void sender(void *send_info,
949 950
950 if (smi_info->run_to_completion) { 951 if (smi_info->run_to_completion) {
951 /* 952 /*
952 * If we are running to completion, start it and run 953 * If we are running to completion, start it. Upper
953 * transactions until everything is clear. 954 * layer will call flush_messages to clear it out.
954 */ 955 */
955 smi_info->waiting_msg = msg; 956 smi_info->waiting_msg = msg;
956
957 flush_messages(smi_info);
958 return; 957 return;
959 } 958 }
960 959
@@ -1260,6 +1259,7 @@ static const struct ipmi_smi_handlers handlers = {
1260 .set_need_watch = set_need_watch, 1259 .set_need_watch = set_need_watch,
1261 .set_maintenance_mode = set_maintenance_mode, 1260 .set_maintenance_mode = set_maintenance_mode,
1262 .set_run_to_completion = set_run_to_completion, 1261 .set_run_to_completion = set_run_to_completion,
1262 .flush_messages = flush_messages,
1263 .poll = poll, 1263 .poll = poll,
1264}; 1264};
1265 1265
diff --git a/include/linux/ipmi_smi.h b/include/linux/ipmi_smi.h
index 41de0cf34c49..f8cea14485dd 100644
--- a/include/linux/ipmi_smi.h
+++ b/include/linux/ipmi_smi.h
@@ -115,6 +115,11 @@ struct ipmi_smi_handlers {
115 implement it. */ 115 implement it. */
116 void (*set_need_watch)(void *send_info, bool enable); 116 void (*set_need_watch)(void *send_info, bool enable);
117 117
118 /*
119 * Called when flushing all pending messages.
120 */
121 void (*flush_messages)(void *send_info);
122
118 /* Called when the interface should go into "run to 123 /* Called when the interface should go into "run to
119 completion" mode. If this call sets the value to true, the 124 completion" mode. If this call sets the value to true, the
120 interface should make sure that all messages are flushed 125 interface should make sure that all messages are flushed