Re: [PATCH] mm/mmu_notifier: Remove non_block_start/end() from notifier invocation

From: Paolo Bonzini

Date: Tue Aug 11 2026 - 16:24:54 EST


If you want to avoid global contention on reads, you can trade it with
for_each_present_cpu().

On Tue, Aug 11, 2026 at 10:06 PM Sean Christopherson <seanjc@xxxxxxxxxx> wrote:
> +static inline unsigned long kvm_gpc_read_begin(struct kvm *kvm)
> +{
> + unsigned long flags;
> +
> + local_irq_save(flags);
> + cpumask_set_cpu(smp_processor_id(), kvm->gpc_readers);

per_cpu(kvm_gpc_reader, smp_processor_id()) = gpc;

> +}
> +
> +static inline void kvm_gpc_read_end(struct kvm *kvm, unsigned long flags)
> +{
> + cpumask_clear_cpu(smp_processor_id(), kvm->gpc_readers);

per_cpu(kvm_gpc_reader, smp_processor_id()) = NULL;

> + local_irq_restore(flags);
> +}

and then:

for_each_present_cpu(cpu)
if (per_cpu(kvm_gpc_reader, cpu) == gpc)
cpumask_set_cpu(cpu, gpc_readers);
__kvm_kick_many_cpus(cpus, wait);

Alternatively, there's always the poor-man RCU using an rwlock_t; you
do read_lock/read_unlock as usual for begin/end of reads, while the
write side does

write_lock(&kvm->gpc_readers);
write_unlock(&kvm->gpc_readers);

in place of synchronize_src().

Paolo