linux/kernel
Oleg Nesterov 13c22168b7 destroy_workqueue() can livelock
Pointed out by Michal Schmidt <mschmidt@redhat.com>.

The bug was introduced in 2.6.22 by me.

cleanup_workqueue_thread() does flush_cpu_workqueue(cwq) in a loop until
->worklist becomes empty.  This is live-lockable, a re-niced caller can get
CPU after wake_up() and insert a new barrier before the lower-priority
cwq->thread has a chance to clear ->current_work.

Change cleanup_workqueue_thread() to do flush_cpu_workqueue(cwq) only once.
 We can rely on the fact that run_workqueue() won't return until it flushes
all works.  So it is safe to call kthread_stop() after that, the "should
stop" request won't be noticed until run_workqueue() returns.

Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru>
Cc: Michal Schmidt <mschmidt@redhat.com>
Cc: Srivatsa Vaddagiri <vatsa@in.ibm.com>
Cc: <stable@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2007-07-17 10:23:03 -07:00
..
irq Improve behaviour of spurious IRQ detect 2007-07-16 09:05:46 -07:00
power
time kallsyms: make KSYM_NAME_LEN include space for trailing '\0' 2007-07-17 10:23:03 -07:00
.gitignore
acct.c
audit.c Freezer: make kernel threads nonfreezable by default 2007-07-17 10:23:02 -07:00
audit.h Audit: add TTY input auditing 2007-07-16 09:05:47 -07:00
auditfilter.c
auditsc.c kerneldoc fix in audit_core_dumps 2007-07-16 09:05:48 -07:00
capability.c
compat.c
configs.c
cpu.c
cpuset.c Reduce cpuset.c write_lock_irq() to read_lock() 2007-07-16 09:05:43 -07:00
delayacct.c
die_notifier.c
dma.c
exec_domain.c
exit.c Freezer: make kernel threads nonfreezable by default 2007-07-17 10:23:02 -07:00
extable.c
fork.c Freezer: make kernel threads nonfreezable by default 2007-07-17 10:23:02 -07:00
futex.c FUTEX: Tidy up the code 2007-07-16 09:05:49 -07:00
futex_compat.c
hrtimer.c [HRTIMER] Fix cpu pointer arg to clockevents_notify() 2007-07-16 17:29:56 -07:00
itimer.c
kallsyms.c kallsyms: make KSYM_NAME_LEN include space for trailing '\0' 2007-07-17 10:23:03 -07:00
Kconfig.hz
Kconfig.preempt
kexec.c
kfifo.c is_power_of_2: kernel/kfifo.c 2007-07-16 09:05:50 -07:00
kmod.c
kprobes.c
ksysfs.c
kthread.c mm: fix improper .init-type section references 2007-07-16 09:05:36 -07:00
latency.c
lockdep.c kallsyms: make KSYM_NAME_LEN include space for trailing '\0' 2007-07-17 10:23:03 -07:00
lockdep_internals.h
lockdep_proc.c
Makefile user namespace: add the framework 2007-07-16 09:05:47 -07:00
module.c kallsyms: make KSYM_NAME_LEN include space for trailing '\0' 2007-07-17 10:23:03 -07:00
mutex-debug.c
mutex-debug.h
mutex.c
mutex.h
nsproxy.c namespace: ensure clone_flags are always stored in an unsigned long 2007-07-16 09:05:48 -07:00
panic.c Report that kernel is tainted if there was an OOPS 2007-07-17 10:23:02 -07:00
params.c
pid.c namespace: ensure clone_flags are always stored in an unsigned long 2007-07-16 09:05:48 -07:00
posix-cpu-timers.c
posix-timers.c
printk.c kernel/printk.c: document possible deadlock against scheduler 2007-07-16 09:05:52 -07:00
profile.c
ptrace.c PTRACE_POKEDATA consolidation 2007-07-17 10:23:03 -07:00
rcupdate.c
rcutorture.c Freezer: make kernel threads nonfreezable by default 2007-07-17 10:23:02 -07:00
relay.c
resource.c
rtmutex-debug.c FUTEX: Tidy up the code 2007-07-16 09:05:49 -07:00
rtmutex-debug.h
rtmutex-tester.c Freezer: make kernel threads nonfreezable by default 2007-07-17 10:23:02 -07:00
rtmutex.c FUTEX: Tidy up the code 2007-07-16 09:05:49 -07:00
rtmutex.h
rtmutex_common.h FUTEX: Tidy up the code 2007-07-16 09:05:49 -07:00
rwsem.c
sched.c Freezer: make kernel threads nonfreezable by default 2007-07-17 10:23:02 -07:00
sched_debug.c
sched_fair.c
sched_idletask.c
sched_rt.c
sched_stats.h
seccomp.c make seccomp zerocost in schedule 2007-07-16 09:05:50 -07:00
signal.c vdso: print fatal signals 2007-07-16 09:05:43 -07:00
softirq.c Freezer: make kernel threads nonfreezable by default 2007-07-17 10:23:02 -07:00
softlockup.c Freezer: make kernel threads nonfreezable by default 2007-07-17 10:23:02 -07:00
spinlock.c
srcu.c
stacktrace.c
stop_machine.c Fix stop_machine_run problem with naughty real time process 2007-07-16 09:05:41 -07:00
sys.c move seccomp from /proc to a prctl 2007-07-16 09:05:50 -07:00
sys_ni.c diskquota: 32bit quota tools on 64bit architectures 2007-07-16 09:05:48 -07:00
sysctl.c proper prototype for proc_nr_files() 2007-07-17 10:23:03 -07:00
taskstats.c taskstats: add context-switch counters 2007-07-16 09:05:46 -07:00
time.c sys_time() speedup 2007-07-16 09:05:48 -07:00
timer.c Slab allocators: Replace explicit zeroing with __GFP_ZERO 2007-07-17 10:23:02 -07:00
tsacct.c
uid16.c
user.c user namespace: add the framework 2007-07-16 09:05:47 -07:00
user_namespace.c fix create_new_namespaces() return value 2007-07-16 09:05:47 -07:00
utsname.c namespace: ensure clone_flags are always stored in an unsigned long 2007-07-16 09:05:48 -07:00
utsname_sysctl.c remove CONFIG_UTS_NS and CONFIG_IPC_NS 2007-07-16 09:05:47 -07:00
wait.c
workqueue.c destroy_workqueue() can livelock 2007-07-17 10:23:03 -07:00