Message ID | 20180507221846.168814-1-marcorr@google.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Mon, May 07, 2018 at 03:18:46PM -0700, Marc Orr wrote: > The kvm struct is (currently) tens of kilo-bytes, which turns out to be a > large amount of memory to allocate contiguously via kzalloc. Thus, this > patch changes the kzalloc to a vzalloc, so that the memory allocation is > less likely to fail in resource-constrained environments. This will break HV KVM on powerpc, which needs the KVM struct to be physically contiguous and in the linear mapping. We'll need to add #define __KVM_HAVE_ARCH_VM_ALLOC to arch/powerpc/include/asm/kvm_host.h and the kzalloc/kfree variant to arch/powerpc/kvm/powerpc.c much like you did on arm. Paul.
On 05/08/2018 07:14 AM, Paul Mackerras wrote: > On Mon, May 07, 2018 at 03:18:46PM -0700, Marc Orr wrote: >> The kvm struct is (currently) tens of kilo-bytes, which turns out to be a >> large amount of memory to allocate contiguously via kzalloc. Thus, this >> patch changes the kzalloc to a vzalloc, so that the memory allocation is >> less likely to fail in resource-constrained environments. > > This will break HV KVM on powerpc, which needs the KVM struct to be > physically contiguous and in the linear mapping. We'll need to add > #define __KVM_HAVE_ARCH_VM_ALLOC to arch/powerpc/include/asm/kvm_host.h > and the kzalloc/kfree variant to arch/powerpc/kvm/powerpc.c much like > you did on arm. In the end I also want kmalloc for s390 (since we do not need the vmalloc for s390 as we are < 16kb). So Paolo, can we turn things around and only use vmalloc for x86?
On 08/05/2018 07:16, Christian Borntraeger wrote: > On 05/08/2018 07:14 AM, Paul Mackerras wrote: >> On Mon, May 07, 2018 at 03:18:46PM -0700, Marc Orr wrote: >>> The kvm struct is (currently) tens of kilo-bytes, which turns out to be a >>> large amount of memory to allocate contiguously via kzalloc. Thus, this >>> patch changes the kzalloc to a vzalloc, so that the memory allocation is >>> less likely to fail in resource-constrained environments. >> >> This will break HV KVM on powerpc, which needs the KVM struct to be >> physically contiguous and in the linear mapping. We'll need to add >> #define __KVM_HAVE_ARCH_VM_ALLOC to arch/powerpc/include/asm/kvm_host.h >> and the kzalloc/kfree variant to arch/powerpc/kvm/powerpc.c much like >> you did on arm. > > In the end I also want kmalloc for s390 (since we do not need the vmalloc for > s390 as we are < 16kb). > > So Paolo, > can we turn things around and only use vmalloc for x86? > The other idea that the #define would pick kzalloc vs. vzalloc (instead of enabling a custom kvm_arch_alloc_vm) would be even better I think. Paolo
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h index c6a749568dd6..b6b1bdafd08e 100644 --- a/arch/arm/include/asm/kvm_host.h +++ b/arch/arm/include/asm/kvm_host.h @@ -315,4 +315,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 1e0784ebbfd6..20990b22e593 100644 --- a/arch/arm/kvm/guest.c +++ b/arch/arm/kvm/guest.c @@ -41,6 +41,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 ab46bc70add6..51a64ff6965e 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -452,4 +452,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 959e50d2588c..4dd0549a41d3 100644 --- a/arch/arm64/kvm/guest.c +++ b/arch/arm64/kvm/guest.c @@ -46,6 +46,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 b58787daf9f8..f990fda1b2f6 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -1838,13 +1838,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 aafcc9881e88..26ab153a293f 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -9949,13 +9949,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 6930c63126c7..cf7b6a3a4197 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
The kvm struct is (currently) tens of kilo-bytes, which turns out to be a large amount of memory to allocate contiguously via kzalloc. Thus, this patch changes the kzalloc to a vzalloc, so that the memory allocation is less likely to fail in resource-constrained environments. Signed-off-by: Marc Orr <marcorr@google.com> --- 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(-)