aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLan Tianyu <tianyu.lan@intel.com>2016-03-12 22:10:28 -0500
committerPaolo Bonzini <pbonzini@redhat.com>2016-03-22 11:38:33 -0400
commit4ae3cb3a2551b41f22284f713e7d5e2b61a85c1d (patch)
tree153de5718a4688050cd3911a7442431a81620926
parent7bfdf2177812c30928bea3fc8bc86b9dea236f65 (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.c18
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
192void kvm_flush_remote_tlbs(struct kvm *kvm) 192void 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);