]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
posix-timers: Invoke cond_resched() during exit_itimers()
authorBenjamin Segall <bsegall@google.com>
Fri, 14 Feb 2025 22:12:20 +0000 (14:12 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 29 May 2025 09:13:17 +0000 (11:13 +0200)
[ Upstream commit f99c5bb396b8d1424ed229d1ffa6f596e3b9c36b ]

exit_itimers() loops through every timer in the process to delete it.  This
requires taking the system-wide hash_lock for each of these timers, and
contends with other processes trying to create or delete timers.

When a process creates hundreds of thousands of timers, and then exits
while other processes contend with it, this can trigger softlockups on
CONFIG_PREEMPT=n.

Add a cond_resched() invocation into the loop to allow the system to make
progress.

Signed-off-by: Ben Segall <bsegall@google.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/xm2634gg2n23.fsf@google.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
kernel/time/posix-timers.c

index 15ed343693101e283dc62238b898ea15fc7ec7c9..43b08a04898a87f7e1d68220ed3e04a4c95b39c3 100644 (file)
@@ -1107,8 +1107,10 @@ void exit_itimers(struct task_struct *tsk)
        spin_unlock_irq(&tsk->sighand->siglock);
 
        /* The timers are not longer accessible via tsk::signal */
-       while (!hlist_empty(&timers))
+       while (!hlist_empty(&timers)) {
                itimer_delete(hlist_entry(timers.first, struct k_itimer, list));
+               cond_resched();
+       }
 
        /*
         * There should be no timers on the ignored list. itimer_delete() has