posix-timers: Invoke cond_resched() during exit_itimers()

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
This commit is contained in:
Benjamin Segall
2025-02-18 10:12:49 +01:00
committed by Thomas Gleixner
parent 4441b976df
commit f99c5bb396
+3 -1
View 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