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 > >

