diff options
| author | Xiao Guangrong <xiaoguangrong@cn.fujitsu.com> | 2010-11-22 22:13:00 -0500 |
|---|---|---|
| committer | Avi Kivity <avi@redhat.com> | 2011-01-12 04:29:51 -0500 |
| commit | a4ee1ca4a36e7857d90ae8c2b85f1bde9a042c10 (patch) | |
| tree | 29707dd004ef14df318ac35321b95ac62570fc99 /virt | |
| parent | 407c61c6bd6a51b56d02f8bbad8aadf19db8c7b5 (diff) | |
KVM: MMU: delay flush all tlbs on sync_page path
Quote from Avi:
| I don't think we need to flush immediately; set a "tlb dirty" bit somewhere
| that is cleareded when we flush the tlb. kvm_mmu_notifier_invalidate_page()
| can consult the bit and force a flush if set.
Signed-off-by: Xiao Guangrong <xiaoguangrong@cn.fujitsu.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'virt')
| -rw-r--r-- | virt/kvm/kvm_main.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 5156d458a84d..ee99b77e4451 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
| @@ -168,8 +168,12 @@ static bool make_all_cpus_request(struct kvm *kvm, unsigned int req) | |||
| 168 | 168 | ||
| 169 | void kvm_flush_remote_tlbs(struct kvm *kvm) | 169 | void kvm_flush_remote_tlbs(struct kvm *kvm) |
| 170 | { | 170 | { |
| 171 | int dirty_count = kvm->tlbs_dirty; | ||
| 172 | |||
| 173 | smp_mb(); | ||
| 171 | if (make_all_cpus_request(kvm, KVM_REQ_TLB_FLUSH)) | 174 | if (make_all_cpus_request(kvm, KVM_REQ_TLB_FLUSH)) |
| 172 | ++kvm->stat.remote_tlb_flush; | 175 | ++kvm->stat.remote_tlb_flush; |
| 176 | cmpxchg(&kvm->tlbs_dirty, dirty_count, 0); | ||
| 173 | } | 177 | } |
| 174 | 178 | ||
| 175 | void kvm_reload_remote_mmus(struct kvm *kvm) | 179 | void kvm_reload_remote_mmus(struct kvm *kvm) |
| @@ -249,7 +253,7 @@ static void kvm_mmu_notifier_invalidate_page(struct mmu_notifier *mn, | |||
| 249 | idx = srcu_read_lock(&kvm->srcu); | 253 | idx = srcu_read_lock(&kvm->srcu); |
| 250 | spin_lock(&kvm->mmu_lock); | 254 | spin_lock(&kvm->mmu_lock); |
| 251 | kvm->mmu_notifier_seq++; | 255 | kvm->mmu_notifier_seq++; |
| 252 | need_tlb_flush = kvm_unmap_hva(kvm, address); | 256 | need_tlb_flush = kvm_unmap_hva(kvm, address) | kvm->tlbs_dirty; |
| 253 | spin_unlock(&kvm->mmu_lock); | 257 | spin_unlock(&kvm->mmu_lock); |
| 254 | srcu_read_unlock(&kvm->srcu, idx); | 258 | srcu_read_unlock(&kvm->srcu, idx); |
| 255 | 259 | ||
| @@ -293,6 +297,7 @@ static void kvm_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn, | |||
| 293 | kvm->mmu_notifier_count++; | 297 | kvm->mmu_notifier_count++; |
| 294 | for (; start < end; start += PAGE_SIZE) | 298 | for (; start < end; start += PAGE_SIZE) |
| 295 | need_tlb_flush |= kvm_unmap_hva(kvm, start); | 299 | need_tlb_flush |= kvm_unmap_hva(kvm, start); |
| 300 | need_tlb_flush |= kvm->tlbs_dirty; | ||
| 296 | spin_unlock(&kvm->mmu_lock); | 301 | spin_unlock(&kvm->mmu_lock); |
| 297 | srcu_read_unlock(&kvm->srcu, idx); | 302 | srcu_read_unlock(&kvm->srcu, idx); |
| 298 | 303 | ||
