posix-timers: Prevent softirq starvation by small intervals and SIG_IGN
Thomas Gleixner authored

posix-timers which deliver an ignored signal are currently rearmed in
the timer softirq: This is necessary because the timer needs to be
delivered again when SIG_IGN is removed. This is not a problem, when
the interval is reasonable.

With high resolution timers enabled one might arm a posix timer with a
very small interval and ignore the signal. This might lead to a
softirq starvation when the interval is so small that the timer is
requeued onto the softirq pending list right away.

This problem was pointed out by Jan Kiszka. Thanks Jan !

The correct solution would be to stop the timer, when the signal is
ignored and rearm it when SIG_IGN is removed. Unfortunately this
requires modification in sigaction and involves non trivial sighand
locking. It's too late in the release cycle for such a change.

For now we just keep the timer running and enforce that the timer only
fires every jiffie. This does not break anything as we keep the
overrun counter correct. It adds a little inaccuracy to the
timer_gettime() interface, but...

The more complex change is necessary anyway to fix another short
coming of the current implementation, which I discovered while looking
at this problem: A pending signal is discarded when SIG_IGN is set. In
case that a posixtimer signal is pending then it is discarded as well,
but when SIG_IGN is removed later nothing rearms the timer. This is
not new, it's that way since posix timers have been merged. So nothing
to worry about right now.

I have a working solution to fix all of this, but the impact is too
large for both stable and 2.6.22. I'm going to send it out for review
in the next days.

This should go into 2.6.21.stable as well.
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Acked-by: default avatarIngo Molnar <mingo@elte.hu>
Cc: Jan Kiszka <jan.kiszka@web.de>
Cc: Ulrich Drepper <drepper@redhat.com>
Cc: Stable Team <stable@kernel.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
58229a18
Name Last commit Last update
..
irq Fix crash with irqpoll due to the IRQF_IRQPOLL flag testing
power swsusp: Fix userland interface
time timer stats: speedups
.gitignore gitignore: ignore more generated files
Kconfig.hz [PATCH] HZ: 300Hz support
Kconfig.preempt Fix trivial typos in Kconfig* files
Makefile move die notifier handling to common code
acct.c [PATCH] kernel: change uses of f_{dentry, vfsmnt} to use f_path
audit.c audit: add spaces on either side of case "..." operator.
audit.h [PATCH] audit signal recipients
auditfilter.c audit_match_signal() and friends are used only if CONFIG_AUDITSYSCALL is set
auditsc.c [PATCH] Abnormal End of Processes
capability.c [PATCH] pid: replace do/while_each_task_pid with do/while_each_pid_task
compat.c signal/timer/event: timerfd compat code
configs.c use simple_read_from_buffer in kernel/
cpu.c microcode: use suspend-related CPU hotplug notifications
cpuset.c cpuset: zero malloc - fix for old cpusets
delayacct.c KMEM_CACHE(): simplify slab cache creation
die_notifier.c move die notifier handling to common code
dma.c [PATCH] struct seq_operations and struct file_operations constification
exec_domain.c Remove obsolete #include <linux/config.h>
exit.c pi-futex: fix exit races and locking problems
extable.c [PATCH] symbol_put_addr() locks kernel
fork.c freezer: fix vfork problem
futex.c Revert "futex_requeue_pi optimization"
futex_compat.c
hrtimer.c
itimer.c
kallsyms.c
kexec.c
kfifo.c
kmod.c
kprobes.c
ksysfs.c
kthread.c
latency.c
lockdep.c
lockdep_internals.h
lockdep_proc.c
module.c
mutex-debug.c
mutex-debug.h
mutex.c
mutex.h
nsproxy.c
panic.c
params.c
pid.c
posix-cpu-timers.c
posix-timers.c
printk.c
profile.c
ptrace.c
rcupdate.c
rcutorture.c
relay.c
resource.c
rtmutex-debug.c
rtmutex-debug.h
rtmutex-tester.c
rtmutex.c
rtmutex.h
rtmutex_common.h
rwsem.c
sched.c
seccomp.c
signal.c
softirq.c
softlockup.c
spinlock.c
srcu.c
stacktrace.c
stop_machine.c
sys.c
sys_ni.c
sysctl.c
taskstats.c
time.c
timer.c
tsacct.c
uid16.c
user.c
utsname.c
utsname_sysctl.c
wait.c
workqueue.c