]> git.ipfire.org Git - thirdparty/linux.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)
committerThomas Gleixner <tglx@linutronix.de>
Tue, 18 Feb 2025 09:12:49 +0000 (10:12 +0100)
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
kernel/time/posix-timers.c

index 1b675aee99a980dda564815069a60fd67ad0c45c..44ba7db07e9001b728893df3e9eb13103e5a6403 100644 (file)
@@ -1099,8 +1099,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