linux/kernel
Thomas Gleixner ac08c26492 [PATCH] posix-cpu-timers: prevent signal delivery starvation
The integer divisions in the timer accounting code can round the result
down to 0.  Adding 0 is without effect and the signal delivery stops.

Clamp the division result to minimum 1 to avoid this.

Problem was reported by Seongbae Park <spark@google.com>, who provided
also an inital patch.

Roland sayeth:

  I have had some more time to think about the problem, and to reproduce it
  using Toyo's test case.  For the record, if my understanding of the problem
  is correct, this happens only in one very particular case.  First, the
  expiry time has to be so soon that in cputime_t units (usually 1s/HZ ticks)
  it's < nthreads so the division yields zero.  Second, it only affects each
  thread that is so new that its CPU time accumulation is zero so now+0 is
  still zero and ->it_*_expires winds up staying zero.  For the VIRT and PROF
  clocks when cputime_t is tick granularity (or the SCHED clock on
  configurations where sched_clock's value only advances on clock ticks), this
  is not hard to arrange with new threads starting up and blocking before they
  accumulate a whole tick of CPU time.  That's what happens in Toyo's test
  case.

  Note that in general it is fine for that division to round down to zero,
  and set each thread's expiry time to its "now" time.  The problem only
  arises with thread's whose "now" value is still zero, so that now+0 winds up
  0 and is interpreted as "not set" instead of ">= now".  So it would be a
  sufficient and more precise fix to just use max(ticks, 1) inside the loop
  when setting each it_*_expires value.

  But, it does no harm to round the division up to one and always advance
  every thread's expiry time.  If the thread didn't already fire timers for
  the expiry time of "now", there is no expectation that it will do so before
  the next tick anyway.  So I followed Thomas's patch in lifting the max out
  of the loops.

  This patch also covers the reload cases, which are harder to write a test
  for (and I didn't try).  I've tested it with Toyo's case and it fixes that.

[toyoa@mvista.com: fix: min_t -> max_t]
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Roland McGrath <roland@redhat.com>
Cc: Daniel Walker <dwalker@mvista.com>
Cc: Toyo Abe <toyoa@mvista.com>
Cc: john stultz <johnstul@us.ibm.com>
Cc: Roman Zippel <zippel@linux-m68k.org>
Cc: Seongbae Park <spark@google.com>
Cc: Peter Mattis <pmattis@google.com>
Cc: Rohit Seth <rohitseth@google.com>
Cc: Martin Bligh <mbligh@google.com>
Cc: <stable@kernel.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-10-17 08:18:43 -07:00
..
irq [PATCH] bitmap: parse input from kernel and user buffers 2006-10-11 11:14:22 -07:00
power [PATCH] swsusp: Use suspend_console 2006-10-11 11:14:14 -07:00
time [PATCH] i386 Time: Avoid PIT SMP lockups 2006-10-17 08:18:42 -07:00
.gitignore
Kconfig.hz
Kconfig.preempt
Makefile [PATCH] srcu-3: RCU variant permitting read-side blocking 2006-10-04 07:55:30 -07:00
acct.c
audit.c [PATCH] kauditd_thread warning fix 2006-10-06 08:53:39 -07:00
audit.h
auditfilter.c [PATCH] arch filter lists with < or > should not be accepted 2006-10-04 08:31:16 -04:00
auditsc.c [PATCH] name_count array overrun 2006-10-04 08:31:21 -04:00
capability.c
compat.c [PATCH] BLOCK: Revert patch to hack around undeclared sigset_t in linux/compat.h 2006-10-02 08:03:31 -07:00
configs.c
cpu.c
cpuset.c [PATCH] cpuset ANSI prototype 2006-10-10 15:37:23 -07:00
delayacct.c
dma.c [PATCH] kernel-doc for kernel/dma.c 2006-10-03 08:03:41 -07:00
exec_domain.c
exit.c [PATCH] namespaces: exit_task_namespaces() invalidates nsproxy 2006-10-02 07:57:21 -07:00
extable.c
fork.c [PATCH] IPC namespace - utils 2006-10-02 07:57:22 -07:00
futex.c [PATCH] __user annotations: futex 2006-10-10 15:37:22 -07:00
futex_compat.c [PATCH] __user annotations: futex 2006-10-10 15:37:22 -07:00
hrtimer.c
itimer.c
kallsyms.c [PATCH] Create kallsyms_lookup_size_offset() 2006-10-03 08:03:41 -07:00
kexec.c
kfifo.c
kmod.c [PATCH] introduce kernel_execve 2006-10-02 07:57:23 -07:00
kprobes.c [PATCH] kretprobe spinlock deadlock patch 2006-10-02 07:57:16 -07:00
ksysfs.c
kthread.c
latency.c
lockdep.c [PATCH] lockdep: increase max allowed recursion depth 2006-10-17 08:18:42 -07:00
lockdep_internals.h
lockdep_proc.c
module.c [PATCH] fix Module taint flags listing in Oops/panic 2006-10-11 11:14:21 -07:00
mutex-debug.c
mutex-debug.h
mutex.c
mutex.h
nsproxy.c [PATCH] nsproxy cloning error path fix 2006-10-02 07:57:22 -07:00
panic.c
params.c
pid.c [PATCH] introduce get_task_pid() to fix unsafe get_pid() 2006-10-02 07:57:25 -07:00
posix-cpu-timers.c [PATCH] posix-cpu-timers: prevent signal delivery starvation 2006-10-17 08:18:43 -07:00
posix-timers.c fix file specification in comments 2006-10-03 23:01:26 +02:00
printk.c [PATCH] lockdep: fix printk recursion logic 2006-10-11 11:14:24 -07:00
profile.c [PATCH] bitmap: parse input from kernel and user buffers 2006-10-11 11:14:22 -07:00
ptrace.c
rcupdate.c [PATCH] rcu: simplify/improve batch tuning 2006-10-04 07:55:31 -07:00
rcutorture.c [PATCH] rcu: add sched torture type to rcutorture 2006-10-04 07:55:31 -07:00
relay.c [PATCH] make kernel/relay.c __user-clean 2006-10-10 15:37:22 -07:00
resource.c [PATCH] kernel-doc for kernel/resource.c 2006-10-03 08:03:41 -07:00
rtmutex-debug.c Remove all inclusions of <linux/config.h> 2006-10-04 03:38:54 -04:00
rtmutex-debug.h
rtmutex-tester.c Remove all inclusions of <linux/config.h> 2006-10-04 03:38:54 -04:00
rtmutex.c
rtmutex.h
rtmutex_common.h
rwsem.c
sched.c [PATCH] sched: likely profiling 2006-10-11 11:14:22 -07:00
seccomp.c
signal.c [PATCH] usb: fixup usb so it uses struct pid 2006-10-02 07:57:15 -07:00
softirq.c
softlockup.c
spinlock.c
srcu.c [PATCH] SRCU: report out-of-memory errors 2006-10-04 07:55:30 -07:00
stacktrace.c
stop_machine.c
sys.c [PATCH] SRCU: report out-of-memory errors 2006-10-04 07:55:30 -07:00
sys_ni.c [PATCH] fix epoll_pwait when EPOLL=n 2006-10-16 09:14:05 -07:00
sysctl.c [PATCH] replace cad_pid by a struct pid 2006-10-02 07:57:25 -07:00
taskstats.c
time.c
timer.c
tsacct.c [PATCH] csa accounting taskstats update 2006-10-01 00:39:29 -07:00
uid16.c
unwind.c
user.c
utsname.c [PATCH] namespaces: utsname: implement CLONE_NEWUTS flag 2006-10-02 07:57:22 -07:00
wait.c
workqueue.c [PATCH] mm: kevent threads: use MPOL_DEFAULT 2006-10-11 11:14:19 -07:00