From: Corey Minyard <co...@minyard.net>

[ Upstream commit 6bd0eb6d759b9a22c5509ea04e19c2e8407ba418 ]

It was possible for the SSIF thread to stop and quit before the
kthread_stop() call because ssif->stopping was set before the
stop.  So only exit the SSIF thread is kthread_should_stop()
returns true.

There is no need to wake the thread, as the wait will be interrupted
by kthread_stop().

Signed-off-by: Corey Minyard <cminy...@mvista.com>
Signed-off-by: Sasha Levin <sas...@kernel.org>
---

Based on my analysis of the commit and the current kernel code, here's
my assessment: **YES** This commit should be backported to stable kernel
trees. ## Detailed Analysis: ### Nature of the Bug Fix: The commit fixes
a **race condition during shutdown** in the IPMI SSIF driver. This is a
critical synchronization bug that can lead to system instability during
driver cleanup. ### Specific Race Condition: Looking at the code
changes, the race occurs between: 1. **Thread termination logic**: In
`ipmi_ssif_thread()` at line 484, there was a check for
`ssif_info->stopping` that would break out of the thread loop 2.
**Shutdown sequence**: In `shutdown_ssif()` at line 1270,
`ssif_info->stopping` is set to `true`, followed by
`complete(&ssif_info->wake_thread)` and then `kthread_stop()` ### The
Race Window: The problematic sequence was: 1. `shutdown_ssif()` sets
`ssif_info->stopping = true` (line 1270) 2. `shutdown_ssif()` calls
`complete(&ssif_info->wake_thread)` (line 1274) 3. The thread wakes up,
sees `stopping = true`, and exits the loop (line 484-485) 4. The thread
function returns and the thread terminates 5. `shutdown_ssif()` calls
`kthread_stop()` (line 1275) on an already-dead thread ### The Fix: The
commit removes the `ssif_info->stopping` check from the thread loop
(lines 484-485 removed) and the unnecessary
`complete(&ssif_info->wake_thread)` call from shutdown (line 1274
removed). Now: 1. The thread **only** exits when `kthread_should_stop()`
returns true (line 478) 2. `kthread_stop()` will properly signal the
thread to stop and wait for it 3. The
`wait_for_completion_interruptible()` call will be interrupted by
`kthread_stop()` ### Why This Should Be Backported: 1. **Critical Bug**:
Race conditions during shutdown can lead to kernel crashes, memory
corruption, or system hangs during reboot/module unload 2. **Minimal
Risk**: The changes are very small and surgical: - Removes 2 lines from
thread logic - Removes 1 line from shutdown logic - No new functionality
introduced - No architectural changes 3. **Follows Stable Tree
Criteria**: - Important bugfix (race condition) - Small, contained
change - Low regression risk - Affects critical kernel subsystem (IPMI)
4. **Similar Pattern**: Looking at the historical commits, commit #4
("Remove rtc_us_timer") and commit #5 ("Rename idle state and check")
both had `Cc: sta...@vger.kernel.org` tags and were marked as
backportable, showing this maintainer's pattern of marking important
SSIF fixes for stable backporting 5. **Production Impact**: IPMI is
commonly used in server environments where system stability during
shutdown/reboot is critical 6. **Clean Fix**: The fix aligns with proper
kernel thread management practices - relying on the standard
`kthread_should_stop()` mechanism rather than custom stopping flags The
commit addresses a real concurrency bug with a clean, minimal fix that
follows kernel best practices for thread management. The risk of
regression is extremely low while the benefit of preventing shutdown
races is significant.

 drivers/char/ipmi/ipmi_ssif.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c
index 0b45b07dec22c..5bf038e620c75 100644
--- a/drivers/char/ipmi/ipmi_ssif.c
+++ b/drivers/char/ipmi/ipmi_ssif.c
@@ -481,8 +481,6 @@ static int ipmi_ssif_thread(void *data)
                /* Wait for something to do */
                result = wait_for_completion_interruptible(
                                                &ssif_info->wake_thread);
-               if (ssif_info->stopping)
-                       break;
                if (result == -ERESTARTSYS)
                        continue;
                init_completion(&ssif_info->wake_thread);
@@ -1270,10 +1268,8 @@ static void shutdown_ssif(void *send_info)
        ssif_info->stopping = true;
        timer_delete_sync(&ssif_info->watch_timer);
        timer_delete_sync(&ssif_info->retry_timer);
-       if (ssif_info->thread) {
-               complete(&ssif_info->wake_thread);
+       if (ssif_info->thread)
                kthread_stop(ssif_info->thread);
-       }
 }
 
 static void ssif_remove(struct i2c_client *client)
-- 
2.39.5



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

Reply via email to