darling54454 发表于 2016-03-18 21:40

vmalloc区域释放的页表如何处理?

内核版本:linux 2.6.30

struct vm_struct *remove_vm_area(const void *addr)
{
        struct vmap_area *va;

        va = find_vmap_area((unsigned long)addr);
        if (va && va->flags & VM_VM_AREA) {
                struct vm_struct *vm = va->private;
                struct vm_struct *tmp, **p;

                vmap_debug_free_range(va->va_start, va->va_end);
                free_unmap_vmap_area(va);
                vm->size -= PAGE_SIZE;

                write_lock(&vmlist_lock);
                for (p = &vmlist; (tmp = *p) != vm; p = &tmp->next)
                        ;
                *p = tmp->next;
                write_unlock(&vmlist_lock);

                return vm;
        }
        return NULL;
}
static void free_unmap_vmap_area(struct vmap_area *va)
{
        flush_cache_vunmap(va->va_start, va->va_end);
        free_unmap_vmap_area_noflush(va);
}
static void free_unmap_vmap_area_noflush(struct vmap_area *va)
{
        va->flags |= VM_LAZY_FREE;
        atomic_add((va->va_end - va->va_start) >> PAGE_SHIFT, &vmap_lazy_nr);
        if (unlikely(atomic_read(&vmap_lazy_nr) > lazy_max_pages()))
                try_purge_vmap_area_lazy();
}
可以看到,它还先把当前要释放的pte表项的数目添加到全局变量vmap_lazy_nr,然后在判断是不是超过lazy_max_pages()来确定是不是释放掉页表项。
那如果没有超过,而且是unlikely的。。那如果再次访问该区域是不是还会继续操作原本映射的内存呢?
在后面虽然是有把vmalloc映射的内存也释放掉,但是应该和MMU的映射没有什么关系吧。
反正它能够最终把虚拟地址映射到一个物理内存上。

nswcfd 发表于 2016-03-21 16:19

貌似低版本(例如2.6.1x)的行为不是这样,没有VM_LAZY_FREE的行为。

-------------------------

为啥3.8版本的free_unmap_vmap_area_noflush先调用unmap_vmap_area?
http://lxr.free-electrons.com/source/mm/vmalloc.c?v=3.8#L669

释放(init_mm)的页表是在unmap_vmap_area里完成的吧?

lazy的部分只负责清空rb_tree和释放vmap_area?
http://lxr.free-electrons.com/source/mm/vmalloc.c?v=3.8#L455
页: [1]
查看完整版本: vmalloc区域释放的页表如何处理?