Skip to content

Commit 187c883

Browse files
sean-jcbonzini
authored andcommitted
KVM: x86: Use rw_semaphore for APICv lock to allow vCPU parallelism
Use a rw_semaphore instead of a mutex to coordinate APICv updates so that vCPUs responding to requests can take the lock for read and run in parallel. Using a mutex forces serialization of vCPUs even though kvm_vcpu_update_apicv() only touches data local to that vCPU or is protected by a different lock, e.g. SVM's ir_list_lock. Signed-off-by: Sean Christopherson <[email protected]> Message-Id: <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]>
1 parent ee49a89 commit 187c883

File tree

3 files changed

+10
-8
lines changed

3 files changed

+10
-8
lines changed

arch/x86/include/asm/kvm_host.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1071,7 +1071,7 @@ struct kvm_arch {
10711071
atomic_t apic_map_dirty;
10721072

10731073
/* Protects apic_access_memslot_enabled and apicv_inhibit_reasons */
1074-
struct mutex apicv_update_lock;
1074+
struct rw_semaphore apicv_update_lock;
10751075

10761076
bool apic_access_memslot_enabled;
10771077
unsigned long apicv_inhibit_reasons;

arch/x86/kvm/hyperv.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ static void synic_update_vector(struct kvm_vcpu_hv_synic *synic,
112112
if (!!auto_eoi_old == !!auto_eoi_new)
113113
return;
114114

115-
mutex_lock(&vcpu->kvm->arch.apicv_update_lock);
115+
down_write(&vcpu->kvm->arch.apicv_update_lock);
116116

117117
if (auto_eoi_new)
118118
hv->synic_auto_eoi_used++;
@@ -123,7 +123,7 @@ static void synic_update_vector(struct kvm_vcpu_hv_synic *synic,
123123
!hv->synic_auto_eoi_used,
124124
APICV_INHIBIT_REASON_HYPERV);
125125

126-
mutex_unlock(&vcpu->kvm->arch.apicv_update_lock);
126+
up_write(&vcpu->kvm->arch.apicv_update_lock);
127127
}
128128

129129
static int synic_set_sint(struct kvm_vcpu_hv_synic *synic, int sint,

arch/x86/kvm/x86.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8778,7 +8778,7 @@ EXPORT_SYMBOL_GPL(kvm_apicv_activated);
87788778

87798779
static void kvm_apicv_init(struct kvm *kvm)
87808780
{
8781-
mutex_init(&kvm->arch.apicv_update_lock);
8781+
init_rwsem(&kvm->arch.apicv_update_lock);
87828782

87838783
if (enable_apicv)
87848784
clear_bit(APICV_INHIBIT_REASON_DISABLE,
@@ -9440,7 +9440,7 @@ void kvm_vcpu_update_apicv(struct kvm_vcpu *vcpu)
94409440
if (!lapic_in_kernel(vcpu))
94419441
return;
94429442

9443-
mutex_lock(&vcpu->kvm->arch.apicv_update_lock);
9443+
down_read(&vcpu->kvm->arch.apicv_update_lock);
94449444

94459445
activate = kvm_apicv_activated(vcpu->kvm);
94469446
if (vcpu->arch.apicv_active == activate)
@@ -9460,14 +9460,16 @@ void kvm_vcpu_update_apicv(struct kvm_vcpu *vcpu)
94609460
kvm_make_request(KVM_REQ_EVENT, vcpu);
94619461

94629462
out:
9463-
mutex_unlock(&vcpu->kvm->arch.apicv_update_lock);
9463+
up_read(&vcpu->kvm->arch.apicv_update_lock);
94649464
}
94659465
EXPORT_SYMBOL_GPL(kvm_vcpu_update_apicv);
94669466

94679467
void __kvm_request_apicv_update(struct kvm *kvm, bool activate, ulong bit)
94689468
{
94699469
unsigned long old, new;
94709470

9471+
lockdep_assert_held_write(&kvm->arch.apicv_update_lock);
9472+
94719473
if (!kvm_x86_ops.check_apicv_inhibit_reasons ||
94729474
!static_call(kvm_x86_check_apicv_inhibit_reasons)(bit))
94739475
return;
@@ -9506,9 +9508,9 @@ EXPORT_SYMBOL_GPL(__kvm_request_apicv_update);
95069508

95079509
void kvm_request_apicv_update(struct kvm *kvm, bool activate, ulong bit)
95089510
{
9509-
mutex_lock(&kvm->arch.apicv_update_lock);
9511+
down_write(&kvm->arch.apicv_update_lock);
95109512
__kvm_request_apicv_update(kvm, activate, bit);
9511-
mutex_unlock(&kvm->arch.apicv_update_lock);
9513+
up_write(&kvm->arch.apicv_update_lock);
95129514
}
95139515
EXPORT_SYMBOL_GPL(kvm_request_apicv_update);
95149516

0 commit comments

Comments
 (0)