diff options
author | Lan Tianyu <tianyu.lan@intel.com> | 2016-03-12 22:10:28 -0500 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2016-03-22 11:38:33 -0400 |
commit | 4ae3cb3a2551b41f22284f713e7d5e2b61a85c1d (patch) | |
tree | 153de5718a4688050cd3911a7442431a81620926 | |
parent | 7bfdf2177812c30928bea3fc8bc86b9dea236f65 (diff) |
KVM: Replace smp_mb() with smp_load_acquire() in the kvm_flush_remote_tlbs()
smp_load_acquire() is enough here and it's cheaper than smp_mb().
Adding a comment about reusing memory barrier of kvm_make_all_cpus_request()
here to keep order between modifications to the page tables and reading mode.
Signed-off-by: Lan Tianyu <tianyu.lan@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r-- | virt/kvm/kvm_main.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 402590dfcf9b..4fd482fb9260 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
@@ -191,9 +191,23 @@ bool kvm_make_all_cpus_request(struct kvm *kvm, unsigned int req) | |||
191 | #ifndef CONFIG_HAVE_KVM_ARCH_TLB_FLUSH_ALL | 191 | #ifndef CONFIG_HAVE_KVM_ARCH_TLB_FLUSH_ALL |
192 | void kvm_flush_remote_tlbs(struct kvm *kvm) | 192 | void kvm_flush_remote_tlbs(struct kvm *kvm) |
193 | { | 193 | { |
194 | long dirty_count = kvm->tlbs_dirty; | 194 | /* |
195 | * Read tlbs_dirty before setting KVM_REQ_TLB_FLUSH in | ||
196 | * kvm_make_all_cpus_request. | ||
197 | */ | ||
198 | long dirty_count = smp_load_acquire(&kvm->tlbs_dirty); | ||
195 | 199 | ||
196 | smp_mb(); | 200 | /* |
201 | * We want to publish modifications to the page tables before reading | ||
202 | * mode. Pairs with a memory barrier in arch-specific code. | ||
203 | * - x86: smp_mb__after_srcu_read_unlock in vcpu_enter_guest | ||
204 | * and smp_mb in walk_shadow_page_lockless_begin/end. | ||
205 | * - powerpc: smp_mb in kvmppc_prepare_to_enter. | ||
206 | * | ||
207 | * There is already an smp_mb__after_atomic() before | ||
208 | * kvm_make_all_cpus_request() reads vcpu->mode. We reuse that | ||
209 | * barrier here. | ||
210 | */ | ||
197 | if (kvm_make_all_cpus_request(kvm, KVM_REQ_TLB_FLUSH)) | 211 | if (kvm_make_all_cpus_request(kvm, KVM_REQ_TLB_FLUSH)) |
198 | ++kvm->stat.remote_tlb_flush; | 212 | ++kvm->stat.remote_tlb_flush; |
199 | cmpxchg(&kvm->tlbs_dirty, dirty_count, 0); | 213 | cmpxchg(&kvm->tlbs_dirty, dirty_count, 0); |