Thomas Gleixner
ceb354b102
smp/hotplug: Move unparking of percpu threads to the control CPU
...
Vikram reported the following backtrace:
BUG: scheduling while atomic: swapper/7/0/0x00000002
CPU: 7 PID: 0 Comm: swapper/7 Not tainted 4.9.32-perf+ #680
schedule
schedule_hrtimeout_range_clock
schedule_hrtimeout
wait_task_inactive
__kthread_bind_mask
__kthread_bind
__kthread_unpark
kthread_unpark
cpuhp_online_idle
cpu_startup_entry
secondary_start_kernel
He analyzed correctly that a parked cpu hotplug thread of an offlined CPU
was still on the runqueue when the CPU came back online and tried to unpark
it. This causes the thread which invoked kthread_unpark() to call
wait_task_inactive() and subsequently schedule() with preemption disabled.
His proposed workaround was to "make sure" that a parked thread has
scheduled out when the CPU goes offline, so the situation cannot happen.
But that's still wrong because the root cause is not the fact that the
percpu thread is still on the runqueue and neither that preemption is
disabled, which could be simply solved by enabling preemption before
calling kthread_unpark().
The real issue is that the calling thread is the idle task of the upcoming
CPU, which is not supposed to call anything which might sleep. The moron,
who wrote that code, missed completely that kthread_unpark() might end up
in schedule().
The solution is simpler than expected. The thread which controls the
hotplug operation is waiting for the CPU to call complete() on the hotplug
state completion. So the idle task of the upcoming CPU can set its state to
CPUHP_AP_ONLINE_IDLE and invoke complete(). This in turn wakes the control
task on a different CPU, which then can safely do the unpark and kick the
now unparked hotplug thread of the upcoming CPU to complete the bringup to
the final target state.
Control CPU AP
bringup_cpu();
__cpu_up() ------------>
bringup_ap();
bringup_wait_for_ap()
wait_for_completion();
cpuhp_online_idle();
<------------ complete();
unpark(AP->stopper);
unpark(AP->hotplugthread);
while(1)
do_idle();
kick(AP->hotplugthread);
wait_for_completion(); hotplug_thread()
run_online_callbacks();
complete();
Change-Id: Ic743d0a29bb236c724b5e066b2fe203ced47b8f4
Fixes: 8df3e07e7f ("cpu/hotplug: Let upcoming cpu bring itself fully up")
Reported-by: Vikram Mulukutla <markivx@codeaurora.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra <peterz@infradead.org>
Cc: Sebastian Sewior <bigeasy@linutronix.de>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Tejun Heo <tj@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Link: http://lkml.kernel.org/r/alpine.DEB.2.20.1707042218020.2131@nanos
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Git-commit: 9cd4f1a4e7a858849e889a081a99adff83e08e4c
Git-repo: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
Signed-off-by: Channagoud Kadabi <ckadabi@codeaurora.org>
2017-07-12 16:20:25 -07:00
..
bpf
This is the 4.9.36 stable release
2017-07-05 16:18:14 +02:00
configs
Merge remote-tracking branch '4.9/tmp-75d78c7' into 4.9
2017-07-05 13:17:33 -07:00
debug
This is the 4.9.6 stable release
2017-01-31 13:55:27 -08:00
events
Merge remote-tracking branch '4.9/tmp-184ce81' into msm-4.9
2017-07-07 14:25:13 -07:00
gcov
gcov: add support for gcc version >= 6
2016-07-15 14:54:27 +09:00
irq
Merge "genirq: Don't allow user space to set IRQ affinity to isolated CPUs"
2017-07-06 20:07:11 -07:00
livepatch
livepatch/module: make TAINT_LIVEPATCH module-specific
2016-08-26 14:42:08 +02:00
locking
mutex: Add a delay into the SPIN_ON_OWNER wait loop.
2017-05-23 16:22:46 -07:00
power
kernel: power: qos: Set PM_QOS_SUM type for each cpu
2017-06-29 15:00:18 -06:00
printk
Merge branch 'upstream-linux-4.9.y' into android-4.9
2017-02-23 14:29:44 -08:00
rcu
rcu: update: Make RCU_EXPEDITE_BOOT be the default
2017-05-05 15:41:33 -07:00
sched
Merge "Merge remote-tracking branch '4.9/tmp-184ce81' into msm-4.9"
2017-07-11 18:31:21 -07:00
time
Merge remote-tracking branch '4.9/tmp-75d78c7' into 4.9
2017-07-05 13:17:33 -07:00
trace
Merge "trace: ipc_logging: Fix potential dead in ipc_log_write"
2017-06-28 23:44:28 -07:00
.gitignore
acct.c
async.c
async: export current_is_async()
2015-11-19 17:51:48 +01:00
audit.c
Merge branch 'stable-4.9' of git://git.infradead.org/users/pcmoore/audit
2016-10-04 14:21:41 -07:00
audit.h
Merge branch 'stable-4.8' of git://git.infradead.org/users/pcmoore/audit
2016-07-29 17:54:17 -07:00
audit_fsnotify.c
wrappers for ->i_mutex access
2016-01-22 18:04:28 -05:00
audit_tree.c
audit: cleanup prune_tree_thread
2016-04-04 09:46:47 -04:00
audit_watch.c
Merge branch 'stable-4.8' of git://git.infradead.org/users/pcmoore/audit
2016-09-01 15:55:56 -07:00
auditfilter.c
audit: add fields to exclude filter by reusing user filter
2016-06-27 11:01:00 -04:00
auditsc.c
Merge branch 'stable-4.9' of git://git.infradead.org/users/pcmoore/audit
2016-10-04 14:21:41 -07:00
backtracetest.c
bounds.c
capability.c
ptrace: Capture the ptracer's creds not PT_PTRACE_CAP
2017-01-06 10:40:13 +01:00
cgroup.c
Merge remote-tracking branch '4.9/tmp-da3493c' into 4.9
2017-06-15 13:20:27 -07:00
cgroup_freezer.c
cgroup: kill cgrp_ss_priv[CGROUP_CANFORK_COUNT] and friends
2015-12-03 10:24:08 -05:00
cgroup_pids.c
cgroup/pids: remove spurious suspicious RCU usage warning
2017-03-26 13:05:58 +02:00
compat.c
configs.c
context_tracking.c
context_tracking: Switch to new static_branch API
2015-11-24 09:56:43 +01:00
cpu.c
smp/hotplug: Move unparking of percpu threads to the control CPU
2017-07-12 16:20:25 -07:00
cpu_pm.c
lpm-levels: Do not disable non-sec interrupts in suspend
2017-02-23 10:43:32 -07:00
cpuset.c
Merge remote-tracking branch '4.9/tmp-da3493c' into 4.9
2017-06-15 13:20:27 -07:00
crash_dump.c
cred.c
cred: Reject inodes with invalid ids in set_create_file_as()
2016-06-30 18:05:09 -05:00
delayacct.c
kmemcg: account certain kmem allocations to memcg
2016-01-14 16:00:49 -08:00
dma.c
elfcore.c
exec_domain.c
exit.c
sched: Call sched_exit() when a task is exiting
2017-03-24 15:57:31 -07:00
extable.c
fork.c
Merge remote-tracking branch '4.9/tmp-951d823' into msm-4.9
2017-05-26 15:03:31 -07:00
freezer.c
freezer, oom: check TIF_MEMDIE on the correct task
2016-07-28 16:07:41 -07:00
futex.c
futex: Add missing error handling to FUTEX_REQUEUE_PI
2017-03-22 12:43:40 +01:00
futex_compat.c
ptrace: use fsuid, fsgid, effective creds for fs access checks
2016-01-20 17:09:18 -08:00
groups.c
cred: simpler, 1D supplementary groups
2016-10-07 18:46:30 -07:00
hung_task.c
hung_task: allow hung_task_panic when hung_task_warnings is 0
2016-10-11 15:06:33 -07:00
irq_work.c
treewide: Remove old email address
2015-11-23 09:44:58 +01:00
jump_label.c
jump_labels: API for flushing deferred jump label updates
2017-01-19 20:17:59 +01:00
kallsyms.c
kallsyms: add support for relative offsets in kallsyms address table
2016-03-15 16:55:16 -07:00
kcmp.c
ptrace: use fsuid, fsgid, effective creds for fs access checks
2016-01-20 17:09:18 -08:00
Kconfig.freezer
Kconfig.hz
Kconfig.locks
Kconfig.preempt
kcov.c
kcov: add missing #include <linux/sched.h>
2016-12-07 17:10:00 -08:00
kexec.c
kexec: allow architectures to override boot mapping
2016-08-02 19:35:27 -04:00
kexec_core.c
kexec: add restriction on kexec_load() segment sizes
2016-08-02 19:35:31 -04:00
kexec_file.c
kexec: fix double-free when failing to relocate the purgatory
2016-09-01 17:52:01 -07:00
kexec_internal.h
kexec: move some memembers and definitions within the scope of CONFIG_KEXEC_FILE
2016-01-20 17:09:18 -08:00
kmod.c
kprobes.c
tracing/kprobes: Enforce kprobes teardown after testing
2017-05-25 15:44:47 +02:00
ksysfs.c
kexec: add a kexec_crash_loaded() function
2016-08-02 19:35:30 -04:00
kthread.c
kthread: Ensure task isn't preempted before dequeue in kthread_parkme
2017-06-25 01:13:01 -07:00
latencytop.c
sched/debug: Make schedstats a runtime tunable that is disabled by default
2016-02-09 11:54:23 +01:00
Makefile
kernel/watchdog.c: move hardlockup detector to separate file
2017-06-17 06:41:57 +02:00
membarrier.c
Fix: Disable sys_membarrier when nohz_full is enabled
2017-03-12 06:41:45 +01:00
memremap.c
mm, devm_memremap_pages: hold device_hotplug lock over mem_hotplug_{begin, done}
2017-03-12 06:41:43 +01:00
module-internal.h
module.c
Re-enable CONFIG_MODVERSIONS in a slightly weaker form
2016-11-29 16:01:30 -08:00
module_signing.c
KEYS: Move the point of trust determination to __key_link()
2016-04-11 22:43:43 +01:00
notifier.c
nsproxy.c
cgroup: introduce cgroup namespaces
2016-02-16 13:04:58 -05:00
padata.c
padata: free correct variable
2017-05-20 14:28:40 +02:00
panic.c
kernel/panic.c: add missing \n
2017-07-05 14:40:24 +02:00
params.c
Nothing exciting, minor tweaks and cleanups.
2015-11-09 15:53:39 -08:00
pid.c
Use after free from pid_nr_ns()
2017-02-15 17:40:08 -08:00
pid_namespace.c
pid_ns: Sleep in TASK_INTERRUPTIBLE in zap_pid_ns_processes
2017-05-25 15:44:38 +02:00
profile.c
profile: Convert to hotplug state machine
2016-07-15 10:41:42 +02:00
ptrace.c
ptrace: Properly initialize ptracer_cred on fork
2017-06-14 15:05:54 +02:00
range.c
reboot.c
relay.c
relay: check array offset before using it
2017-01-12 11:39:30 +01:00
resource.c
/proc/iomem: only expose physical resource addresses to privileged users
2016-04-14 12:56:09 -07:00
seccomp.c
seccomp: Fix tracer exit notifications during fatal signals
2016-08-30 16:12:46 -07:00
signal.c
signal: Only reschedule timers on signals timers have sent
2017-06-29 13:00:29 +02:00
smp.c
smp: Do not wake up all idle CPUs
2017-02-07 14:50:30 -08:00
smpboot.c
sched: Add per CPU load tracking for each task
2017-02-07 14:50:51 -08:00
smpboot.h
cpu/hotplug: Create hotplug threads
2016-03-01 20:36:56 +01:00
softirq.c
sched: avoid migrating when softint on tgt cpu should be short
2017-06-07 05:53:14 +05:30
stacktrace.c
stacktrace, lockdep: Fix address, newline ugliness
2017-02-14 15:25:42 -08:00
stop_machine.c
Merge branch 'sched-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
2016-10-03 13:39:00 -07:00
sys.c
ANDROID: mm: add a field to store names for private anonymous memory
2017-01-27 13:52:21 -08:00
sys_ni.c
x86/pkeys: Fix pkeys build breakage for some non-x86 arches
2016-09-13 14:41:36 +02:00
sysctl.c
sched: introduce sched_{up,down}migrate knobs
2017-06-21 17:15:50 -07:00
sysctl_binary.c
sysctl: add cold_boot sysctl entry
2017-01-11 13:57:41 -08:00
task_work.c
task_work: use READ_ONCE/lockless_dereference, avoid pi_lock if !task_works
2016-08-02 19:35:02 -04:00
taskstats.c
taskstats: fix the length of cgroupstats_cmd_get_policy
2016-11-03 16:55:58 -04:00
test_kprobes.c
torture.c
torture: Convert torture_shutdown() to hrtimer
2016-08-22 10:01:49 -07:00
tracepoint.c
kernel/...: convert pr_warning to pr_warn
2016-03-22 15:36:02 -07:00
tsacct.c
time, acct: Drop irq save & restore from __acct_update_integrals()
2016-02-29 09:53:09 +01:00
ucount.c
kernel/ucount.c: mark user_header with kmemleak_ignore()
2017-06-17 06:41:51 +02:00
uid16.c
cred: simpler, 1D supplementary groups
2016-10-07 18:46:30 -07:00
up.c
smp: Add function to execute a function synchronously on a CPU
2016-09-05 13:52:39 +02:00
user-return-notifier.c
user.c
user_namespace.c
Merge branch 'nsfs-ioctls' into HEAD
2016-09-22 20:00:36 -05:00
utsname.c
Merge branch 'nsfs-ioctls' into HEAD
2016-09-22 20:00:36 -05:00
utsname_sysctl.c
watchdog.c
Merge remote-tracking branch '4.9/tmp-75d78c7' into 4.9
2017-07-05 13:17:33 -07:00
watchdog_hld.c
kernel/watchdog: prevent false hardlockup on overloaded system
2017-06-17 06:41:57 +02:00
workqueue.c
time: Remove CONFIG_TIMER_STATS
2017-05-11 13:26:42 -07:00
workqueue_internal.h
sched/core: Get rid of 'cpu' argument in wq_worker_sleeping()
2016-03-02 10:28:47 -05:00