• Kan Liang's avatar
    iommu/vt-d: Fix an IOMMU perfmon warning when CPU hotplug · 16812c96
    Kan Liang authored
    A warning can be triggered when hotplug CPU 0.
    $ echo 0 > /sys/devices/system/cpu/cpu0/online
    
     ------------[ cut here ]------------
     Voluntary context switch within RCU read-side critical section!
     WARNING: CPU: 0 PID: 19 at kernel/rcu/tree_plugin.h:318
              rcu_note_context_switch+0x4f4/0x580
     RIP: 0010:rcu_note_context_switch+0x4f4/0x580
     Call Trace:
      <TASK>
      ? perf_event_update_userpage+0x104/0x150
      __schedule+0x8d/0x960
      ? perf_event_set_state.part.82+0x11/0x50
      schedule+0x44/0xb0
      schedule_timeout+0x226/0x310
      ? __perf_event_disable+0x64/0x1a0
      ? _raw_spin_unlock+0x14/0x30
      wait_for_completion+0x94/0x130
      __wait_rcu_gp+0x108/0x130
      synchronize_rcu+0x67/0x70
      ? invoke_rcu_core+0xb0/0xb0
      ? __bpf_trace_rcu_stall_warning+0x10/0x10
      perf_pmu_migrate_context+0x121/0x370
      iommu_pmu_cpu_offline+0x6a/0xa0
      ? iommu_pmu_del+0x1e0/0x1e0
      cpuhp_invoke_callback+0x129/0x510
      cpuhp_thread_fun+0x94/0x150
      smpboot_thread_fn+0x183/0x220
      ? sort_range+0x20/0x20
      kthread+0xe6/0x110
      ? kthread_complete_and_exit+0x20/0x20
      ret_from_fork+0x1f/0x30
      </TASK>
     ---[ end trace 0000000000000000 ]---
    
    The synchronize_rcu() will be invoked in the perf_pmu_migrate_context(),
    when migrating a PMU to a new CPU. However, the current for_each_iommu()
    is within RCU read-side critical section.
    
    Two methods were considered to fix the issue.
    - Use the dmar_global_lock to replace the RCU read lock when going
      through the drhd list. But it triggers a lockdep warning.
    - Use the cpuhp_setup_state_multi() to set up a dedicated state for each
      IOMMU PMU. The lock can be avoided.
    
    The latter method is implemented in this patch. Since each IOMMU PMU has
    a dedicated state, add cpuhp_node and cpu in struct iommu_pmu to track
    the state. The state can be dynamically allocated now. Remove the
    CPUHP_AP_PERF_X86_IOMMU_PERF_ONLINE.
    
    Fixes: 46284c6c ("iommu/vt-d: Support cpumask for IOMMU perfmon")
    Reported-by: default avatarAmmy Yi <ammy.yi@intel.com>
    Signed-off-by: default avatarKan Liang <kan.liang@linux.intel.com>
    Link: https://lore.kernel.org/r/20230328182028.1366416-1-kan.liang@linux.intel.comSigned-off-by: default avatarLu Baolu <baolu.lu@linux.intel.com>
    Link: https://lore.kernel.org/r/20230329134721.469447-4-baolu.lu@linux.intel.comSigned-off-by: default avatarJoerg Roedel <jroedel@suse.de>
    16812c96
perfmon.c 25 KB