[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <99a961d2-d46c-ead9-1138-45f6587a60ed@maciej.szmigiero.name>
Date: Tue, 1 Jun 2021 22:25:19 +0200
From: "Maciej S. Szmigiero" <mail@...iej.szmigiero.name>
To: Sean Christopherson <seanjc@...gle.com>
Cc: Paolo Bonzini <pbonzini@...hat.com>,
Vitaly Kuznetsov <vkuznets@...hat.com>,
Wanpeng Li <wanpengli@...cent.com>,
Jim Mattson <jmattson@...gle.com>,
Igor Mammedov <imammedo@...hat.com>,
Marc Zyngier <maz@...nel.org>,
James Morse <james.morse@....com>,
Julien Thierry <julien.thierry.kdev@...il.com>,
Suzuki K Poulose <suzuki.poulose@....com>,
Huacai Chen <chenhuacai@...nel.org>,
Aleksandar Markovic <aleksandar.qemu.devel@...il.com>,
Paul Mackerras <paulus@...abs.org>,
Christian Borntraeger <borntraeger@...ibm.com>,
Janosch Frank <frankja@...ux.ibm.com>,
David Hildenbrand <david@...hat.com>,
Cornelia Huck <cohuck@...hat.com>,
Claudio Imbrenda <imbrenda@...ux.ibm.com>,
Joerg Roedel <joro@...tes.org>, kvm@...r.kernel.org,
linux-kernel@...r.kernel.org
Subject: Re: [PATCH v3 7/8] KVM: Optimize gfn lookup in kvm_zap_gfn_range()
On 26.05.2021 19:33, Sean Christopherson wrote:
> On Sun, May 16, 2021, Maciej S. Szmigiero wrote:
>> From: "Maciej S. Szmigiero" <maciej.szmigiero@...cle.com>
>>
>> Introduce a memslots gfn upper bound operation and use it to optimize
>> kvm_zap_gfn_range().
>> This way this handler can do a quick lookup for intersecting gfns and won't
>> have to do a linear scan of the whole memslot set.
>>
>> Signed-off-by: Maciej S. Szmigiero <maciej.szmigiero@...cle.com>
>> ---
>> arch/x86/kvm/mmu/mmu.c | 41 ++++++++++++++++++++++++++++++++++++++--
>> include/linux/kvm_host.h | 22 +++++++++++++++++++++
>> 2 files changed, 61 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
>> index 7222b552d139..f23398cf0316 100644
>> --- a/arch/x86/kvm/mmu/mmu.c
>> +++ b/arch/x86/kvm/mmu/mmu.c
>> @@ -5490,14 +5490,51 @@ void kvm_zap_gfn_range(struct kvm *kvm, gfn_t gfn_start, gfn_t gfn_end)
>> int i;
>> bool flush = false;
>>
>> + if (gfn_end == gfn_start || WARN_ON(gfn_end < gfn_start))
>> + return;
>> +
>> write_lock(&kvm->mmu_lock);
>> for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++) {
>> - int ctr;
>> + int idxactive;
>> + struct rb_node *node;
>>
>> slots = __kvm_memslots(kvm, i);
>> - kvm_for_each_memslot(memslot, ctr, slots) {
>> + idxactive = kvm_memslots_idx(slots);
>> +
>> + /*
>> + * Find the slot with the lowest gfn that can possibly intersect with
>> + * the range, so we'll ideally have slot start <= range start
>> + */
>> + node = kvm_memslots_gfn_upper_bound(slots, gfn_start);
>> + if (node) {
>> + struct rb_node *pnode;
>> +
>> + /*
>> + * A NULL previous node means that the very first slot
>> + * already has a higher start gfn.
>> + * In this case slot start > range start.
>> + */
>> + pnode = rb_prev(node);
>> + if (pnode)
>> + node = pnode;
>> + } else {
>> + /* a NULL node below means no slots */
>> + node = rb_last(&slots->gfn_tree);
>> + }
>> +
>> + for ( ; node; node = rb_next(node)) {
>> gfn_t start, end;
>
> Can this be abstracted into something like:
>
> kvm_for_each_memslot_in_gfn_range(...) {
>
> }
>
> and share that implementation with kvm_check_memslot_overlap() in the next patch?
>
> I really don't think arch code should be poking into gfn_tree, and ideally arch
> code wouldn't even be aware that gfn_tree exists.
That's a good idea, will do.
Thanks,
Maciej
Powered by blists - more mailing lists