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>
Prateek Sood <prsood@codeaurora.org>
Loading
Please register or sign in to comment
