]> Git Repo - linux.git/commitdiff
KVM: arm64: Add fast path to handle permission relaxation during dirty logging
authorJing Zhang <[email protected]>
Tue, 18 Jan 2022 01:57:02 +0000 (01:57 +0000)
committerMarc Zyngier <[email protected]>
Tue, 8 Feb 2022 14:27:53 +0000 (14:27 +0000)
To reduce MMU lock contention during dirty logging, all permission
relaxation operations would be performed under read lock.

Signed-off-by: Jing Zhang <[email protected]>
Tested-by: Fuad Tabba <[email protected]>
Reviewed-by: Fuad Tabba <[email protected]>
Signed-off-by: Marc Zyngier <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
arch/arm64/kvm/mmu.c

index cafd5813c949612be24de169e637cf809c011db4..10df5d855d5449c28d6f496d32dde6d7eb8c647b 100644 (file)
@@ -1080,6 +1080,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
        gfn_t gfn;
        kvm_pfn_t pfn;
        bool logging_active = memslot_is_logging(memslot);
+       bool logging_perm_fault = false;
        unsigned long fault_level = kvm_vcpu_trap_get_fault_level(vcpu);
        unsigned long vma_pagesize, fault_granule;
        enum kvm_pgtable_prot prot = KVM_PGTABLE_PROT_R;
@@ -1114,6 +1115,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
        if (logging_active) {
                force_pte = true;
                vma_shift = PAGE_SHIFT;
+               logging_perm_fault = (fault_status == FSC_PERM && write_fault);
        } else {
                vma_shift = get_vma_page_shift(vma, hva);
        }
@@ -1212,7 +1214,15 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
        if (exec_fault && device)
                return -ENOEXEC;
 
-       write_lock(&kvm->mmu_lock);
+       /*
+        * To reduce MMU contentions and enhance concurrency during dirty
+        * logging dirty logging, only acquire read lock for permission
+        * relaxation.
+        */
+       if (logging_perm_fault)
+               read_lock(&kvm->mmu_lock);
+       else
+               write_lock(&kvm->mmu_lock);
        pgt = vcpu->arch.hw_mmu->pgt;
        if (mmu_notifier_retry(kvm, mmu_seq))
                goto out_unlock;
@@ -1271,7 +1281,10 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
        }
 
 out_unlock:
-       write_unlock(&kvm->mmu_lock);
+       if (logging_perm_fault)
+               read_unlock(&kvm->mmu_lock);
+       else
+               write_unlock(&kvm->mmu_lock);
        kvm_set_pfn_accessed(pfn);
        kvm_release_pfn_clean(pfn);
        return ret != -EAGAIN ? ret : 0;
This page took 0.061242 seconds and 4 git commands to generate.