The underlying implementation of radix_tree is xarray since v4.20. Changing to the xarray API directly relaxes some of the locking obligations and provides more symmetry with the next vsie changes in the series. Signed-off-by: Christoph Schlameuss --- arch/s390/include/asm/kvm_host.h | 2 +- arch/s390/kvm/vsie.c | 39 ++++++++++++++++----------------------- 2 files changed, 17 insertions(+), 24 deletions(-) diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h index d0b0dd9e4f10..2ae8fa51bf51 100644 --- a/arch/s390/include/asm/kvm_host.h +++ b/arch/s390/include/asm/kvm_host.h @@ -630,7 +630,7 @@ struct vsie_page; struct kvm_s390_vsie { struct mutex mutex; - struct radix_tree_root addr_to_page; + struct xarray addr_to_page; int page_count; int next; struct vsie_page *pages[KVM_MAX_VCPUS]; diff --git a/arch/s390/kvm/vsie.c b/arch/s390/kvm/vsie.c index 805d28f0e705..569054552b83 100644 --- a/arch/s390/kvm/vsie.c +++ b/arch/s390/kvm/vsie.c @@ -59,8 +59,7 @@ struct vsie_page { gpa_t sdnx_gpa; /* 0x0250 */ /* * guest address of the original SCB. Remains set for free vsie - * pages, so we can properly look them up in our addr_to_page - * radix tree. + * pages, so we can properly look them up in our addr_to_page map. */ gpa_t scb_gpa; /* 0x0258 */ /* the shadow gmap in use by the vsie_page */ @@ -1533,19 +1532,15 @@ static struct vsie_page *get_vsie_page(struct kvm *kvm, unsigned long addr) struct vsie_page *vsie_page; int nr_vcpus; - rcu_read_lock(); - vsie_page = radix_tree_lookup(&kvm->arch.vsie.addr_to_page, addr >> 9); - rcu_read_unlock(); - if (vsie_page) { - if (try_get_vsie_page(vsie_page)) { - if (vsie_page->scb_gpa == addr) - return vsie_page; - /* - * We raced with someone reusing + putting this vsie - * page before we grabbed it. - */ - put_vsie_page(vsie_page); - } + vsie_page = xa_load(&kvm->arch.vsie.addr_to_page, addr >> 9); + if (vsie_page && try_get_vsie_page(vsie_page)) { + if (vsie_page->scb_gpa == addr) + return vsie_page; + /* + * We raced with someone reusing + putting this vsie + * page before we grabbed it. + */ + put_vsie_page(vsie_page); } /* @@ -1574,14 +1569,15 @@ static struct vsie_page *get_vsie_page(struct kvm *kvm, unsigned long addr) kvm->arch.vsie.next %= nr_vcpus; } if (vsie_page->scb_gpa != ULONG_MAX) - radix_tree_delete(&kvm->arch.vsie.addr_to_page, - vsie_page->scb_gpa >> 9); + xa_erase(&kvm->arch.vsie.addr_to_page, + vsie_page->scb_gpa >> 9); /* Mark it as invalid until it resides in the tree. */ vsie_page->scb_gpa = ULONG_MAX; } /* Double use of the same address or allocation failure. */ - if (radix_tree_insert(&kvm->arch.vsie.addr_to_page, addr >> 9, vsie_page)) { + if (xa_insert(&kvm->arch.vsie.addr_to_page, addr >> 9, vsie_page, + GFP_KERNEL_ACCOUNT)) { put_vsie_page(vsie_page); mutex_unlock(&kvm->arch.vsie.mutex); return NULL; @@ -1661,7 +1657,7 @@ int kvm_s390_handle_vsie(struct kvm_vcpu *vcpu) void kvm_s390_vsie_init(struct kvm *kvm) { mutex_init(&kvm->arch.vsie.mutex); - INIT_RADIX_TREE(&kvm->arch.vsie.addr_to_page, GFP_KERNEL_ACCOUNT); + xa_init_flags(&kvm->arch.vsie.addr_to_page, XA_FLAGS_ACCOUNT); } /* Destroy the vsie data structures. To be called when a vm is destroyed. */ @@ -1677,12 +1673,9 @@ void kvm_s390_vsie_destroy(struct kvm *kvm) if (vsie_page->gmap_cache.gmap) release_gmap_shadow(vsie_page); kvm->arch.vsie.pages[i] = NULL; - /* free the radix tree entry */ - if (vsie_page->scb_gpa != ULONG_MAX) - radix_tree_delete(&kvm->arch.vsie.addr_to_page, - vsie_page->scb_gpa >> 9); free_vsie_page(vsie_page); } + xa_destroy(&kvm->arch.vsie.addr_to_page); kvm->arch.vsie.page_count = 0; mutex_unlock(&kvm->arch.vsie.mutex); } -- 2.55.0