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: Izik Eidus <izike@qumranet.com> Signed-off-by: Avi Kivity <avi@qumranet.com>
This commit is contained in:
parent
3200f405a1
commit
3ee16c8145
|
@ -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)
|
||||||
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)
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue