Hi,ALL
This is a revised patch I sent 30th,July because of its awkward style
These are the descriptions
Regards,
M.Gouji.
>From 25e193731d3f04bad12d30eb35d21e990c935719 Mon Sep 17 00:00:00 2001
From: root <[email protected]>
Date: Fri, 3 Jul 2015 11:54:34 +0900
Subject: [PATCH] ipmi:driver not to stop when the hardware not respond in irq
mode
I have a malfunctional BMC which sometimes stop to respond in IRQ mode.
In the case that the BMC works in Polling mode, this problem already solved
last year.
with adding the timer restart in ipmi_thread() while it is stopping
But this won't work in IRQ mode because there ipmi_thread() never be
invoked.
So, I propose the patch to solve this .
The idea is that for make the timer for smi_timeout never stop
Even if smi_event_handler returns SM_IDLE in smi_timeout.
If the timer value for this is arranged properly like the interval of
ipmi_thread while idle ,
I think this could work as proper alternative for ipmi_thread() and
solves the problem described above.
Signed-off-by: Masayuki Gouji <[email protected]>
---
drivers/char/ipmi/ipmi_si_intf.c | 37 ++++++++++++++++++++++++++++++++-----
1 file changed, 32 insertions(+), 5 deletions(-)
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index 8a45e92..cb72f44 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -82,8 +82,11 @@
/* Call every 10 ms. */
#define SI_TIMEOUT_TIME_USEC 10000
+#define SI_TIMEOUT_TIME_FOR_TRIGGER_USEC (100*1000)
#define SI_USEC_PER_JIFFY (1000000/HZ)
#define SI_TIMEOUT_JIFFIES (SI_TIMEOUT_TIME_USEC/SI_USEC_PER_JIFFY)
+#define SI_TIMEOUT_FOR_TRIGGER_JIFFIES \
+(SI_TIMEOUT_TIME_FOR_TRIGGER_USEC/SI_USEC_PER_JIFFY)
#define SI_SHORT_TIMEOUT_USEC 250 /* .25ms when the SM request a
short timeout */
@@ -1140,13 +1143,38 @@ static void smi_timeout(unsigned long data)
jiffies_now = jiffies;
time_diff = (((long)jiffies_now - (long)smi_info->last_timeout_jiffies)
* SI_USEC_PER_JIFFY);
- smi_result = smi_event_handler(smi_info, time_diff);
+
+ /* For compatibility to IPMI_thread,
+ * call event_handler with timeout value 0
+ * This is is judged by duration even though it's may not be precise.
+ * + SI_USEC_PER_JIFFY is for evading the jittery of timer
+ */
+
+ smi_result = smi_event_handler(smi_info,
+ ((smi_info->irq) && (!smi_info->interrupt_disabled) &&
+ (time_diff > (SI_TIMEOUT_TIME_USEC+SI_USEC_PER_JIFFY)))
+ ? 0 : time_diff);
if ((smi_info->irq) && (!smi_info->interrupt_disabled)) {
/* Running with interrupts, only do long timeouts. */
- timeout = jiffies + SI_TIMEOUT_JIFFIES;
- smi_inc_stat(smi_info, long_timeouts);
- goto do_mod_timer;
+
+ /* Use this as an alternative of ipmi_thread for hang up
+ * when this timer stops.
+ * Make this timer always alive as 100ms which ipmi_thread uses
+ * in idle for compatibility
+ * Statistics shouldn't be got in this extra timer.
+ */
+
+ if (!(time_diff <= SI_TIMEOUT_TIME_USEC + SI_USEC_PER_JIFFY))
+ smi_inc_stat(smi_info, long_timeouts);
+
+ /* Use extra timer which coincides ipmi_thread during idle. */
+
+ timeout = jiffies + ((smi_result != SI_SM_IDLE) ?
+ SI_TIMEOUT_JIFFIES : SI_TIMEOUT_FOR_TRIGGER_JIFFIES);
+ smi_mod_timer(smi_info, timeout);
+ spin_unlock_irqrestore(&(smi_info->si_lock), flags);
+ return;
}
/*
@@ -1161,7 +1189,6 @@ static void smi_timeout(unsigned long data)
timeout = jiffies + SI_TIMEOUT_JIFFIES;
}
- do_mod_timer:
if (smi_result != SI_SM_IDLE)
smi_mod_timer(smi_info, timeout);
else
--
2.4.3
------------------------------------------------------------------------------
_______________________________________________
Openipmi-developer mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openipmi-developer