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 /include/linux/cpu.h | |
| 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 'include/linux/cpu.h')
| -rw-r--r-- | include/linux/cpu.h | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/include/linux/cpu.h b/include/linux/cpu.h index a157a69097b5..a3bcdfbef9ca 100644 --- a/include/linux/cpu.h +++ b/include/linux/cpu.h @@ -234,6 +234,7 @@ extern struct bus_type cpu_subsys; extern void cpu_hotplug_begin(void); extern void cpu_hotplug_done(void); extern void get_online_cpus(void); +extern void cpu_hotplug_mutex_held(void); extern void put_online_cpus(void); extern void cpu_hotplug_disable(void); extern void cpu_hotplug_enable(void); @@ -256,6 +257,7 @@ static inline void cpu_hotplug_done(void) {} #define cpu_hotplug_enable() do { } while (0) #define hotcpu_notifier(fn, pri) do { (void)(fn); } while (0) #define __hotcpu_notifier(fn, pri) do { (void)(fn); } while (0) +#define cpu_hotplug_mutex_held() do { } while (0) /* These aren't inline functions due to a GCC bug. */ #define register_hotcpu_notifier(nb) ({ (void)(nb); 0; }) #define __register_hotcpu_notifier(nb) ({ (void)(nb); 0; }) |
