On Mon, 20 Jul 2026 at 06:39, Akihiko Odaki
<[email protected]> wrote:
>
> Convert the list of PMUs to a RCU-protected list that has primitives to
> avoid read-side contention.
>
> Assisted-by: Codex:gpt-5.5
> Signed-off-by: Akihiko Odaki <[email protected]>

Reviewed-by: Fuad Tabba <[email protected]>

Cheers,
/fuad


> ---
>  arch/arm64/kvm/pmu-emul.c | 18 ++++++++++--------
>  1 file changed, 10 insertions(+), 8 deletions(-)
>
> diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
> index 9ac5f307ea31..c5c505b6fc61 100644
> --- a/arch/arm64/kvm/pmu-emul.c
> +++ b/arch/arm64/kvm/pmu-emul.c
> @@ -7,9 +7,9 @@
>  #include <linux/cpu.h>
>  #include <linux/kvm.h>
>  #include <linux/kvm_host.h>
> -#include <linux/list.h>
>  #include <linux/perf_event.h>
>  #include <linux/perf/arm_pmu.h>
> +#include <linux/rculist.h>
>  #include <linux/uaccess.h>
>  #include <asm/kvm_emulate.h>
>  #include <kvm/arm_pmu.h>
> @@ -20,6 +20,10 @@
>  #define MDCR_EL2_PMU_RECREATE_MASK     (MDCR_EL2_HPMN | MDCR_EL2_HPMD | \
>                                          MDCR_EL2_HLP)
>
> +/*
> + * arm_pmus is append-only. kvm_supports_guest_pmuv3() feeds persistent
> + * VM state, so a true result must remain valid after the check.
> + */
>  static LIST_HEAD(arm_pmus);
>  static DEFINE_MUTEX(arm_pmus_lock);
>
> @@ -29,7 +33,6 @@ static bool kvm_pmu_counter_is_enabled(struct kvm_pmc *pmc);
>
>  bool kvm_supports_guest_pmuv3(void)
>  {
> -       guard(mutex)(&arm_pmus_lock);
>         return !list_empty(&arm_pmus);
>  }
>
> @@ -807,7 +810,7 @@ void kvm_host_pmu_init(struct arm_pmu *pmu)
>                 return;
>
>         entry->arm_pmu = pmu;
> -       list_add_tail(&entry->entry, &arm_pmus);
> +       list_add_tail_rcu(&entry->entry, &arm_pmus);
>  }
>
>  static struct arm_pmu *kvm_pmu_probe_armpmu(void)
> @@ -816,7 +819,7 @@ static struct arm_pmu *kvm_pmu_probe_armpmu(void)
>         struct arm_pmu *pmu;
>         int cpu;
>
> -       guard(mutex)(&arm_pmus_lock);
> +       guard(rcu)();
>
>         /*
>          * It is safe to use a stale cpu to iterate the list of PMUs so long 
> as
> @@ -836,7 +839,7 @@ static struct arm_pmu *kvm_pmu_probe_armpmu(void)
>          * carried here.
>          */
>         cpu = raw_smp_processor_id();
> -       list_for_each_entry(entry, &arm_pmus, entry) {
> +       list_for_each_entry_rcu(entry, &arm_pmus, entry) {
>                 pmu = entry->arm_pmu;
>
>                 if (cpumask_test_cpu(cpu, &pmu->supported_cpus))
> @@ -1088,9 +1091,9 @@ static int kvm_arm_pmu_v3_set_pmu(struct kvm_vcpu 
> *vcpu, int pmu_id)
>         int ret = -ENXIO;
>
>         lockdep_assert_held(&kvm->arch.config_lock);
> -       mutex_lock(&arm_pmus_lock);
> +       guard(rcu)();
>
> -       list_for_each_entry(entry, &arm_pmus, entry) {
> +       list_for_each_entry_rcu(entry, &arm_pmus, entry) {
>                 arm_pmu = entry->arm_pmu;
>                 if (arm_pmu->pmu.type == pmu_id) {
>                         if (kvm_vm_has_ran_once(kvm) ||
> @@ -1106,7 +1109,6 @@ static int kvm_arm_pmu_v3_set_pmu(struct kvm_vcpu 
> *vcpu, int pmu_id)
>                 }
>         }
>
> -       mutex_unlock(&arm_pmus_lock);
>         return ret;
>  }
>
>
> --
> 2.55.0
>
>

Reply via email to