linux-uconsole/kernel
Heiko Carstens 0a8eea5287 nohz: Fix printk_needs_cpu() return value on offline cpus
commit 61ab25447a upstream.

This patch fixes a hang observed with 2.6.32 kernels where timers got enqueued
on offline cpus.

printk_needs_cpu() may return 1 if called on offline cpus. When a cpu gets
offlined it schedules the idle process which, before killing its own cpu, will
call tick_nohz_stop_sched_tick(). That function in turn will call
printk_needs_cpu() in order to check if the local tick can be disabled. On
offline cpus this function should naturally return 0 since regardless if the
tick gets disabled or not the cpu will be dead short after. That is besides the
fact that __cpu_disable() should already have made sure that no interrupts on
the offlined cpu will be delivered anyway.

In this case it prevents tick_nohz_stop_sched_tick() to call
select_nohz_load_balancer(). No idea if that really is a problem. However what
made me debug this is that on 2.6.32 the function get_nohz_load_balancer() is
used within __mod_timer() to select a cpu on which a timer gets enqueued. If
printk_needs_cpu() returns 1 then the nohz_load_balancer cpu doesn't get
updated when a cpu gets offlined. It may contain the cpu number of an offline
cpu. In turn timers get enqueued on an offline cpu and not very surprisingly
they never expire and cause system hangs.

This has been observed 2.6.32 kernels. On current kernels __mod_timer() uses
get_nohz_timer_target() which doesn't have that problem. However there might be
other problems because of the too early exit tick_nohz_stop_sched_tick() in
case a cpu goes offline.

Easiest way to fix this is just to test if the current cpu is offline and call
printk_tick() directly which clears the condition.

