vmalloc区域释放的页表如何处理?
内核版本:linux 2.6.30struct 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的映射没有什么关系吧。
反正它能够最终把虚拟地址映射到一个物理内存上。 貌似低版本(例如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]