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

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

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

{

if (prot == PROT_EXEC) {

pkey = execute_only_pkey(mm);

/* Obtain the address to map to. we verify (or select) it and ensure * that it represents a valid section of the address space. */

addr = get_unmapped_area(file, addr, len, pgoff, flags); if (offset_in_page(addr))

returnaddr;

/* Too many mappings? */

if (mm->map_count > sysctl_max_map_count)

return -ENOMEM; /* offset overflow? */

if ((pgoff + (len>> PAGE_SHIFT))

return -EOVERFLOW;

/* Careful about overflows.. */ len = PAGE_ALIGN(len); if (!len)

return -ENOMEM; if (!(flags& MAP_FIXED))

addr = round_hint_to_min(addr); /*

* Does the application expect PROT_READ to imply PROT_EXEC? *

* (the exception is when the underlying filesystem is noexec * mounted, in which case we dont add PROT_EXEC.) */

if ((prot& PROT_READ) && (current->personality & READ_IMPLIES_EXEC))

if (!(file&& path_noexec(&file->f_path)))

prot |= PROT_EXEC;

if (!len)

return -EINVAL; *populate = 0;

structmm_struct *mm = current->mm; int pkey = 0;

}

if (pkey < 0)

pkey = 0;

/* Do simple checking here so the lower-level routines won't have * to. we assume access permissions have been handled by the open * of the memory object, so we don't do any here. */

vm_flags |= calc_vm_prot_bits(prot, pkey) | calc_vm_flag_bits(flags) |

mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;

if (flags& MAP_LOCKED)

if (!can_do_mlock())

return -EPERM;

if (mlock_future_check(mm, vm_flags, len))

return -EAGAIN;

if (file) {

switch (flags& MAP_TYPE) { case MAP_SHARED:

if ((prot&PROT_WRITE) && !(file->f_mode&FMODE_WRITE)) /*

* Make sure we don't allow writing to an append-only * file.. */

if (IS_APPEND(inode) && (file->f_mode & FMODE_WRITE)) /*

* Make sure there are no mandatory locks on the file. */

if (locks_verify_locked(file))

return -EAGAIN; return -EACCES; return -EACCES;

structinode *inode = file_inode(file);

vm_flags |= VM_SHARED | VM_MAYSHARE; if (!(file->f_mode & FMODE_WRITE))

vm_flags&= ~(VM_MAYWRITE | VM_SHARED);

/* fall through */

} /*

case MAP_PRIVATE:

if (!(file->f_mode & FMODE_READ)) }

if (!file->f_op->mmap)

return -ENODEV; return -EINVAL;

if (vm_flags& (VM_GROWSDOWN|VM_GROWSUP)) break;

return -EACCES; if (vm_flags& VM_EXEC)

return -EPERM; vm_flags&= ~VM_MAYEXEC; if (path_noexec(&file->f_path)) {

default: }

switch (flags& MAP_TYPE) { case MAP_SHARED: }

if (vm_flags& (VM_GROWSDOWN|VM_GROWSUP)) /*

* Ignore pgoff. */ pgoff = 0;

vm_flags |= VM_SHARED | VM_MAYSHARE; break; /*

* Set pgoff according to addr for anon_vma. */

pgoff = addr>> PAGE_SHIFT; break;

return -EINVAL;

return -EINVAL; return -EINVAL;

} else {

case MAP_PRIVATE:

default:

* Set 'VM_NORESERVE' if we should not account for the * memory use of this mapping. */

}

if (flags& MAP_NORESERVE) { }

addr = mmap_region(file, addr, len, vm_flags, pgoff); if (!IS_ERR_VALUE(addr) && ((vm_flags& VM_LOCKED) ||

(flags& (MAP_POPULATE | MAP_NONBLOCK)) == MAP_POPULATE))

*populate = len; returnaddr;

/* We honor MAP_NORESERVE if allowed to overcommit */ if (sysctl_overcommit_memory != OVERCOMMIT_NEVER)

vm_flags |= VM_NORESERVE;

/* hugetlb applies strict overcommit unless MAP_NORESERVE */ if (file&& is_file_hugepages(file))

vm_flags |= VM_NORESERVE;

算法伪代码: do_mmap() {

判断是否隐藏了可执行属性;

该虚拟区间的地址是否必须有参数addr指定,若不是,重新获取addr地址; 检测要映射的文件部分的长度是否是页对齐; offset是否越界; 映射数量限制;

获得一个一个未映射区间的起始地址,并检查是否是页大小对齐的,即低12位必须*为0;

获取文件相关节点inode;

如果file结构指针为0,则目的仅在于创建虚拟区间,或者说,并没有真正的映射*发生;如果file结构指针不为0,则目的在于建立从文件到虚拟区间的映射,那就要*根据标志指定的映射种类,把为文件设置的访问权考虑进去;

判断输入的欲映射的起始地址是否小于最小映射地址,如果小于,将addr修改为最小地址,不过前提是MAP_FIXED旗标没有设置;

查找没有映射过的空洞内存区,返回值addr就是这段空洞的起始地址;

对vm_flags进行设置,由参数flags确定vma线性区的flags,是共享还是私有; 创建vma,mmap_region(); }

(4)mmap_region()代码如下:

unsignedlong mmap_region(structfile *file, unsignedlongaddr, {

structmm_struct *mm = current->mm; structvm_area_struct *vma, *prev;

unsignedlonglen, vm_flags_t vm_flags, unsignedlongpgoff)

int error;

structrb_node **rb_link, *rb_parent; unsignedlong charged = 0;

/* Check against address space limit. */

if (!may_expand_vm(mm, vm_flags, len>> PAGE_SHIFT)) { }

/* Clear old maps */

while (find_vma_links(mm, addr, addr + len, &prev, &rb_link, } /*

* Private writable mapping: check memory availability */

if (accountable_mapping(file, vm_flags)) { } /*

* Can we just expand an old mapping? */

vma = vma_merge(mm, prev, addr, addr + len, vm_flags,

NULL, file, pgoff, NULL, NULL_VM_UFFD_CTX);

if (vma)

goto out;

charged = len>> PAGE_SHIFT;

if (security_vm_enough_memory_mm(mm, charged))

return -ENOMEM; vm_flags |= VM_ACCOUNT;

&rb_parent)) { return -ENOMEM;

if (do_munmap(mm, addr, len)) unsignedlong nr_pages; /*

* MAP_FIXED may remove pages of mappings that intersects with * requested mapping. Account for the pages it would unmap. */

nr_pages = count_vma_pages_range(mm, addr, addr + len); if (!may_expand_vm(mm, vm_flags,

(len>> PAGE_SHIFT) - nr_pages))

return -ENOMEM;

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

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