Commit 11cccf5c authored by Ben Gardon's avatar Ben Gardon Committed by Paolo Bonzini

KVM: x86/mmu: Make TDP MMU root refcount atomic

In order to parallelize more operations for the TDP MMU, make the
refcount on TDP MMU roots atomic, so that a future patch can allow
multiple threads to take a reference on the root concurrently, while
holding the MMU lock in read mode.
Signed-off-by: default avatarBen Gardon <bgardon@google.com>
Message-Id: <20210401233736.638171-7-bgardon@google.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent cfc10997
...@@ -50,7 +50,11 @@ struct kvm_mmu_page { ...@@ -50,7 +50,11 @@ struct kvm_mmu_page {
u64 *spt; u64 *spt;
/* hold the gfn of each spte inside spt */ /* hold the gfn of each spte inside spt */
gfn_t *gfns; gfn_t *gfns;
int root_count; /* Currently serving as active root */ /* Currently serving as active root */
union {
int root_count;
refcount_t tdp_mmu_root_count;
};
unsigned int unsync_children; unsigned int unsync_children;
struct kvm_rmap_head parent_ptes; /* rmap pointers to parent sptes */ struct kvm_rmap_head parent_ptes; /* rmap pointers to parent sptes */
DECLARE_BITMAP(unsync_child_bitmap, 512); DECLARE_BITMAP(unsync_child_bitmap, 512);
......
...@@ -56,7 +56,7 @@ void kvm_tdp_mmu_put_root(struct kvm *kvm, struct kvm_mmu_page *root) ...@@ -56,7 +56,7 @@ void kvm_tdp_mmu_put_root(struct kvm *kvm, struct kvm_mmu_page *root)
lockdep_assert_held_write(&kvm->mmu_lock); lockdep_assert_held_write(&kvm->mmu_lock);
if (--root->root_count) if (!refcount_dec_and_test(&root->tdp_mmu_root_count))
return; return;
WARN_ON(!root->tdp_mmu_page); WARN_ON(!root->tdp_mmu_page);
...@@ -168,7 +168,7 @@ hpa_t kvm_tdp_mmu_get_vcpu_root_hpa(struct kvm_vcpu *vcpu) ...@@ -168,7 +168,7 @@ hpa_t kvm_tdp_mmu_get_vcpu_root_hpa(struct kvm_vcpu *vcpu)
} }
root = alloc_tdp_mmu_page(vcpu, 0, vcpu->arch.mmu->shadow_root_level); root = alloc_tdp_mmu_page(vcpu, 0, vcpu->arch.mmu->shadow_root_level);
root->root_count = 1; refcount_set(&root->tdp_mmu_root_count, 1);
list_add(&root->link, &kvm->arch.tdp_mmu_roots); list_add(&root->link, &kvm->arch.tdp_mmu_roots);
......
...@@ -10,10 +10,14 @@ hpa_t kvm_tdp_mmu_get_vcpu_root_hpa(struct kvm_vcpu *vcpu); ...@@ -10,10 +10,14 @@ hpa_t kvm_tdp_mmu_get_vcpu_root_hpa(struct kvm_vcpu *vcpu);
static inline void kvm_tdp_mmu_get_root(struct kvm *kvm, static inline void kvm_tdp_mmu_get_root(struct kvm *kvm,
struct kvm_mmu_page *root) struct kvm_mmu_page *root)
{ {
BUG_ON(!root->root_count); lockdep_assert_held_write(&kvm->mmu_lock);
lockdep_assert_held(&kvm->mmu_lock);
++root->root_count; /*
* This should never fail since roots are removed from the roots
* list under the MMU write lock when their reference count falls
* to zero.
*/
refcount_inc_not_zero(&root->tdp_mmu_root_count);
} }
void kvm_tdp_mmu_put_root(struct kvm *kvm, struct kvm_mmu_page *root); void kvm_tdp_mmu_put_root(struct kvm *kvm, struct kvm_mmu_page *root);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment