Message ID | 20190607114914.13357-1-khorenko@virtuozzo.com |
---|---|
State | New |
Series | "Series without cover letter" |
Headers | show |
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 0c3ded90dd38..18c7f63fcccd 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -5383,7 +5383,12 @@ mmu_shrink_scan(struct shrinker *shrink, struct shrink_control *sc) !kvm_has_zapped_obsolete_pages(kvm)) continue; - kvm_get_kvm(kvm); + /* + * If try_get fails, we race with last kvm_put_kvm(), + * so skip the VM, it will die soon anyway. + */ + if (!kvm_try_get_kvm(kvm)) + continue; spin_unlock(&kvm_lock); idx = srcu_read_lock(&kvm->srcu); diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index ff50020dc91f..f0d028e6f9fb 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -542,6 +542,7 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align, void kvm_exit(void); void kvm_get_kvm(struct kvm *kvm); +int kvm_try_get_kvm(struct kvm *kvm); void kvm_put_kvm(struct kvm *kvm); static inline struct kvm_memslots *__kvm_memslots(struct kvm *kvm, int as_id) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index ccab89847623..b8b0146f7c8b 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -733,6 +733,12 @@ void kvm_get_kvm(struct kvm *kvm) } EXPORT_SYMBOL_GPL(kvm_get_kvm); +int kvm_try_get_kvm(struct kvm *kvm) +{ + return atomic_inc_not_zero(&kvm->users_count); +} +EXPORT_SYMBOL_GPL(kvm_try_get_kvm); + void kvm_put_kvm(struct kvm *kvm) { if (atomic_dec_and_test(&kvm->users_count))
On 07.06.2019 14:49, Konstantin Khorenko wrote: > Honor the race between VM memory shrink and VM destroy, > just skip dying VMs, shrink alive ones. > > Fixes: 05a623470d4b ("kvm: move actual VM memory shrink out of kvm_lock") > https://jira.sw.ru/browse/PSBM-95077 > > Reported-by: Kirill Tkhai <ktkhai@virtuozzo.com> > Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com> Reviewed-by: Kirill Tkhai <ktkhai@virtuozzo.com> > --- > arch/x86/kvm/mmu.c | 7 ++++++- > include/linux/kvm_host.h | 1 + > virt/kvm/kvm_main.c | 6 ++++++ > 3 files changed, 13 insertions(+), 1 deletion(-) > > diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c > index 0c3ded90dd38..18c7f63fcccd 100644 > --- a/arch/x86/kvm/mmu.c > +++ b/arch/x86/kvm/mmu.c > @@ -5383,7 +5383,12 @@ mmu_shrink_scan(struct shrinker *shrink, struct shrink_control *sc) > !kvm_has_zapped_obsolete_pages(kvm)) > continue; > > - kvm_get_kvm(kvm); > + /* > + * If try_get fails, we race with last kvm_put_kvm(), > + * so skip the VM, it will die soon anyway. > + */ > + if (!kvm_try_get_kvm(kvm)) > + continue; > spin_unlock(&kvm_lock); > > idx = srcu_read_lock(&kvm->srcu); > diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h > index ff50020dc91f..f0d028e6f9fb 100644 > --- a/include/linux/kvm_host.h > +++ b/include/linux/kvm_host.h > @@ -542,6 +542,7 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align, > void kvm_exit(void); > > void kvm_get_kvm(struct kvm *kvm); > +int kvm_try_get_kvm(struct kvm *kvm); > void kvm_put_kvm(struct kvm *kvm); > > static inline struct kvm_memslots *__kvm_memslots(struct kvm *kvm, int as_id) > diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c > index ccab89847623..b8b0146f7c8b 100644 > --- a/virt/kvm/kvm_main.c > +++ b/virt/kvm/kvm_main.c > @@ -733,6 +733,12 @@ void kvm_get_kvm(struct kvm *kvm) > } > EXPORT_SYMBOL_GPL(kvm_get_kvm); > > +int kvm_try_get_kvm(struct kvm *kvm) > +{ > + return atomic_inc_not_zero(&kvm->users_count); > +} > +EXPORT_SYMBOL_GPL(kvm_try_get_kvm); > + > void kvm_put_kvm(struct kvm *kvm) > { > if (atomic_dec_and_test(&kvm->users_count)) >
Honor the race between VM memory shrink and VM destroy, just skip dying VMs, shrink alive ones. Fixes: 05a623470d4b ("kvm: move actual VM memory shrink out of kvm_lock") https://jira.sw.ru/browse/PSBM-95077 Reported-by: Kirill Tkhai <ktkhai@virtuozzo.com> Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com> --- arch/x86/kvm/mmu.c | 7 ++++++- include/linux/kvm_host.h | 1 + virt/kvm/kvm_main.c | 6 ++++++ 3 files changed, 13 insertions(+), 1 deletion(-)