• Thomas Gleixner's avatar
    watchdog/hardlockup/perf: Prevent CPU hotplug deadlock · 941154bd
    Thomas Gleixner authored
    The following deadlock is possible in the watchdog hotplug code:
    
      cpus_write_lock()
        ...
          takedown_cpu()
            smpboot_park_threads()
              smpboot_park_thread()
                kthread_park()
                  ->park() := watchdog_disable()
                    watchdog_nmi_disable()
                      perf_event_release_kernel();
                        put_event()
                          _free_event()
                            ->destroy() := hw_perf_event_destroy()
                              x86_release_hardware()
                                release_ds_buffers()
                                  get_online_cpus()
    
    when a per cpu watchdog perf event is destroyed which drops the last
    reference to the PMU hardware. The cleanup code there invokes
    get_online_cpus() which instantly deadlocks because the hotplug percpu
    rwsem is write locked.
    
    To solve this add a deferring mechanism:
    
      cpus_write_lock()
    			   kthread_park()
    			    watchdog_nmi_disable(deferred)
    			 ...
    941154bd
cpu.c 43.5 KB