77范文网 - 专业文章范例文档资料分享平台

linux内核虚拟内存管理算法(3)

来源:网络收集 时间:2018-11-25 下载这篇文档 手机版
说明:文章内容仅供预览,部分内容可能不全,需要完整文档或者需要复制内容,请下载word后使用。下载word有问题请添加微信号:或QQ: 处理(尽可能给您提供完整文档),感谢您的支持与谅解。点击这里给我发消息

/*

* Determine the object being mapped and call the appropriate * specific mapper. the address has already been validated, but * not unmapped, but the maps are removed from the list. */

vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); if (!vma) { }

vma->vm_mm = mm; vma->vm_start = addr; vma->vm_end = addr + len; vma->vm_flags = vm_flags;

vma->vm_page_prot = vm_get_page_prot(vm_flags); vma->vm_pgoff = pgoff;

INIT_LIST_HEAD(&vma->anon_vma_chain); if (file) {

if (vm_flags& VM_DENYWRITE) { }

if (vm_flags& VM_SHARED) { }

/* ->mmap() can change vma->vm_file, but must guarantee that * vma_link() below can deny write-access if VM_DENYWRITE is set * and map writably if VM_SHARED is set. This usually means the * new file must not have been exposed to user-space, yet. */

vma->vm_file = get_file(file); error = file->f_op->mmap(file, vma); if (error)

goto unmap_and_free_vma;

error = mapping_map_writable(file->f_mapping); if (error)

goto allow_write_and_free_vma; error = deny_write_access(file); if (error)

goto free_vma;

error = -ENOMEM; goto unacct_error;

/* Can addr have changed?? *

* Answer: Yes, several device drivers can do it in their

}

* f_op->mmap method. -DaveM

* Bug: If addr is changed, prev, rb_link, rb_parent should * be updated for vma_link() */

WARN_ON_ONCE(addr != vma->vm_start); addr = vma->vm_start; vm_flags = vma->vm_flags; error = shmem_zero_setup(vma); if (error)

goto free_vma;

} elseif (vm_flags& VM_SHARED) {

vma_link(mm, vma, prev, rb_link, rb_parent);

/* Once vma denies write, undo our temporary denial count */ if (file) { }

file = vma->vm_file; perf_event_mmap(vma);

vm_stat_account(mm, vm_flags, len>> PAGE_SHIFT); if (vm_flags& VM_LOCKED) { } if (file) /*

* New (or expanded) vma always get soft dirty status. * Otherwise user-space soft-dirty page tracker won't * be able to distinguish situation when vma area unmapped, * then new mapped in-place (which must be aimed as * a completely new data area).

uprobe_mmap(vma);

if (!((vm_flags& VM_SPECIAL) || is_vm_hugetlb_page(vma) ||

vma == get_gate_vma(current->mm)))

mm->locked_vm += (len>> PAGE_SHIFT); vma->vm_flags &= VM_LOCKED_CLEAR_MASK; if (vm_flags& VM_SHARED)

mapping_unmap_writable(file->f_mapping); allow_write_access(file); if (vm_flags& VM_DENYWRITE)

out:

else

*/

vma->vm_flags |= VM_SOFTDIRTY; vma_set_page_prot(vma); returnaddr;

unmap_and_free_vma: }

/* Undo any partial mapping done by a device driver. */ unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end); charged = 0;

if (vm_flags& VM_SHARED)

mapping_unmap_writable(file->f_mapping); vma->vm_file = NULL; fput(file);

allow_write_and_free_vma:

if (vm_flags& VM_DENYWRITE)

allow_write_access(file);

free_vma:

kmem_cache_free(vm_area_cachep, vma); if (charged)

vm_unacct_memory(charged); return error; unacct_error:

算法伪代码: mmap_region() {

寻找前后一个区域的vm_area_struct实例以及红黑树中节点对应的数据; if(在指定的映射位置已经存在映射)

do_munmap(); 检查内存空间是否满足需求,是否需要扩充;

如果是匿名映射(file为空),并且这个虚拟区是非共享的,则可以把这个虚拟区和*与它紧挨的前一个虚拟区进行合并;虚拟区的合并是由vma_merge()函数实现的。如*果合并成功,则转out处,请看后面out处的代码;

创建新的vm_area_strcut实例; file->f_op->mmap();//创建映射 if(VM_LOCKED)

扫描映射中各页发出的中断以便读取数据; retuen 映射的起始地址; }

(5)linux使用do_munmap()函数取消断开可执行映像向虚存区域的映射,删除有关的虚

存区域,定义在/mm/mmap.c中;

int do_munmap(structmm_struct *mm, unsignedlongstart, size_t len) {

error = __split_vma(mm, vma, start, 0);

/*

* Make sure that map_count on return from munmap() will * not exceed its limit; but let map_count go just above * its limit temporarily, to help free resources as expected. */

if (end < vma->vm_end &&mm->map_count >= sysctl_max_map_count)

return -ENOMEM;

/*

* If we need to split any vma, do it now to save pain later. *

* Note: mremap's move_vma VM_ACCOUNT handling assumes a partially * unmapped vm_area_struct will remain in use: so lower split_vma * places tmp vma above, and higher split_vma places tmp vma below. */

if (start> vma->vm_start) {

int error;

/* if it doesn't overlap, we have nothing.. */ end = start + len; if (vma->vm_start >= end)

return 0;

/* Find the first overlapping VMA */ vma = find_vma(mm, start); if (!vma)

return 0; prev = vma->vm_prev;

/* we have start < vma->vm_end */ len = PAGE_ALIGN(len); if (len == 0)

return -EINVAL;

if ((offset_in_page(start)) || start> TASK_SIZE || len> TASK_SIZE-start)

return -EINVAL; unsignedlong end;

structvm_area_struct *vma, *prev, *last;

}

}

if (error)

return error; prev = vma;

/* Does it split the last one? */ last = find_vma(mm, end);

if (last && end > last->vm_start) { }

vma = prev ? prev->vm_next : mm->mmap; /*

* unlock any mlock()ed ranges before detaching vmas */

if (mm->locked_vm) { } /*

* Remove the vma's, and unmap the actual pages */

detach_vmas_to_be_unmapped(mm, vma, prev, end); unmap_region(mm, vma, prev, start, end); arch_unmap(mm, vma, start, end); /* Fix up all other VM information */ remove_vma_list(mm, vma); return 0;

structvm_area_struct *tmp = vma; while (tmp && tmp->vm_start < end) { }

if (tmp->vm_flags & VM_LOCKED) { }

tmp = tmp->vm_next;

mm->locked_vm -= vma_pages(tmp); munlock_vma_pages_all(tmp);

int error = __split_vma(mm, last, end, 1); if (error)

return error;

算法伪代码: do_munmap() {

百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库linux内核虚拟内存管理算法(3)在线全文阅读。

linux内核虚拟内存管理算法(3).doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印 下载失败或者文档不完整,请联系客服人员解决!
本文链接:https://www.77cn.com.cn/wenku/zonghe/309527.html(转载请注明文章来源)
Copyright © 2008-2022 免费范文网 版权所有
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ: 邮箱:tiandhx2@hotmail.com
苏ICP备16052595号-18
× 注册会员免费下载(下载后可以自由复制和排版)
注册会员下载
全站内容免费自由复制
注册会员下载
全站内容免费自由复制
注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: