Woops. Forgot to include my edits. Please ignore. I'll send out another version shortly. Thanks, Marc On Mon, May 14, 2018 at 11:55 AM Marc Orr <marcorr@xxxxxxxxxx> wrote: > The kvm struct has been bloating. For example, it's tens of kilo-bytes > for x86, which turns out to be a large amount of memory to allocate > contiguously via kzalloc. Thus, this patch does the following: > 1. Uses architecture-specific routines to allocat the kvm struct via > kzalloc for x86 and also for arm when has_tbe() is true. > 2. Introduces a baseline allocator for the kvm struct that uses valloc. > This allocator can be used by an architecture by defining the > __KVM_VALLOC_ARCH_VM macro before including include/linux/kvm_host.h. > 3. Finally, continue to default to kalloc for all other situations, as > many architectures have taken a dependence on kalloc. > Signed-off-by: Marc Orr <marcorr@xxxxxxxxxx> > --- > arch/arm/include/asm/kvm_host.h | 4 ++++ > arch/arm/kvm/guest.c | 10 ++++++++++ > arch/arm64/include/asm/kvm_host.h | 4 ++++ > arch/arm64/kvm/guest.c | 10 ++++++++++ > arch/x86/kvm/svm.c | 4 ++-- > arch/x86/kvm/vmx.c | 4 ++-- > include/linux/kvm_host.h | 5 +++-- > 7 files changed, 35 insertions(+), 6 deletions(-) > diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h > index c7c28c885a19..f38fd60b4d4d 100644 > --- a/arch/arm/include/asm/kvm_host.h > +++ b/arch/arm/include/asm/kvm_host.h > @@ -318,4 +318,8 @@ static inline bool kvm_arm_harden_branch_predictor(void) > static inline void kvm_vcpu_load_sysregs(struct kvm_vcpu *vcpu) {} > static inline void kvm_vcpu_put_sysregs(struct kvm_vcpu *vcpu) {} > +#define __KVM_HAVE_ARCH_VM_ALLOC > +struct kvm *kvm_arch_alloc_vm(void); > +void kvm_arch_free_vm(struct kvm *kvm); > + > #endif /* __ARM_KVM_HOST_H__ */ > diff --git a/arch/arm/kvm/guest.c b/arch/arm/kvm/guest.c > index a18f33edc471..e0e9aa6e333b 100644 > --- a/arch/arm/kvm/guest.c > +++ b/arch/arm/kvm/guest.c > @@ -42,6 +42,16 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { > { NULL } > }; > +struct kvm *kvm_arch_alloc_vm(void) > +{ > + return kzalloc(sizeof(struct kvm), GFP_KERNEL); > +} > + > +void kvm_arch_free_vm(struct kvm *kvm) > +{ > + kfree(kvm); > +} > + > int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) > { > return 0; > diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h > index 469de8acd06f..358b1b4dcd92 100644 > --- a/arch/arm64/include/asm/kvm_host.h > +++ b/arch/arm64/include/asm/kvm_host.h > @@ -455,4 +455,8 @@ static inline bool kvm_arm_harden_branch_predictor(void) > void kvm_vcpu_load_sysregs(struct kvm_vcpu *vcpu); > void kvm_vcpu_put_sysregs(struct kvm_vcpu *vcpu); > +#define __KVM_HAVE_ARCH_VM_ALLOC > +struct kvm *kvm_arch_alloc_vm(void); > +void kvm_arch_free_vm(struct kvm *kvm); > + > #endif /* __ARM64_KVM_HOST_H__ */ > diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c > index 56a0260ceb11..7a788e1f5cf3 100644 > --- a/arch/arm64/kvm/guest.c > +++ b/arch/arm64/kvm/guest.c > @@ -47,6 +47,16 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { > { NULL } > }; > +struct kvm *kvm_arch_alloc_vm(void) > +{ > + return kzalloc(sizeof(struct kvm), GFP_KERNEL); > +} > + > +void kvm_arch_free_vm(struct kvm *kvm) > +{ > + kfree(kvm); > +} > + > int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) > { > return 0; > diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c > index 1fc05e428aba..45b903ed3e5d 100644 > --- a/arch/x86/kvm/svm.c > +++ b/arch/x86/kvm/svm.c > @@ -1849,13 +1849,13 @@ static void __unregister_enc_region_locked(struct kvm *kvm, > static struct kvm *svm_vm_alloc(void) > { > - struct kvm_svm *kvm_svm = kzalloc(sizeof(struct kvm_svm), GFP_KERNEL); > + struct kvm_svm *kvm_svm = vzalloc(sizeof(struct kvm_svm)); > return &kvm_svm->kvm; > } > static void svm_vm_free(struct kvm *kvm) > { > - kfree(to_kvm_svm(kvm)); > + vfree(to_kvm_svm(kvm)); > } > static void sev_vm_destroy(struct kvm *kvm) > diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c > index 3f1696570b41..ee85ba887db6 100644 > --- a/arch/x86/kvm/vmx.c > +++ b/arch/x86/kvm/vmx.c > @@ -9936,13 +9936,13 @@ STACK_FRAME_NON_STANDARD(vmx_vcpu_run); > static struct kvm *vmx_vm_alloc(void) > { > - struct kvm_vmx *kvm_vmx = kzalloc(sizeof(struct kvm_vmx), GFP_KERNEL); > + struct kvm_vmx *kvm_vmx = vzalloc(sizeof(struct kvm_vmx)); > return &kvm_vmx->kvm; > } > static void vmx_vm_free(struct kvm *kvm) > { > - kfree(to_kvm_vmx(kvm)); > + vfree(to_kvm_vmx(kvm)); > } > static void vmx_switch_vmcs(struct kvm_vcpu *vcpu, struct loaded_vmcs *vmcs) > diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h > index 6d6e79c59e68..ffdc29d8505e 100644 > --- a/include/linux/kvm_host.h > +++ b/include/linux/kvm_host.h > @@ -19,6 +19,7 @@ > #include <linux/preempt.h> > #include <linux/msi.h> > #include <linux/slab.h> > +#include <linux/vmalloc.h> > #include <linux/rcupdate.h> > #include <linux/ratelimit.h> > #include <linux/err.h> > @@ -810,12 +811,12 @@ int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu); > #ifndef __KVM_HAVE_ARCH_VM_ALLOC > static inline struct kvm *kvm_arch_alloc_vm(void) > { > - return kzalloc(sizeof(struct kvm), GFP_KERNEL); > + return vzalloc(sizeof(struct kvm)); > } > static inline void kvm_arch_free_vm(struct kvm *kvm) > { > - kfree(kvm); > + vfree(kvm); > } > #endif > -- > 2.17.0.441.gb46fe60e1d-goog