From: Marc Zyngier <maz@kernel.org> Date: 2021-11-05 19:22:29
The kvm structure is pretty large. A large portion of it is the vcpu
array, which is 4kB on x86_64 and arm64 as they deal with 512 vcpu
VMs. Of course, hardly anyone runs VMs this big, so this is often a
net waste of memory and cache locality.
A possible approach is to turn the fixed-size array into an xarray,
which results in a net code deletion after a bit of cleanup.
This series is on top of the current linux/master as it touches the
RISC-V implementation. Only tested on arm64.
Marc Zyngier (5):
KVM: Move wiping of the kvm->vcpus array to common code
KVM: mips: Use kvm_get_vcpu() instead of open-coded access
KVM: s390: Use kvm_get_vcpu() instead of open-coded access
KVM: x86: Use kvm_get_vcpu() instead of open-coded access
KVM: Convert the kvm->vcpus array to a xarray
arch/arm64/kvm/arm.c | 10 +---------
arch/mips/kvm/loongson_ipi.c | 4 ++--
arch/mips/kvm/mips.c | 23 ++---------------------
arch/powerpc/kvm/powerpc.c | 10 +---------
arch/riscv/kvm/vm.c | 10 +---------
arch/s390/kvm/kvm-s390.c | 26 ++++++--------------------
arch/x86/kvm/vmx/posted_intr.c | 2 +-
arch/x86/kvm/x86.c | 9 +--------
include/linux/kvm_host.h | 7 ++++---
virt/kvm/kvm_main.c | 33 ++++++++++++++++++++++++++-------
10 files changed, 45 insertions(+), 89 deletions(-)
--
2.30.2
From: Marc Zyngier <maz@kernel.org> Date: 2021-11-05 19:22:05
As we are about to change the way vcpus are allocated, mandate
the use of kvm_get_vcpu() instead of open-coding the access.
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
arch/mips/kvm/loongson_ipi.c | 4 ++--
arch/mips/kvm/mips.c | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
From: Marc Zyngier <maz@kernel.org> Date: 2021-11-05 19:22:52
As we are about to change the way vcpus are allocated, mandate
the use of kvm_get_vcpu() instead of open-coding the access.
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
arch/s390/kvm/kvm-s390.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
From: Marc Zyngier <maz@kernel.org> Date: 2021-11-05 19:23:15
As we are about to change the way vcpus are allocated, mandate
the use of kvm_get_vcpu() instead of open-coding the access.
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
arch/x86/kvm/vmx/posted_intr.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
From: Marc Zyngier <maz@kernel.org> Date: 2021-11-05 19:23:39
All architectures have similar loops iterating over the vcpus,
freeing one vcpu at a time, and eventually wiping the reference
off the vcpus array. They are also inconsistently taking
the kvm->lock mutex when wiping the references from the array.
Make this code common, which will simplify further changes.
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
arch/arm64/kvm/arm.c | 10 +---------
arch/mips/kvm/mips.c | 21 +--------------------
arch/powerpc/kvm/powerpc.c | 10 +---------
arch/riscv/kvm/vm.c | 10 +---------
arch/s390/kvm/kvm-s390.c | 18 +-----------------
arch/x86/kvm/x86.c | 9 +--------
include/linux/kvm_host.h | 2 +-
virt/kvm/kvm_main.c | 20 ++++++++++++++++++--
8 files changed, 25 insertions(+), 75 deletions(-)
@@ -171,25 +171,6 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)return0;}-voidkvm_mips_free_vcpus(structkvm*kvm)-{-unsignedinti;-structkvm_vcpu*vcpu;--kvm_for_each_vcpu(i,vcpu,kvm){-kvm_vcpu_destroy(vcpu);-}--mutex_lock(&kvm->lock);--for(i=0;i<atomic_read(&kvm->online_vcpus);i++)-kvm->vcpus[i]=NULL;--atomic_set(&kvm->online_vcpus,0);--mutex_unlock(&kvm->lock);-}-staticvoidkvm_mips_free_gpa_pt(structkvm*kvm){/* It should always be safe to remove after flushing the whole range */
From: Marc Zyngier <maz@kernel.org> Date: 2021-11-05 19:24:02
At least on arm64 and x86, the vcpus array is pretty huge (512 entries),
and is mostly empty in most cases (running 512 vcpu VMs is not that
common). This mean that we end-up with a 4kB block of unused memory
in the middle of the kvm structure.
Instead of wasting away this memory, let's use an xarray instead,
which gives us almost the same flexibility as a normal array, but
with a reduced memory usage with smaller VMs.
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
include/linux/kvm_host.h | 5 +++--
virt/kvm/kvm_main.c | 15 +++++++++------
2 files changed, 12 insertions(+), 8 deletions(-)
@@ -552,7 +553,7 @@ struct kvm {structmutexslots_arch_lock;structmm_struct*mm;/* userspace tied to this vm */structkvm_memslots__rcu*memslots[KVM_ADDRESS_SPACE_NUM];-structkvm_vcpu*vcpus[KVM_MAX_VCPUS];+structxarrayvcpu_array;/* Used to wait for completion of MMU notifiers. */spinlock_tmn_invalidate_lock;
@@ -693,7 +694,7 @@ static inline struct kvm_vcpu *kvm_get_vcpu(struct kvm *kvm, int i)/* Pairs with smp_wmb() in kvm_vm_ioctl_create_vcpu. */smp_rmb();-returnkvm->vcpus[i];+returnxa_load(&kvm->vcpu_array,i);}#define kvm_for_each_vcpu(idx, vcpup, kvm) \
@@ -1066,6 +1066,7 @@ static struct kvm *kvm_create_vm(unsigned long type)mutex_init(&kvm->slots_arch_lock);spin_lock_init(&kvm->mn_invalidate_lock);rcuwait_init(&kvm->mn_memslots_update_rcuwait);+xa_init(&kvm->vcpu_array);INIT_LIST_HEAD(&kvm->devices);
@@ -3661,7 +3662,10 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, u32 id)}vcpu->vcpu_idx=atomic_read(&kvm->online_vcpus);-BUG_ON(kvm->vcpus[vcpu->vcpu_idx]);+r=xa_insert(&kvm->vcpu_array,vcpu->vcpu_idx,vcpu,GFP_KERNEL_ACCOUNT);+BUG_ON(r==-EBUSY);+if(r)+gotounlock_vcpu_destroy;/* Fill the stats id string for the vcpu */snprintf(vcpu->stats_id,sizeof(vcpu->stats_id),"kvm-%d/vcpu-%d",
From: Sean Christopherson <seanjc@google.com> Date: 2021-11-05 20:04:46
On Fri, Nov 05, 2021, Marc Zyngier wrote:
quoted hunk
As we are about to change the way vcpus are allocated, mandate
the use of kvm_get_vcpu() instead of open-coding the access.
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
arch/x86/kvm/vmx/posted_intr.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
@@ -272,7 +272,7 @@ int pi_update_irte(struct kvm *kvm, unsigned int host_irq, uint32_t guest_irq,if(!kvm_arch_has_assigned_device(kvm)||!irq_remapping_cap(IRQ_POSTING_CAP)||-!kvm_vcpu_apicv_active(kvm->vcpus[0]))+!kvm_vcpu_apicv_active(kvm_get_vcpu(kvm,0)))
Huh. The existing code is decidedly odd. I think it might even be broken, as
it's not obvious that vCPU0 _must_ be created when e.g. kvm_arch_irq_bypass_add_producer()
is called.
An equivalent, safe check would be:
@@ -272,7 +272,7 @@ int pi_update_irte(struct kvm *kvm, unsigned int host_irq, uint32_t guest_irq,if(!kvm_arch_has_assigned_device(kvm)||!irq_remapping_cap(IRQ_POSTING_CAP)||-!kvm_vcpu_apicv_active(kvm->vcpus[0]))+!kvm_apicv_activated(kvm))return0;idx=srcu_read_lock(&kvm->irq_srcu);
But I think even that is flawed, as APICv can be dynamically deactivated and
re-activated while the VM is running, and I don't see a path that re-updates
the IRTE when APICv is re-activated. So I think a more conservative check is
needed, e.g.
From: Sean Christopherson <seanjc@google.com> Date: 2021-11-05 20:13:01
On Fri, Nov 05, 2021, Marc Zyngier wrote:
All architectures have similar loops iterating over the vcpus,
freeing one vcpu at a time, and eventually wiping the reference
off the vcpus array. They are also inconsistently taking
the kvm->lock mutex when wiping the references from the array.
But why is kvm->lock taken here? Unless I'm overlooking an arch, everyone calls
this from kvm_arch_destroy_vm(), in which case this is the only remaining reference
to @kvm. And if there's some magic path for which that's not true, I don't see how
it can possibly be safe to call kvm_vcpu_destroy() without holding kvm->lock, or
how this would guarantee that all vCPUs have actually been destroyed before nullifying
the array.
+ for (i = 0; i < atomic_read(&kvm->online_vcpus); i++)
+ kvm->vcpus[i] = NULL;
+
+ atomic_set(&kvm->online_vcpus, 0);
+ mutex_unlock(&kvm->lock);
+}
+EXPORT_SYMBOL_GPL(kvm_destroy_vcpus);
From: Sean Christopherson <seanjc@google.com> Date: 2021-11-05 20:22:28
On Fri, Nov 05, 2021, Marc Zyngier wrote:
At least on arm64 and x86, the vcpus array is pretty huge (512 entries),
and is mostly empty in most cases (running 512 vcpu VMs is not that
common). This mean that we end-up with a 4kB block of unused memory
in the middle of the kvm structure.
Heh, x86 is now up to 1024 entries.
quoted hunk
Instead of wasting away this memory, let's use an xarray instead,
which gives us almost the same flexibility as a normal array, but
with a reduced memory usage with smaller VMs.
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
@@ -693,7 +694,7 @@ static inline struct kvm_vcpu *kvm_get_vcpu(struct kvm *kvm, int i) /* Pairs with smp_wmb() in kvm_vm_ioctl_create_vcpu. */ smp_rmb();- return kvm->vcpus[i];+ return xa_load(&kvm->vcpu_array, i); }
It'd be nice for this series to convert kvm_for_each_vcpu() to use xa_for_each()
as well. Maybe as a patch on top so that potential explosions from that are
isolated from the initiali conversion?
Or maybe even use xa_for_each_range() to cap at online_vcpus? That's technically
a functional change, but IMO it's easier to reason about iterating over a snapshot
of vCPUs as opposed to being able to iterate over vCPUs as their being added. In
practice I doubt it matters.
#define kvm_for_each_vcpu(idx, vcpup, kvm) \
xa_for_each_range(&kvm->vcpu_array, idx, vcpup, 0, atomic_read(&kvm->online_vcpus))
From: Marc Zyngier <maz@kernel.org> Date: 2021-11-06 11:18:26
On Fri, 05 Nov 2021 20:12:12 +0000,
Sean Christopherson [off-list ref] wrote:
On Fri, Nov 05, 2021, Marc Zyngier wrote:
quoted
All architectures have similar loops iterating over the vcpus,
freeing one vcpu at a time, and eventually wiping the reference
off the vcpus array. They are also inconsistently taking
the kvm->lock mutex when wiping the references from the array.
But why is kvm->lock taken here? Unless I'm overlooking an arch,
everyone calls this from kvm_arch_destroy_vm(), in which case this
is the only remaining reference to @kvm. And if there's some magic
path for which that's not true, I don't see how it can possibly be
safe to call kvm_vcpu_destroy() without holding kvm->lock, or how
this would guarantee that all vCPUs have actually been destroyed
before nullifying the array.
I asked myself the same question two years ago, and couldn't really
understand the requirement. However, x86 does just that, so I
preserved the behaviour.
If you too believe that this is just wrong, I'm happy to drop the
locking altogether. If that breaks someone's flow, they'll shout soon
enough.
Thanks,
M.
--
Without deviation from the norm, progress is not possible.
From: Marc Zyngier <maz@kernel.org> Date: 2021-11-06 11:49:16
On Fri, 05 Nov 2021 20:21:36 +0000,
Sean Christopherson [off-list ref] wrote:
On Fri, Nov 05, 2021, Marc Zyngier wrote:
quoted
At least on arm64 and x86, the vcpus array is pretty huge (512 entries),
and is mostly empty in most cases (running 512 vcpu VMs is not that
common). This mean that we end-up with a 4kB block of unused memory
in the middle of the kvm structure.
Heh, x86 is now up to 1024 entries.
Humph. I don't want to know whether people are actually using that in
practice. The only time I create VMs with 512 vcpus is to check
whether it still works...
quoted
Instead of wasting away this memory, let's use an xarray instead,
which gives us almost the same flexibility as a normal array, but
with a reduced memory usage with smaller VMs.
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
@@ -693,7 +694,7 @@ static inline struct kvm_vcpu *kvm_get_vcpu(struct kvm *kvm, int i) /* Pairs with smp_wmb() in kvm_vm_ioctl_create_vcpu. */ smp_rmb();- return kvm->vcpus[i];+ return xa_load(&kvm->vcpu_array, i); }
It'd be nice for this series to convert kvm_for_each_vcpu() to use
xa_for_each() as well. Maybe as a patch on top so that potential
explosions from that are isolated from the initiali conversion?
Or maybe even use xa_for_each_range() to cap at online_vcpus?
That's technically a functional change, but IMO it's easier to
reason about iterating over a snapshot of vCPUs as opposed to being
able to iterate over vCPUs as their being added. In practice I
doubt it matters.
#define kvm_for_each_vcpu(idx, vcpup, kvm) \
xa_for_each_range(&kvm->vcpu_array, idx, vcpup, 0, atomic_read(&kvm->online_vcpus))
I think that's already the behaviour of this iterator (we stop at the
first empty slot capped to online_vcpus. The only change in behaviour
is that vcpup currently holds a pointer to the last vcpu in no empty
slot has been encountered. xa_for_each{,_range}() would set the
pointer to NULL at all times.
I doubt anyone relies on that, but it is probably worth eyeballing
some of the use cases...
Thanks,
M.
--
Without deviation from the norm, progress is not possible.
From: Philippe Mathieu-Daudé <hidden> Date: 2021-11-06 15:57:09
On Fri, Nov 5, 2021 at 9:14 PM Marc Zyngier [off-list ref] wrote:
As we are about to change the way vcpus are allocated, mandate
the use of kvm_get_vcpu() instead of open-coding the access.
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
arch/mips/kvm/loongson_ipi.c | 4 ++--
arch/mips/kvm/mips.c | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
From: Marc Zyngier <maz@kernel.org> Date: 2021-11-08 08:23:56
On 2021-11-06 11:48, Marc Zyngier wrote:
On Fri, 05 Nov 2021 20:21:36 +0000,
Sean Christopherson [off-list ref] wrote:
quoted
On Fri, Nov 05, 2021, Marc Zyngier wrote:
quoted
At least on arm64 and x86, the vcpus array is pretty huge (512 entries),
and is mostly empty in most cases (running 512 vcpu VMs is not that
common). This mean that we end-up with a 4kB block of unused memory
in the middle of the kvm structure.
Heh, x86 is now up to 1024 entries.
Humph. I don't want to know whether people are actually using that in
practice. The only time I create VMs with 512 vcpus is to check
whether it still works...
quoted
quoted
Instead of wasting away this memory, let's use an xarray instead,
which gives us almost the same flexibility as a normal array, but
with a reduced memory usage with smaller VMs.
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
@@ -693,7 +694,7 @@ static inline struct kvm_vcpu *kvm_get_vcpu(struct kvm *kvm, int i) /* Pairs with smp_wmb() in kvm_vm_ioctl_create_vcpu. */ smp_rmb();- return kvm->vcpus[i];+ return xa_load(&kvm->vcpu_array, i); }
It'd be nice for this series to convert kvm_for_each_vcpu() to use
xa_for_each() as well. Maybe as a patch on top so that potential
explosions from that are isolated from the initiali conversion?
Or maybe even use xa_for_each_range() to cap at online_vcpus?
That's technically a functional change, but IMO it's easier to
reason about iterating over a snapshot of vCPUs as opposed to being
able to iterate over vCPUs as their being added. In practice I
doubt it matters.
#define kvm_for_each_vcpu(idx, vcpup, kvm) \
xa_for_each_range(&kvm->vcpu_array, idx, vcpup, 0,
atomic_read(&kvm->online_vcpus))
I think that's already the behaviour of this iterator (we stop at the
first empty slot capped to online_vcpus. The only change in behaviour
is that vcpup currently holds a pointer to the last vcpu in no empty
slot has been encountered. xa_for_each{,_range}() would set the
pointer to NULL at all times.
I doubt anyone relies on that, but it is probably worth eyeballing
some of the use cases...
This turned out to be an interesting exercise, as we always use an
int for the index, and the xarray iterators insist on an unsigned
long (and even on a pointer to it). On the other hand, I couldn't
spot any case where we'd rely on the last value of the vcpu pointer.
I'll repost the series once we have a solution for patch #4, and
we can then decide whether we want the iterator churn.
--
Jazz is not dead. It just smells funny...
On Fri, 5 Nov 2021 19:20:57 +0000
Marc Zyngier [off-list ref] wrote:
All architectures have similar loops iterating over the vcpus,
freeing one vcpu at a time, and eventually wiping the reference
off the vcpus array. They are also inconsistently taking
the kvm->lock mutex when wiping the references from the array.
Make this code common, which will simplify further changes.
Signed-off-by: Marc Zyngier <maz@kernel.org>
no objections
Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
@@ -171,25 +171,6 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)return0;}-voidkvm_mips_free_vcpus(structkvm*kvm)-{-unsignedinti;-structkvm_vcpu*vcpu;--kvm_for_each_vcpu(i,vcpu,kvm){-kvm_vcpu_destroy(vcpu);-}--mutex_lock(&kvm->lock);--for(i=0;i<atomic_read(&kvm->online_vcpus);i++)-kvm->vcpus[i]=NULL;--atomic_set(&kvm->online_vcpus,0);--mutex_unlock(&kvm->lock);-}-staticvoidkvm_mips_free_gpa_pt(structkvm*kvm){/* It should always be safe to remove after flushing the whole range */
On Fri, 5 Nov 2021 19:20:59 +0000
Marc Zyngier [off-list ref] wrote:
As we are about to change the way vcpus are allocated, mandate
the use of kvm_get_vcpu() instead of open-coding the access.
Signed-off-by: Marc Zyngier <maz@kernel.org>
makes sense
Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
From: Paolo Bonzini <pbonzini@redhat.com> Date: 2021-11-16 13:50:18
On 11/6/21 12:17, Marc Zyngier wrote:
If you too believe that this is just wrong, I'm happy to drop the
locking altogether. If that breaks someone's flow, they'll shout soon
enough.
Yes, it's not necessary. It was added in 2009 (commit 988a2cae6a3c,
"KVM: Use macro to iterate over vcpus.") and it was unnecessary back
then too.
Paolo
From: Paolo Bonzini <pbonzini@redhat.com> Date: 2021-11-16 14:05:46
On 11/5/21 21:03, Sean Christopherson wrote:
quoted hunk
But I think even that is flawed, as APICv can be dynamically deactivated and
re-activated while the VM is running, and I don't see a path that re-updates
the IRTE when APICv is re-activated. So I think a more conservative check is
needed, e.g.
@@ -272,7 +272,7 @@ int pi_update_irte(struct kvm *kvm, unsigned int host_irq, uint32_t guest_irq,if(!kvm_arch_has_assigned_device(kvm)||!irq_remapping_cap(IRQ_POSTING_CAP)||-!kvm_vcpu_apicv_active(kvm->vcpus[0]))+!irqchip_in_kernel(kvm)||!enable_apicv)return0;idx=srcu_read_lock(&kvm->irq_srcu);
What happens then if pi_pre_block is called and the IRTE denotes a
posted interrupt?
I might be wrong, but it seems to me that you have to change all of the
occurrences this way. As soon as enable_apicv is set, you need to go
through the POSTED_INTR_WAKEUP_VECTOR just in case.
Paolo
The kvm structure is pretty large. A large portion of it is the vcpu
array, which is 4kB on x86_64 and arm64 as they deal with 512 vcpu
VMs. Of course, hardly anyone runs VMs this big, so this is often a
net waste of memory and cache locality.
A possible approach is to turn the fixed-size array into an xarray,
which results in a net code deletion after a bit of cleanup.
This series is on top of the current linux/master as it touches the
RISC-V implementation. Only tested on arm64.
Marc Zyngier (5):
KVM: Move wiping of the kvm->vcpus array to common code
KVM: mips: Use kvm_get_vcpu() instead of open-coded access
KVM: s390: Use kvm_get_vcpu() instead of open-coded access
KVM: x86: Use kvm_get_vcpu() instead of open-coded access
KVM: Convert the kvm->vcpus array to a xarray
arch/arm64/kvm/arm.c | 10 +---------
arch/mips/kvm/loongson_ipi.c | 4 ++--
arch/mips/kvm/mips.c | 23 ++---------------------
arch/powerpc/kvm/powerpc.c | 10 +---------
arch/riscv/kvm/vm.c | 10 +---------
arch/s390/kvm/kvm-s390.c | 26 ++++++--------------------
arch/x86/kvm/vmx/posted_intr.c | 2 +-
arch/x86/kvm/x86.c | 9 +--------
include/linux/kvm_host.h | 7 ++++---
virt/kvm/kvm_main.c | 33 ++++++++++++++++++++++++++-------
10 files changed, 45 insertions(+), 89 deletions(-)
For x86 you can add my:
Tested-by: Juergen Gross <jgross@suse.com>
Juergen
From: Paolo Bonzini <pbonzini@redhat.com> Date: 2021-11-16 14:22:51
On 11/16/21 15:13, Juergen Gross wrote:
On 05.11.21 20:20, Marc Zyngier wrote:
quoted
The kvm structure is pretty large. A large portion of it is the vcpu
array, which is 4kB on x86_64 and arm64 as they deal with 512 vcpu
VMs. Of course, hardly anyone runs VMs this big, so this is often a
net waste of memory and cache locality.
A possible approach is to turn the fixed-size array into an xarray,
which results in a net code deletion after a bit of cleanup.
This series is on top of the current linux/master as it touches the
RISC-V implementation. Only tested on arm64.
Marc Zyngier (5):
KVM: Move wiping of the kvm->vcpus array to common code
KVM: mips: Use kvm_get_vcpu() instead of open-coded access
KVM: s390: Use kvm_get_vcpu() instead of open-coded access
KVM: x86: Use kvm_get_vcpu() instead of open-coded access
KVM: Convert the kvm->vcpus array to a xarray
arch/arm64/kvm/arm.c | 10 +---------
arch/mips/kvm/loongson_ipi.c | 4 ++--
arch/mips/kvm/mips.c | 23 ++---------------------
arch/powerpc/kvm/powerpc.c | 10 +---------
arch/riscv/kvm/vm.c | 10 +---------
arch/s390/kvm/kvm-s390.c | 26 ++++++--------------------
arch/x86/kvm/vmx/posted_intr.c | 2 +-
arch/x86/kvm/x86.c | 9 +--------
include/linux/kvm_host.h | 7 ++++---
virt/kvm/kvm_main.c | 33 ++++++++++++++++++++++++++-------
10 files changed, 45 insertions(+), 89 deletions(-)
For x86 you can add my:
Tested-by: Juergen Gross <jgross@suse.com>
Heh, unfortunately x86 is the only one that needs a change in patch 4.
I'll Cc you on my version.
Paolo
The kvm structure is pretty large. A large portion of it is the vcpu
array, which is 4kB on x86_64 and arm64 as they deal with 512 vcpu
VMs. Of course, hardly anyone runs VMs this big, so this is often a
net waste of memory and cache locality.
A possible approach is to turn the fixed-size array into an xarray,
which results in a net code deletion after a bit of cleanup.
This series is on top of the current linux/master as it touches the
RISC-V implementation. Only tested on arm64.
Marc Zyngier (5):
KVM: Move wiping of the kvm->vcpus array to common code
KVM: mips: Use kvm_get_vcpu() instead of open-coded access
KVM: s390: Use kvm_get_vcpu() instead of open-coded access
KVM: x86: Use kvm_get_vcpu() instead of open-coded access
KVM: Convert the kvm->vcpus array to a xarray
arch/arm64/kvm/arm.c | 10 +---------
arch/mips/kvm/loongson_ipi.c | 4 ++--
arch/mips/kvm/mips.c | 23 ++---------------------
arch/powerpc/kvm/powerpc.c | 10 +---------
arch/riscv/kvm/vm.c | 10 +---------
arch/s390/kvm/kvm-s390.c | 26 ++++++--------------------
arch/x86/kvm/vmx/posted_intr.c | 2 +-
arch/x86/kvm/x86.c | 9 +--------
include/linux/kvm_host.h | 7 ++++---
virt/kvm/kvm_main.c | 33 ++++++++++++++++++++++++++-------
10 files changed, 45 insertions(+), 89 deletions(-)
For x86 you can add my:
Tested-by: Juergen Gross <jgross@suse.com>
Heh, unfortunately x86 is the only one that needs a change in patch 4.
I'll Cc you on my version.
I guess the changes in kvm_main.c are more important for my series. :-)
I've replaced patch 4 with your variant and everything is still working.
Not sure how relevant that is, though.
Juergen
From: Paolo Bonzini <pbonzini@redhat.com> Date: 2021-11-16 15:04:50
On 11/5/21 20:20, Marc Zyngier wrote:
The kvm structure is pretty large. A large portion of it is the vcpu
array, which is 4kB on x86_64 and arm64 as they deal with 512 vcpu
VMs. Of course, hardly anyone runs VMs this big, so this is often a
net waste of memory and cache locality.
A possible approach is to turn the fixed-size array into an xarray,
which results in a net code deletion after a bit of cleanup.
This series is on top of the current linux/master as it touches the
RISC-V implementation. Only tested on arm64.
From: Marc Zyngier <maz@kernel.org> Date: 2021-11-16 15:41:27
On Tue, 16 Nov 2021 15:03:40 +0000,
Paolo Bonzini [off-list ref] wrote:
On 11/5/21 20:20, Marc Zyngier wrote:
quoted
The kvm structure is pretty large. A large portion of it is the vcpu
array, which is 4kB on x86_64 and arm64 as they deal with 512 vcpu
VMs. Of course, hardly anyone runs VMs this big, so this is often a
net waste of memory and cache locality.
A possible approach is to turn the fixed-size array into an xarray,
which results in a net code deletion after a bit of cleanup.
This series is on top of the current linux/master as it touches the
RISC-V implementation. Only tested on arm64.
In which case, let me send a v2 with the changes that we discussed
with Sean. It will still have my version of patch 4, but that's
nothing you can't fix.
M.
--
Without deviation from the norm, progress is not possible.
From: Sean Christopherson <seanjc@google.com> Date: 2021-11-16 16:08:40
On Tue, Nov 16, 2021, Paolo Bonzini wrote:
On 11/5/21 21:03, Sean Christopherson wrote:
quoted
But I think even that is flawed, as APICv can be dynamically deactivated and
re-activated while the VM is running, and I don't see a path that re-updates
the IRTE when APICv is re-activated. So I think a more conservative check is
needed, e.g.
@@ -272,7 +272,7 @@ int pi_update_irte(struct kvm *kvm, unsigned int host_irq, uint32_t guest_irq,if(!kvm_arch_has_assigned_device(kvm)||!irq_remapping_cap(IRQ_POSTING_CAP)||-!kvm_vcpu_apicv_active(kvm->vcpus[0]))+!irqchip_in_kernel(kvm)||!enable_apicv)return0;idx=srcu_read_lock(&kvm->irq_srcu);
What happens then if pi_pre_block is called and the IRTE denotes a posted
interrupt?
I might be wrong, but it seems to me that you have to change all of the
occurrences this way. As soon as enable_apicv is set, you need to go
through the POSTED_INTR_WAKEUP_VECTOR just in case.
Sorry, I didn't grok that at all. All occurences of what?
What happens then if pi_pre_block is called and the IRTE denotes a posted
interrupt?
I might be wrong, but it seems to me that you have to change all of the
occurrences this way. As soon as enable_apicv is set, you need to go
through the POSTED_INTR_WAKEUP_VECTOR just in case.
Sorry, I didn't grok that at all. All occurences of what?
Of the !assigned-device || !VTd-PI || !kvm_vcpu_apicv_active(vcpu)
checks. This way, CPUs are woken up correctly even if you have
!kvm_vcpu_apicv_active(vcpu) but the IRTE is a posted-interrupt one.
Paolo