Alternatively I tried a cpu hotplug notifier which would clear the condition,
however between calling the notifier function and printk_needs_cpu() something
could have called printk() again and the problem is back again. This seems to
be the safest fix.

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <20101126120235.406766476@de.ibm.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2011-01-07 14:43:03 -08:00
..
gcov gcov: fix null-pointer dereference for certain module types 2010-09-20 13:17:53 -07:00
irq irq: Add new IRQ flag IRQF_NO_SUSPEND 2010-08-13 13:19:50 -07:00
power Freezer: Fix buggy resume test for tasks frozen with cgroup freezer 2010-04-26 07:41:17 -07:00
time timekeeping: Fix clock_gettime vsyscall time warp 2010-08-13 13:20:13 -07:00
trace ring-buffer: Fix typo of time extends per page 2010-10-28 21:44:00 -07:00
.gitignore
acct.c bsdacct: fix uid/gid misreporting 2009-12-18 14:03:52 -08:00
async.c async: Fix lack of boot-time console due to insufficient synchronization 2009-06-08 12:31:53 -07:00
audit.c Audit: send signal info if selinux is disabled 2009-09-24 03:50:26 -04:00
audit.h Fix rule eviction order for AUDIT_DIR 2009-06-24 00:02:38 -04:00
audit_tree.c fix more leaks in audit_tree.c tag_chunk() 2010-01-18 10:19:50 -08:00
audit_watch.c Audit: reorganize struct audit_watch to save 8 bytes 2009-09-24 03:50:25 -04:00
auditfilter.c Audit: clean up all op= output to include string quoting 2009-06-24 00:00:52 -04:00
auditsc.c Audit: rearrange audit_context to save 16 bytes per struct 2009-09-24 03:50:26 -04:00
backtracetest.c
bounds.c
capability.c
cgroup.c cgroups: fix 2.6.32 regression causing BUG_ON() in cgroup_diput() 2010-01-18 10:19:32 -08:00
cgroup_freezer.c Freezer: Fix buggy resume test for tasks frozen with cgroup freezer 2010-04-26 07:41:17 -07:00
compat.c compat: Make compat_alloc_user_space() incorporate the access_ok() 2010-09-20 13:17:57 -07:00
configs.c
cpu.c sched: _cpu_down(): Don't play with current->cpus_allowed 2010-09-20 13:18:08 -07:00
cpuset.c sched: Make select_fallback_rq() cpuset friendly 2010-09-20 13:18:08 -07:00
cred-internals.h
cred.c CRED: Fix a race in creds_are_invalid() in credentials debugging 2010-05-12 14:57:10 -07:00
delayacct.c headers: taskstats_kern.h trim 2009-09-18 09:48:52 -07:00
dma.c
exec_domain.c
exit.c do_exit(): make sure that we run with get_fs() == USER_DS 2010-12-09 13:27:01 -08:00
extable.c
fork.c sched: Fix fork vs hotplug vs cpuset namespaces 2010-09-20 13:18:02 -07:00
freezer.c sched: fix nr_uninterruptible accounting of frozen tasks really 2009-07-18 14:19:53 +02:00
futex.c futex: Fix errors in nested key ref-counting 2010-11-22 10:47:31 -08:00
futex_compat.c futex: Fix compat_futex to be same as futex for REQUEUE_PI 2009-08-10 15:41:12 +02:00
groups.c kernel/groups.c: fix integer overflow in groups_search 2010-09-20 13:17:54 -07:00
hrtimer.c hrtimer: Preserve timer state in remove_hrtimer() 2010-10-28 21:44:01 -07:00
hung_task.c sysctl: remove "struct file *" argument of ->proc_handler 2009-09-24 07:21:04 -07:00
itimer.c itimers: Add tracepoints for itimer 2009-08-29 14:10:07 +02:00
kallsyms.c kallsyms: use new arch_is_kernel_text() 2009-09-23 07:39:30 -07:00
Kconfig.freezer
Kconfig.hz
Kconfig.preempt
kexec.c kexec: fix omitting offset in extended crashkernel syntax 2009-07-29 19:10:34 -07:00
kfifo.c kfifo: Use "const" definitions 2009-09-19 13:13:17 -07:00
kgdb.c sysrq, intel_fb: fix sysrq g collision 2009-05-15 07:56:24 -05:00
kmod.c Revert "kmod: fix race in usermodehelper code" 2009-09-23 18:12:10 -07:00
kprobes.c const: constify remaining file_operations 2009-10-01 16:11:11 -07:00
ksysfs.c
kthread.c cpuset: fix the problem that cpuset_mem_spread_node() returns an offline node 2010-04-01 15:58:46 -07:00
latencytop.c latencytop: fix per task accumulator 2010-12-09 13:26:51 -08:00
lockdep.c Revert "lockdep: fix incorrect percpu usage" 2010-06-01 09:45:46 -07:00
lockdep_internals.h lockdep: BFS cleanup 2009-07-24 10:53:29 +02:00
lockdep_proc.c seq_file: constify seq_operations 2009-09-23 07:39:29 -07:00
lockdep_states.h
Makefile SLOW_WORK: Move slow_work's proc file to debugfs 2009-12-01 08:20:31 -08:00
module.c dynamic debug: move ddebug_remove_module() down into free_module() 2010-08-02 10:20:47 -07:00
mutex-debug.c headers: remove sched.h from interrupt.h 2009-10-11 11:20:58 -07:00
mutex-debug.h
mutex.c mutex: Fix optimistic spinning vs. BKL 2010-07-05 11:10:31 -07:00
mutex.h
notifier.c
ns_cgroup.c cgroups: let ss->can_attach and ss->attach do whole threadgroups at a time 2009-09-24 07:20:58 -07:00
nsproxy.c nsproxy: extract create_nsproxy() 2009-06-18 13:03:56 -07:00
panic.c Merge branch 'core-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip 2009-10-08 12:16:35 -07:00
params.c param: fix setting arrays of bool 2009-10-29 08:56:20 +10:30
perf_event.c Fix racy use of anon_inode_getfd() in perf_event.c 2010-07-05 11:10:30 -07:00
pid.c mm: also use alloc_large_system_hash() for the PID hash table 2009-09-22 07:17:38 -07:00
pid_namespace.c pidns: deny CLONE_PARENT|CLONE_NEWPID combination 2009-09-24 07:21:04 -07:00
pm_qos_params.c
posix-cpu-timers.c itimers: Add tracepoints for itimer 2009-08-29 14:10:07 +02:00
posix-timers.c posix_timer: Fix error path in timer_create 2010-07-05 11:10:30 -07:00
printk.c nohz: Fix printk_needs_cpu() return value on offline cpus 2011-01-07 14:43:03 -08:00
profile.c profile: fix stats and data leakage 2010-05-26 14:29:18 -07:00
ptrace.c ptrace: __ptrace_detach: do __wake_up_parent() if we reap the tracee 2009-09-24 07:20:59 -07:00
rcupdate.c rcu: Move rcu_barrier() to rcutree 2009-10-07 08:11:20 +02:00
rcutorture.c rcu: Clean up code to address Ingo's checkpatch feedback 2009-09-23 19:46:30 +02:00
rcutree.c rcu: Fix note_new_gpnum() uses of ->gpnum 2009-12-18 14:03:01 -08:00
rcutree.h rcu: Remove inline from forward-referenced functions 2009-12-18 14:03:04 -08:00
rcutree_plugin.h rcu: Remove inline from forward-referenced functions 2009-12-18 14:03:04 -08:00
rcutree_trace.c rcu: Make hot-unplugged CPU relinquish its own RCU callbacks 2009-10-07 08:11:20 +02:00
relay.c const: mark struct vm_struct_operations 2009-09-27 11:39:25 -07:00
res_counter.c memcg: some modification to softlimit under hierarchical memory reclaim. 2009-10-01 16:11:13 -07:00
resource.c walk system ram range 2009-09-23 07:39:41 -07:00
rtmutex-debug.c
rtmutex-debug.h
rtmutex-tester.c
rtmutex.c rtmutex: Avoid deadlock in rt_mutex_start_proxy_lock() 2009-08-06 05:50:21 +02:00
rtmutex.h
rtmutex_common.h
rwsem.c
sched.c sched: Fix string comparison in /proc/sched_features 2010-11-22 10:47:30 -08:00
sched_clock.c sched: Fix cpu_clock() in NMIs, on !CONFIG_HAVE_UNSTABLE_SCHED_CLOCK 2010-01-22 15:18:30 -08:00
sched_cpupri.c sched: Add new prio to cpupri before removing old prio 2009-08-02 14:26:09 +02:00
sched_cpupri.h
sched_debug.c sched: Remove forced2_migrations stats 2010-09-20 13:17:59 -07:00
sched_fair.c sched: Fix select_idle_sibling() logic in select_task_rq_fair() 2010-09-20 13:18:12 -07:00
sched_features.h sched: Add new wakeup preemption mode: WAKEUP_RUNNING 2009-09-17 10:17:25 +02:00
sched_idletask.c sched: Fix TASK_WAKING vs fork deadlock 2010-09-20 13:18:09 -07:00
sched_rt.c sched: Fix TASK_WAKING vs fork deadlock 2010-09-20 13:18:09 -07:00
sched_stats.h
seccomp.c
semaphore.c
signal.c signals: check_kill_permission(): don't check creds if same_thread_group() 2010-07-05 11:10:56 -07:00
slow-work-debugfs.c SLOW_WORK: Move slow_work's proc file to debugfs 2009-12-01 08:20:31 -08:00
slow-work.c slow-work: use get_ref wrapper instead of directly calling get_ref 2010-08-10 10:20:45 -07:00
slow-work.h SLOW_WORK: Move slow_work's proc file to debugfs 2009-12-01 08:20:31 -08:00
smp.c cpumask: remove arch_send_call_function_ipi 2009-09-24 09:34:47 +09:30
softirq.c softirq: add BLOCK_IOPOLL to softirq_to_name 2009-09-17 15:53:44 -04:00
softlockup.c softlockup: Stop spurious softlockup messages due to overflow 2010-04-01 15:58:47 -07:00
spinlock.c locking: Allow arch-inlined spinlocks 2009-08-31 18:08:50 +02:00
srcu.c
stacktrace.c
stop_machine.c
sys.c pid: make setpgid() system call use RCU read-side critical section 2010-09-26 17:21:25 -07:00
sys_ni.c Merge branch 'master' of /home/davem/src/GIT/linux-2.6/ 2009-09-24 15:13:11 -07:00
sysctl.c kernel/sysctl.c: fix stable merge error in NOMMU mmap_min_addr 2010-01-18 10:19:49 -08:00
sysctl_check.c NET: fix oops at bootime in sysctl code 2010-02-09 04:51:02 -08:00
taskstats.c genetlink: make netns aware 2009-07-12 14:03:27 -07:00
test_kprobes.c
time.c time: Prevent 32 bit overflow with set_normalized_timespec() 2009-09-15 10:17:30 +02:00
timeconst.pl
timer.c Merge branch 'timers-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip 2009-09-23 09:46:15 -07:00
tracepoint.c trivial: fix typo "to to" in multiple files 2009-09-21 15:14:55 +02:00
tsacct.c
uid16.c headers: utsname.h redux 2009-09-23 18:13:10 -07:00
up.c
user.c uids: Prevent tear down race 2009-11-02 16:02:39 +01:00
user_namespace.c
utsname.c utsns: extract creeate_uts_ns() 2009-06-18 13:03:55 -07:00
utsname_sysctl.c sysctl: remove "struct file *" argument of ->proc_handler 2009-09-24 07:21:04 -07:00
wait.c locking, sched: Give waitqueue spinlocks their own lockdep classes 2009-08-10 14:43:09 +02:00
workqueue.c workqueue: fix race condition in schedule_on_each_cpu() 2009-11-17 17:40:33 -08:00