Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1292051
  • 博文数量: 494
  • 博客积分: 161
  • 博客等级: 入伍新兵
  • 技术积分: 5084
  • 用 户 组: 普通用户
  • 注册时间: 2011-07-01 07:37
个人简介

只有偏执狂才能生存

文章分类

全部博文(494)

文章存档

2016年(10)

2015年(112)

2014年(69)

2013年(275)

2012年(28)

分类: LINUX

2013-06-20 16:46:08

影子页表页管理-----分配和回收

影子页表页分配
static struct kvm_mmu_page *kvm_mmu_alloc_page(struct kvm_vcpu *vcpu,
                                               u64 *parent_pte)
{
        struct kvm_mmu_page *sp;
        sp = mmu_memory_cache_alloc(&vcpu->arch.mmu_page_header_cache, sizeof *sp);//分配影子页表数据结构
        sp->spt = mmu_memory_cache_alloc(&vcpu->arch.mmu_page_cache, PAGE_SIZE); //分配的内存页
     sp->gfns = mmu_memory_cache_alloc(&vcpu->arch.mmu_page_cache, PAGE_SIZE);
        set_page_private(virt_to_page(sp->spt), (unsigned long)sp);//内存页的用途为影子页表,其实就是两者统一起来
        list_add(&sp->link, &vcpu->kvm->arch.active_mmu_pages); //分配页连接起来形成链表
          --vcpu->kvm->arch.n_free_mmu_pages;//空闲页数量减少
        return sp;
}
影子页表分配会创建一个缓存池,这样可以一次多分配内存。下面创建缓存池为ARRAY_SIZE为40,这样可以减少每次需要内存,每次分配内存带来时间损耗。影子页表分配应该是一个频繁过程。
参数
    min:8
如果缓存池内存页小于8的话,需要补充满,达到40页。
static int mmu_topup_memory_cache_page(struct kvm_mmu_memory_cache *cache,
                                       int min)
{       
        struct page *page;
        
        if (cache->nobjs >= min)    //如果
                return 0;
        while (cache->nobjs < ARRAY_SIZE(cache->objects)) {
                page = alloc_page(GFP_KERNEL);
                if (!page)
                        return -ENOMEM;
                set_page_private(page, 0);
                cache->objects[cache->nobjs++] = page_address(page);
        }
        return 0;
}

影子页表页回收
static void kvm_mmu_free_page(struct kvm *kvm, struct kvm_mmu_page *sp)
{
        ASSERT(is_empty_shadow_page(sp->spt));
        list_del(&sp->link);
        __free_page(virt_to_page(sp->spt));
        __free_page(virt_to_page(sp->gfns));
        kfree(sp);
        ++kvm->arch.n_free_mmu_pages;//空闲页数量增加
}

什么情况下,回收影子页表页呢?
该函数在什么情况下调用呢,一般在影子页表故障情况下,如果影子页表页不存在,需要分配影子页表页内存。分配内存前应该调用该函数,补充内存。
#define KVM_REFILL_PAGES 25
当空闲页小于25个时候,开始回收影子页表页。kvm_mmu_zap_page函数会调用kvm_mmu_free_page释放。
void __kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu)
{
        while (vcpu->kvm->arch.n_free_mmu_pages < KVM_REFILL_PAGES &&
               !list_empty(&vcpu->kvm->arch.active_mmu_pages)) {
                struct kvm_mmu_page *sp;

                sp = container_of(vcpu->kvm->arch.active_mmu_pages.prev,
                                  struct kvm_mmu_page, link); 
                kvm_mmu_zap_page(vcpu->kvm, sp);
                ++vcpu->kvm->stat.mmu_recycled;
        }
}

阅读(949) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~
评论热议
请登录后评论。

登录 注册