Commit 3ee16c81 authored by Izik Eidus's avatar Izik Eidus Committed by Avi Kivity

KVM: MMU: allow the vm to shrink the kvm mmu shadow caches

Allow the Linux memory manager to reclaim memory in the kvm shadow cache.
Signed-off-by: default avatarIzik Eidus <izike@qumranet.com>
Signed-off-by: default avatarAvi Kivity <avi@qumranet.com>
parent 3200f405
...@@ -1966,7 +1966,53 @@ void kvm_mmu_zap_all(struct kvm *kvm) ...@@ -1966,7 +1966,53 @@ void kvm_mmu_zap_all(struct kvm *kvm)
kvm_flush_remote_tlbs(kvm); kvm_flush_remote_tlbs(kvm);
} }
void kvm_mmu_module_exit(void) void kvm_mmu_remove_one_alloc_mmu_page(struct kvm *kvm)
{
struct kvm_mmu_page *page;
page = container_of(kvm->arch.active_mmu_pages.prev,
struct kvm_mmu_page, link);
kvm_mmu_zap_page(kvm, page);
}
static int mmu_shrink(int nr_to_scan, gfp_t gfp_mask)
{
struct kvm *kvm;
struct kvm *kvm_freed = NULL;
int cache_count = 0;
spin_lock(&kvm_lock);
list_for_each_entry(kvm, &vm_list, vm_list) {
int npages;
spin_lock(&kvm->mmu_lock);
npages = kvm->arch.n_alloc_mmu_pages -
kvm->arch.n_free_mmu_pages;
cache_count += npages;
if (!kvm_freed && nr_to_scan > 0 && npages > 0) {
kvm_mmu_remove_one_alloc_mmu_page(kvm);
cache_count--;
kvm_freed = kvm;
}
nr_to_scan--;
spin_unlock(&kvm->mmu_lock);
}
if (kvm_freed)
list_move_tail(&kvm_freed->vm_list, &vm_list);
spin_unlock(&kvm_lock);
return cache_count;
}
static struct shrinker mmu_shrinker = {
.shrink = mmu_shrink,
.seeks = DEFAULT_SEEKS * 10,
};
void mmu_destroy_caches(void)
{ {
if (pte_chain_cache) if (pte_chain_cache)
kmem_cache_destroy(pte_chain_cache); kmem_cache_destroy(pte_chain_cache);
...@@ -1976,6 +2022,12 @@ void kvm_mmu_module_exit(void) ...@@ -1976,6 +2022,12 @@ void kvm_mmu_module_exit(void)
kmem_cache_destroy(mmu_page_header_cache); kmem_cache_destroy(mmu_page_header_cache);
} }
void kvm_mmu_module_exit(void)
{
mmu_destroy_caches();
unregister_shrinker(&mmu_shrinker);
}
int kvm_mmu_module_init(void) int kvm_mmu_module_init(void)
{ {
pte_chain_cache = kmem_cache_create("kvm_pte_chain", pte_chain_cache = kmem_cache_create("kvm_pte_chain",
...@@ -1995,10 +2047,12 @@ int kvm_mmu_module_init(void) ...@@ -1995,10 +2047,12 @@ int kvm_mmu_module_init(void)
if (!mmu_page_header_cache) if (!mmu_page_header_cache)
goto nomem; goto nomem;
register_shrinker(&mmu_shrinker);
return 0; return 0;
nomem: nomem:
kvm_mmu_module_exit(); mmu_destroy_caches();
return -ENOMEM; return -ENOMEM;
} }
......
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