diff options
author | Prateek Sood <prsood@codeaurora.org> | 2017-09-08 13:10:55 +0530 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2017-09-13 00:24:53 -0700 |
commit | da781e2b84b23ffade73c9998b709cf57a98dee4 (patch) | |
tree | 77551d42e92541a9fe032fc20d8e7eb0fe185e5c /kernel/cpu.c | |
parent | 14f6bfeeebb97c02cbf0c43818f7998e3bdb3cae (diff) |
cgroup/cpuset: remove circular dependency deadlock
Remove circular dependency deadlock in a scenario where hotplug of CPU is
being done while there is updation in cgroup and cpuset triggered from
userspace.
Process A => kthreadd => Process B => Process C => Process A
Process A
cpu_subsys_offline();
cpu_down();
_cpu_down();
mutex_lock(&cpuhotplug.lock); //held
__cpu_notify();
workqueue_cpu_down_callback();
queue_work_on(system_highpri_wq);
__queue_work();
insert_work();
wake_up_worker(); //pool->nr_running = 0
flush_work();
wait_for_completion();
worker_thread();
need_more_worker(); // returns true
manage_workers();
maybe_create_worker();
create_worker();
kthread_create_on_node();
wake_up_process(kthreadd_task);
kthreadd
kthreadd();
kernel_thread();
do_fork();
copy_process();
percpu_down_read(&cgroup_threadgroup_rwsem);
__rwsem_down_read_failed_common(); //waiting
Process B
kernfs_fop_write();
cgroup_file_write();
cgroup_tasks_write();
percpu_down_write(&cgroup_threadgroup_rwsem); //held
cgroup_attach_task();
cgroup_migrate();
cgroup_taskset_migrate();
cpuset_can_attach();
mutex_lock(&cpuset_mutex); //waiting
Process C
kernfs_fop_write();
cgroup_file_write();
cpuset_write_resmask();
mutex_lock(&cpuset_mutex); //held
update_cpumask();
update_cpumasks_hier();
rebuild_sched_domains_locked();
get_online_cpus();
mutex_lock(&cpuhotplug.lock); //waiting
Eliminate this dependecy by reordering locking of cpuset_mutex
and cpuhotplug.lock.
Change-Id: Ifd76373d717c53b531623a3be76b7d32e0d959fd
Signed-off-by: Prateek Sood <prsood@codeaurora.org>
Diffstat (limited to 'kernel/cpu.c')
-rw-r--r-- | kernel/cpu.c | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/kernel/cpu.c b/kernel/cpu.c index 1d6b0a209bc0..5b4440d57f89 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c @@ -91,6 +91,11 @@ static struct { #define cpuhp_lock_acquire() lock_map_acquire(&cpu_hotplug.dep_map) #define cpuhp_lock_release() lock_map_release(&cpu_hotplug.dep_map) +void cpu_hotplug_mutex_held(void) +{ + lockdep_assert_held(&cpu_hotplug.lock); +} +EXPORT_SYMBOL(cpu_hotplug_mutex_held); void get_online_cpus(void) { |