Commit 3ad82a7e authored by Zhang Xiantao's avatar Zhang Xiantao Committed by Avi Kivity

KVM: Recalculate mmu pages needed for every memory region change

Instead of incrementally changing the mmu cache size for every memory slot
operation, recalculate it from scratch.  This is simpler and safer.
Signed-off-by: default avatarZhang Xiantao <xiantao.zhang@intel.com>
Signed-off-by: default avatarAvi Kivity <avi@qumranet.com>
parent 62266869
...@@ -333,26 +333,13 @@ int __kvm_set_memory_region(struct kvm *kvm, ...@@ -333,26 +333,13 @@ int __kvm_set_memory_region(struct kvm *kvm,
if (mem->slot >= kvm->nmemslots) if (mem->slot >= kvm->nmemslots)
kvm->nmemslots = mem->slot + 1; kvm->nmemslots = mem->slot + 1;
*memslot = new;
if (!kvm->n_requested_mmu_pages) { if (!kvm->n_requested_mmu_pages) {
unsigned int n_pages; unsigned int nr_mmu_pages = kvm_mmu_calculate_mmu_pages(kvm);
kvm_mmu_change_mmu_pages(kvm, nr_mmu_pages);
if (npages) {
n_pages = npages * KVM_PERMILLE_MMU_PAGES / 1000;
kvm_mmu_change_mmu_pages(kvm, kvm->n_alloc_mmu_pages +
n_pages);
} else {
unsigned int nr_mmu_pages;
n_pages = old.npages * KVM_PERMILLE_MMU_PAGES / 1000;
nr_mmu_pages = kvm->n_alloc_mmu_pages - n_pages;
nr_mmu_pages = max(nr_mmu_pages,
(unsigned int) KVM_MIN_ALLOC_MMU_PAGES);
kvm_mmu_change_mmu_pages(kvm, nr_mmu_pages);
}
} }
*memslot = new;
kvm_mmu_slot_remove_write_access(kvm, mem->slot); kvm_mmu_slot_remove_write_access(kvm, mem->slot);
kvm_flush_remote_tlbs(kvm); kvm_flush_remote_tlbs(kvm);
......
...@@ -1535,6 +1535,25 @@ nomem: ...@@ -1535,6 +1535,25 @@ nomem:
return -ENOMEM; return -ENOMEM;
} }
/*
* Caculate mmu pages needed for kvm.
*/
unsigned int kvm_mmu_calculate_mmu_pages(struct kvm *kvm)
{
int i;
unsigned int nr_mmu_pages;
unsigned int nr_pages = 0;
for (i = 0; i < kvm->nmemslots; i++)
nr_pages += kvm->memslots[i].npages;
nr_mmu_pages = nr_pages * KVM_PERMILLE_MMU_PAGES / 1000;
nr_mmu_pages = max(nr_mmu_pages,
(unsigned int) KVM_MIN_ALLOC_MMU_PAGES);
return nr_mmu_pages;
}
#ifdef AUDIT #ifdef AUDIT
static const char *audit_msg; static const char *audit_msg;
......
...@@ -236,6 +236,7 @@ void kvm_mmu_set_nonpresent_ptes(u64 trap_pte, u64 notrap_pte); ...@@ -236,6 +236,7 @@ void kvm_mmu_set_nonpresent_ptes(u64 trap_pte, u64 notrap_pte);
int kvm_mmu_reset_context(struct kvm_vcpu *vcpu); int kvm_mmu_reset_context(struct kvm_vcpu *vcpu);
void kvm_mmu_slot_remove_write_access(struct kvm *kvm, int slot); void kvm_mmu_slot_remove_write_access(struct kvm *kvm, int slot);
void kvm_mmu_zap_all(struct kvm *kvm); void kvm_mmu_zap_all(struct kvm *kvm);
unsigned int kvm_mmu_calculate_mmu_pages(struct kvm *kvm);
void kvm_mmu_change_mmu_pages(struct kvm *kvm, unsigned int kvm_nr_mmu_pages); void kvm_mmu_change_mmu_pages(struct kvm *kvm, unsigned int kvm_nr_mmu_pages);
enum emulation_result { enum emulation_result {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment