Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1728340
| From | Peter Zijlstra <peterz@infradead.org> |
|---|---|
| Newsgroups | linux.kernel |
| Subject | Re: [PATCH] cgroup/cpuset: remove circular dependency deadlock |
| Date | 2017-09-07 19:50 +0200 |
| Message-ID | <un96a-3hI-11@gated-at.bofh.it> (permalink) |
| References | <un5vA-A2-9@gated-at.bofh.it> |
| Organization | linux.* mail to news gateway |
On Thu, Sep 07, 2017 at 07:26:23PM +0530, Prateek Sood wrote: > 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(); > percpu_down_write(&cpu_hotplug_lock); //held > cpuhp_invoke_callback(); > workqueue_offline_cpu(); > wq_update_unbound_numa(); > kthread_create_on_node(); > wake_up_process(); //wakeup kthreadd TJ, I'm puzzled, why would we need to spawn new threads to update NUMA affinity when taking a CPU out? That doesn't make sense to me, we can either shrink the affinity of an existing thread or completely kill of a thread if the mask becomes empty. But why spawn a new thread? > flush_work(); > wait_for_completion(); > > kthreadd > kthreadd(); > kernel_thread(); > do_fork(); > copy_process(); > percpu_down_read(&cgroup_threadgroup_rwsem); > __rwsem_down_read_failed_common(); //waiting So this will eventually do our: complete() to make A go. > Process B > kernfs_fop_write(); > cgroup_file_write(); > cgroup_procs_write(); > percpu_down_write(&cgroup_threadgroup_rwsem); //held > cgroup_attach_task(); > cgroup_migrate(); > cgroup_migrate_execute(); > 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(); > percpu_down_read(&cpu_hotplug_lock); //waiting So the whole thing looks like: A B C D L(hotplug) L(threadgroup) L(cpuset) L(threadgroup) WFC(c) L(cpuset) L(hotplug) C(c) Yes, inverting cpuset and hotplug would break that chain, but I'm still wondering why workqueue needs to spawn threads on CPU down.
Back to linux.kernel | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
[PATCH] cgroup/cpuset: remove circular dependency deadlock Prateek Sood <prsood@codeaurora.org> - 2017-09-07 16:00 +0200
Re: [PATCH] cgroup/cpuset: remove circular dependency deadlock Peter Zijlstra <peterz@infradead.org> - 2017-09-07 19:50 +0200
Re: [PATCH] cgroup/cpuset: remove circular dependency deadlock Prateek Sood <prsood@codeaurora.org> - 2017-09-08 04:20 +0200
Re: [PATCH] cgroup/cpuset: remove circular dependency deadlock Peter Zijlstra <peterz@infradead.org> - 2017-09-07 20:00 +0200
csiph-web