aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAvi Kivity <avi@qumranet.com>2007-04-15 09:31:09 -0400
committerAvi Kivity <avi@qumranet.com>2007-05-03 03:52:29 -0400
commitb5a33a75720c03d58d8281a72b45ffd214f00ed7 (patch)
tree7451b196f292eb96caf5173ad3c6459ab9efb1d7
parent417726a3fbecb2092f1054bbaee87bc442b05ef3 (diff)
KVM: Use slab caches to allocate mmu data structures
Better leak detection, statistics, memory use, speed -- goodness all around. Signed-off-by: Avi Kivity <avi@qumranet.com>
-rw-r--r--drivers/kvm/kvm.h3
-rw-r--r--drivers/kvm/kvm_main.c7
-rw-r--r--drivers/kvm/mmu.c39
3 files changed, 45 insertions, 4 deletions
diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index fceeb840a255..b9c318a9e334 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -433,6 +433,9 @@ extern struct kvm_arch_ops *kvm_arch_ops;
433int kvm_init_arch(struct kvm_arch_ops *ops, struct module *module); 433int kvm_init_arch(struct kvm_arch_ops *ops, struct module *module);
434void kvm_exit_arch(void); 434void kvm_exit_arch(void);
435 435
436int kvm_mmu_module_init(void);
437void kvm_mmu_module_exit(void);
438
436void kvm_mmu_destroy(struct kvm_vcpu *vcpu); 439void kvm_mmu_destroy(struct kvm_vcpu *vcpu);
437int kvm_mmu_create(struct kvm_vcpu *vcpu); 440int kvm_mmu_create(struct kvm_vcpu *vcpu);
438int kvm_mmu_setup(struct kvm_vcpu *vcpu); 441int kvm_mmu_setup(struct kvm_vcpu *vcpu);
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 0b30631585bd..ab4dbd7fa5f8 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -3063,6 +3063,10 @@ static __init int kvm_init(void)
3063 static struct page *bad_page; 3063 static struct page *bad_page;
3064 int r; 3064 int r;
3065 3065
3066 r = kvm_mmu_module_init();
3067 if (r)
3068 goto out4;
3069
3066 r = register_filesystem(&kvm_fs_type); 3070 r = register_filesystem(&kvm_fs_type);
3067 if (r) 3071 if (r)
3068 goto out3; 3072 goto out3;
@@ -3091,6 +3095,8 @@ out:
3091out2: 3095out2:
3092 unregister_filesystem(&kvm_fs_type); 3096 unregister_filesystem(&kvm_fs_type);
3093out3: 3097out3:
3098 kvm_mmu_module_exit();
3099out4:
3094 return r; 3100 return r;
3095} 3101}
3096 3102
@@ -3100,6 +3106,7 @@ static __exit void kvm_exit(void)
3100 __free_page(pfn_to_page(bad_page_address >> PAGE_SHIFT)); 3106 __free_page(pfn_to_page(bad_page_address >> PAGE_SHIFT));
3101 mntput(kvmfs_mnt); 3107 mntput(kvmfs_mnt);
3102 unregister_filesystem(&kvm_fs_type); 3108 unregister_filesystem(&kvm_fs_type);
3109 kvm_mmu_module_exit();
3103} 3110}
3104 3111
3105module_init(kvm_init) 3112module_init(kvm_init)
diff --git a/drivers/kvm/mmu.c b/drivers/kvm/mmu.c
index 9ff74805c7d1..a368ea8297f3 100644
--- a/drivers/kvm/mmu.c
+++ b/drivers/kvm/mmu.c
@@ -159,6 +159,9 @@ struct kvm_rmap_desc {
159 struct kvm_rmap_desc *more; 159 struct kvm_rmap_desc *more;
160}; 160};
161 161
162static struct kmem_cache *pte_chain_cache;
163static struct kmem_cache *rmap_desc_cache;
164
162static int is_write_protection(struct kvm_vcpu *vcpu) 165static int is_write_protection(struct kvm_vcpu *vcpu)
163{ 166{
164 return vcpu->cr0 & CR0_WP_MASK; 167 return vcpu->cr0 & CR0_WP_MASK;
@@ -196,14 +199,14 @@ static int is_rmap_pte(u64 pte)
196} 199}
197 200
198static int mmu_topup_memory_cache(struct kvm_mmu_memory_cache *cache, 201static int mmu_topup_memory_cache(struct kvm_mmu_memory_cache *cache,
199 size_t objsize, int min) 202 struct kmem_cache *base_cache, int min)
200{ 203{
201 void *obj; 204 void *obj;
202 205
203 if (cache->nobjs >= min) 206 if (cache->nobjs >= min)
204 return 0; 207 return 0;
205 while (cache->nobjs < ARRAY_SIZE(cache->objects)) { 208 while (cache->nobjs < ARRAY_SIZE(cache->objects)) {
206 obj = kzalloc(objsize, GFP_NOWAIT); 209 obj = kmem_cache_zalloc(base_cache, GFP_NOWAIT);
207 if (!obj) 210 if (!obj)
208 return -ENOMEM; 211 return -ENOMEM;
209 cache->objects[cache->nobjs++] = obj; 212 cache->objects[cache->nobjs++] = obj;
@@ -222,11 +225,11 @@ static int mmu_topup_memory_caches(struct kvm_vcpu *vcpu)
222 int r; 225 int r;
223 226
224 r = mmu_topup_memory_cache(&vcpu->mmu_pte_chain_cache, 227 r = mmu_topup_memory_cache(&vcpu->mmu_pte_chain_cache,
225 sizeof(struct kvm_pte_chain), 4); 228 pte_chain_cache, 4);
226 if (r) 229 if (r)
227 goto out; 230 goto out;
228 r = mmu_topup_memory_cache(&vcpu->mmu_rmap_desc_cache, 231 r = mmu_topup_memory_cache(&vcpu->mmu_rmap_desc_cache,
229 sizeof(struct kvm_rmap_desc), 1); 232 rmap_desc_cache, 1);
230out: 233out:
231 return r; 234 return r;
232} 235}
@@ -1333,6 +1336,34 @@ void kvm_mmu_zap_all(struct kvm_vcpu *vcpu)
1333 init_kvm_mmu(vcpu); 1336 init_kvm_mmu(vcpu);
1334} 1337}
1335 1338
1339void kvm_mmu_module_exit(void)
1340{
1341 if (pte_chain_cache)
1342 kmem_cache_destroy(pte_chain_cache);
1343 if (rmap_desc_cache)
1344 kmem_cache_destroy(rmap_desc_cache);
1345}
1346
1347int kvm_mmu_module_init(void)
1348{
1349 pte_chain_cache = kmem_cache_create("kvm_pte_chain",
1350 sizeof(struct kvm_pte_chain),
1351 0, 0, NULL, NULL);
1352 if (!pte_chain_cache)
1353 goto nomem;
1354 rmap_desc_cache = kmem_cache_create("kvm_rmap_desc",
1355 sizeof(struct kvm_rmap_desc),
1356 0, 0, NULL, NULL);
1357 if (!rmap_desc_cache)
1358 goto nomem;
1359
1360 return 0;
1361
1362nomem:
1363 kvm_mmu_module_exit();
1364 return -ENOMEM;
1365}
1366
1336#ifdef AUDIT 1367#ifdef AUDIT
1337 1368
1338static const char *audit_msg; 1369static const char *audit_msg;