Skip to content

Commit

Permalink
KVM: x86/mmu: Make TDP MMU root refcount atomic
Browse files Browse the repository at this point in the history
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: Ben Gardon <bgardon@google.com>
  • Loading branch information
Ben Gardon authored and intel-lab-lkp committed Mar 31, 2021
1 parent 124c869 commit 6bfd88c
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 14 deletions.
6 changes: 5 additions & 1 deletion arch/x86/kvm/mmu/mmu_internal.h
Expand Up @@ -50,7 +50,11 @@ struct kvm_mmu_page {
u64 *spt;
/* hold the gfn of each spte inside spt */
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;
struct kvm_rmap_head parent_ptes; /* rmap pointers to parent sptes */
DECLARE_BITMAP(unsync_child_bitmap, 512);
Expand Down
15 changes: 8 additions & 7 deletions arch/x86/kvm/mmu/tdp_mmu.c
Expand Up @@ -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);

if (--root->root_count)
if (!refcount_dec_and_test(&root->tdp_mmu_root_count))
return;

WARN_ON(!root->tdp_mmu_page);
Expand Down Expand Up @@ -88,10 +88,12 @@ static struct kvm_mmu_page *tdp_mmu_next_root(struct kvm *kvm,
next_root = list_first_entry(&kvm->arch.tdp_mmu_roots,
typeof(*next_root), link);

while (!list_entry_is_head(next_root, &kvm->arch.tdp_mmu_roots, link) &&
!kvm_tdp_mmu_get_root(kvm, next_root))
next_root = list_next_entry(next_root, link);

if (list_entry_is_head(next_root, &kvm->arch.tdp_mmu_roots, link))
next_root = NULL;
else
kvm_tdp_mmu_get_root(kvm, next_root);

if (prev_root)
kvm_tdp_mmu_put_root(kvm, prev_root);
Expand Down Expand Up @@ -158,14 +160,13 @@ hpa_t kvm_tdp_mmu_get_vcpu_root_hpa(struct kvm_vcpu *vcpu)

/* Check for an existing root before allocating a new one. */
for_each_tdp_mmu_root(kvm, root) {
if (root->role.word == role.word) {
kvm_tdp_mmu_get_root(kvm, root);
if (root->role.word == role.word &&
kvm_tdp_mmu_get_root(kvm, root))
goto out;
}
}

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);

Expand Down
9 changes: 3 additions & 6 deletions arch/x86/kvm/mmu/tdp_mmu.h
Expand Up @@ -7,13 +7,10 @@

hpa_t kvm_tdp_mmu_get_vcpu_root_hpa(struct kvm_vcpu *vcpu);

static inline void kvm_tdp_mmu_get_root(struct kvm *kvm,
struct kvm_mmu_page *root)
__must_check static inline bool kvm_tdp_mmu_get_root(struct kvm *kvm,
struct kvm_mmu_page *root)
{
BUG_ON(!root->root_count);
lockdep_assert_held(&kvm->mmu_lock);

++root->root_count;
return refcount_inc_not_zero(&root->tdp_mmu_root_count);
}

void kvm_tdp_mmu_put_root(struct kvm *kvm, struct kvm_mmu_page *root);
Expand Down

0 comments on commit 6bfd88c

Please sign in to comment.