[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <aFrANSe6fJOfMpOC@google.com>
Date: Tue, 24 Jun 2025 08:11:49 -0700
From: Sean Christopherson <seanjc@...gle.com>
To: Keir Fraser <keirf@...gle.com>
Cc: linux-arm-kernel@...ts.infradead.org, linux-kernel@...r.kernel.org,
kvm@...r.kernel.org, Eric Auger <eric.auger@...hat.com>,
Oliver Upton <oliver.upton@...ux.dev>, Marc Zyngier <maz@...nel.org>, Will Deacon <will@...nel.org>,
Paolo Bonzini <pbonzini@...hat.com>, Li RongQing <lirongqing@...du.com>
Subject: Re: [PATCH 3/3] KVM: Avoid synchronize_srcu() in kvm_io_bus_register_dev()
+Li
On Tue, Jun 24, 2025, Keir Fraser wrote:
> Device MMIO registration may happen quite frequently during VM boot,
> and the SRCU synchronization each time has a measurable effect
> on VM startup time. In our experiments it can account for around 25%
> of a VM's startup time.
>
> Replace the synchronization with a deferred free of the old kvm_io_bus
> structure.
>
> Signed-off-by: Keir Fraser <keirf@...gle.com>
> ---
> include/linux/kvm_host.h | 1 +
> virt/kvm/kvm_main.c | 10 ++++++++--
> 2 files changed, 9 insertions(+), 2 deletions(-)
>
> diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
> index 3bde4fb5c6aa..28a63f1ad314 100644
> --- a/include/linux/kvm_host.h
> +++ b/include/linux/kvm_host.h
> @@ -205,6 +205,7 @@ struct kvm_io_range {
> struct kvm_io_bus {
> int dev_count;
> int ioeventfd_count;
> + struct rcu_head rcu;
> struct kvm_io_range range[];
> };
>
> diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
> index eec82775c5bf..b7d4da8ba0b2 100644
> --- a/virt/kvm/kvm_main.c
> +++ b/virt/kvm/kvm_main.c
> @@ -5924,6 +5924,13 @@ int kvm_io_bus_read(struct kvm_vcpu *vcpu, enum kvm_bus bus_idx, gpa_t addr,
> }
> EXPORT_SYMBOL_GPL(kvm_io_bus_read);
>
> +static void __free_bus(struct rcu_head *rcu)
> +{
> + struct kvm_io_bus *bus = container_of(rcu, struct kvm_io_bus, rcu);
> +
> + kfree(bus);
> +}
> +
> int kvm_io_bus_register_dev(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr,
> int len, struct kvm_io_device *dev)
> {
> @@ -5962,8 +5969,7 @@ int kvm_io_bus_register_dev(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr,
> memcpy(new_bus->range + i + 1, bus->range + i,
> (bus->dev_count - i) * sizeof(struct kvm_io_range));
> rcu_assign_pointer(kvm->buses[bus_idx], new_bus);
> - synchronize_srcu_expedited(&kvm->srcu);
> - kfree(bus);
> + call_srcu(&kvm->srcu, &bus->rcu, __free_bus);
I'm 99% certain this will break ABI. KVM needs to ensure all readers are guaranteed
to see the new device prior to returning to userspace. I'm quite confident there
are other flows that rely on the synchronization, the vGIC case is simply the one
that's documented.
https://lore.kernel.org/all/aAkAY40UbqzQNr8m@google.com
Powered by blists - more mailing lists