Avi Kivity wrote: > Izik Eidus wrote: >> void kvm_mmu_module_exit(void) >> { >> if (pte_chain_cache) >> @@ -1980,6 +2026,7 @@ void kvm_mmu_module_exit(void) >> kmem_cache_destroy(rmap_desc_cache); >> if (mmu_page_header_cache) >> kmem_cache_destroy(mmu_page_header_cache); >> + unregister_shrinker(&mmu_shrinker); >> } >> > > kvm_mmu_module_exit() can be called from the nomem: label below, so the > shrinker will be unregistered despite not being registered. > > Suggest renaming kvm_mmu_module_exit() to mmu_destroy_caches(), and > adding a new kvm_mmu_module_exit() which will call mmu_destroy_caches() > and unregister_shrinker(). > >> >> int kvm_mmu_module_init(void) >> @@ -2001,6 +2048,8 @@ int kvm_mmu_module_init(void) >> if (!mmu_page_header_cache) >> goto nomem; >> >> + register_shrinker(&mmu_shrinker); >> + >> return 0; >> >> nomem: >> > >
ok, this should address all the issues. >From a4cd289ab2502172bde994612636f84bec5e7a60 Mon Sep 17 00:00:00 2001 From: Izik Eidus <[EMAIL PROTECTED]> Date: Sun, 30 Mar 2008 15:13:47 +0300 Subject: [PATCH] KVM: register the kvm mmu cache with the shrinker. Signed-off-by: Izik Eidus <[EMAIL PROTECTED]> --- arch/x86/kvm/mmu.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 56 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index a0be4f5..8a6a4f9 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -1963,7 +1963,53 @@ void kvm_mmu_zap_all(struct kvm *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) kmem_cache_destroy(pte_chain_cache); @@ -1973,6 +2019,12 @@ void kvm_mmu_module_exit(void) 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) { pte_chain_cache = kmem_cache_create("kvm_pte_chain", @@ -1992,10 +2044,12 @@ int kvm_mmu_module_init(void) if (!mmu_page_header_cache) goto nomem; + register_shrinker(&mmu_shrinker); + return 0; nomem: - kvm_mmu_module_exit(); + mmu_destroy_caches(); return -ENOMEM; } -- 1.5.3.6 -- woof. ------------------------------------------------------------------------- Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace _______________________________________________ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel