Get all operations that manipulate the interface list into thread
context.

Signed-off-by: Corey Minyard <cminy...@mvista.com>
---
 drivers/char/ipmi/ipmi_msghandler.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/char/ipmi/ipmi_msghandler.c 
b/drivers/char/ipmi/ipmi_msghandler.c
index 22813b1598b0..e08ec9918a32 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -5083,8 +5083,11 @@ static struct timer_list ipmi_timer;
 
 static atomic_t stop_operation;
 
-static void ipmi_timeout(struct timer_list *unused)
+static void ipmi_timeout_work(struct work_struct *work)
 {
+       if (atomic_read(&stop_operation))
+               return;
+
        struct ipmi_smi *intf;
        bool need_timer = false;
        int index;
@@ -5111,6 +5114,16 @@ static void ipmi_timeout(struct timer_list *unused)
                mod_timer(&ipmi_timer, jiffies + IPMI_TIMEOUT_JIFFIES);
 }
 
+static DECLARE_WORK(ipmi_timer_work, ipmi_timeout_work);
+
+static void ipmi_timeout(struct timer_list *unused)
+{
+       if (atomic_read(&stop_operation))
+               return;
+
+       queue_work(system_bh_wq, &ipmi_timer_work);
+}
+
 static void need_waiter(struct ipmi_smi *intf)
 {
        /* Racy, but worst case we start the timer twice. */
@@ -5538,6 +5551,7 @@ static void __exit cleanup_ipmi(void)
                 */
                atomic_set(&stop_operation, 1);
                del_timer_sync(&ipmi_timer);
+               cancel_work_sync(&ipmi_timer_work);
 
                initialized = false;
 
-- 
2.43.0



_______________________________________________
Openipmi-developer mailing list
Openipmi-developer@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openipmi-developer

Reply via email to