diff options
author | Hidehiro Kawai <hidehiro.kawai.ez@hitachi.com> | 2015-07-27 01:55:16 -0400 |
---|---|---|
committer | Corey Minyard <cminyard@mvista.com> | 2015-09-03 16:02:28 -0400 |
commit | 82802f968bd3118af04eaeb3814c21d9813be527 (patch) | |
tree | dd26a8d2a0d96b013938814083144654bf30db71 | |
parent | e45361d733d0a1432b0f6307375045e66ac02489 (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.c | 3 | ||||
-rw-r--r-- | drivers/char/ipmi/ipmi_si_intf.c | 10 | ||||
-rw-r--r-- | include/linux/ipmi_smi.h | 5 |
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 | ||
927 | static void flush_messages(struct smi_info *smi_info) | 927 | static 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 |