Linux内核管理之分配掩码(三)

分配掩码是linux内存管理中非常重要的一个参数,它影响着页面分配的整个流程。

分配掩码gfp_mask定义在include/linux/gfp.h文件中,这些标志位在Linux4.4内核中被重新归类,大致可以分成以下几类:

  • 内存管理区修饰符(zone modifier)
  • 移动修饰符(mobility and placement modifier)
  • 水位修饰符(watermark modifier)
  • 页面回收修饰符(page reclaim modifier)
  • 行动修饰符(action modifier)

内存管理区修饰符

内存管理区修饰符主要是用来表示应当从哪些内存管理区中来分配物理内存。内存管理区修饰符使用gfp_mask的最低4个比特位来表示

标志 描述
__GFP_DMA 从ZONE_DAM中分配内存
__GFP_DMA32 从ZONE_DMA32中分配内存
__GFP_HIGHMEM 优先从ZONE_HIGHMEN中分配内存

移动修饰符

移动修饰符主要用来指示分配出来的页面具有的移动属性。

在Linux2.6.24内核中,为了解决外碎片化的问题,引入了迁移类型,因此在分配内存时也需要指定所分配的页面具有哪些移动属性。

标志 描述
__GFP_MOVABLE 页面可以被迁移或者回收,比如内存规整
__GFP_RECLAIMABLE 在slab分配器中指定了SLAB_RECLAIM_ACCOUNT标志位,表示slab中使用的页面可以通过shrinkers来回收
__GFP_HARDWALL 使能cpuset内存分配策略
__GFP_THISNODE 从指定的内存节点中分配内存,并且没有回退机制
__GFP_ACCOUNT 分配过程中会被kmemcg记录

水位修饰符

水位修饰符用来控制是否可以访问系统紧急预留的内存

标志 描述
__GFP_HIGH 表示分配内存具有高优先级,并且这个分配请求是很有必要的,分配器可以使用紧急的内存池
__GFP_ATOMIC 表示分配内存的过程不能执行页面回收或者睡眠动作,并且具有很高的优先级。常用的场景是在中断上下文分配内存
__GFP_MEMALLOC 分配过程中允许访问所有的内存,包括系统预留的紧急内存
__GFP_NOMEMALLOC 分配过程中不允许访问系统预留的紧急内存

页面回收修饰符

标志 描述
__GFP_IO 允许开启I/O传输
__GFP_FS 允许调用底层的文件系统。。清楚这个标志位通常是为了避免死锁的发生
__GFP_DIRECT_RECLAIM 分配内存的过程中调用直接页面回收机制
__GFP_KSWAPD_RECLAIM 表示当到达内存管理区的低水位时会唤醒kswapd内核现成去异步地回收内存,直到内存管理区恢复到高水位为止
__GFP_RECLAIM 用来允许或禁止直接页面回收和kswapd内核线程
__GFP_REPEAT 当分配失败时会继续尝试
__GFP_NOFAIL 当分配失败时会无限地尝试下去,直到分配成功为止。当分配者希望分配内存不失败时,应该使用这个标志位,而不是自己写一个while循环来不断调用页面分配接口函数
__GFP_NORETRY 当直接页面回收和内存规整等机制都使用了还是无法分配内存时,就不用去重复尝试分配了,直接返回NULL

行动修饰符

标志 描述
__GFP_COLD 分配的内存不会马上被使用
__GFP_NOWARN 关闭分配过程中的一些错误报告
__GFP_ZERO 返回一个全部填充为0的页面
__GFP_NOTRACK 不被kmemcheck机制跟踪
__GFP_OTHER_NODE 在远端一个内存节点上分配

类型标志

对于内核开发者或者驱动开发者来说,要正确使用这些标志位是一件很困难的事情,因此定义了一些常用的分配掩码的组合,成为类型标志。类型标志提供了内核开发中常用的分配掩码的组合,推荐开发者使用这些类型标志。

一般来说,__GFP开头的就为分配掩码,GFP开头的(没有下划线)的就是类型标志

标志 描述
GFP_ATOMIC 调用者不能睡眠并且保证分配会成功。它可以访问系统预留的内存,这个标志位通常使用在中断处理程序、下半部、持有自旋锁或者其他不能睡眠的地方
GFP_KERNEL 内核分配内存最常用的标志位之一。它可能会被阻塞,即分配过程可能会睡眠
GFP_NOWAIT 分配不允许睡眠等待
GFP_NOIO 不需要启动任何的I/O操作。比如使用直接回收机制去丢弃干净的页面或者为slab分配的页面
GFP_NOFS 不会访问任何的文件系统的接口和操作
GFP_USER 通过用户空间的进程用来分配内存,这些内存可以被内核或者硬件使用。常用的一个场景是,硬件使用的DMA缓冲器要映射到用户空间,比如显卡的缓冲器
GFP_DMA/GFP_DMA32 使用ZOME_DMA或者ZOME_DMA32来分配内存
GFP_HIGHUSER 用户空间进程用来分配内存,优先使用ZONE_HIGHME,这些内存可以被映射到用户空间,内核空间不会直接访问这些内存,另外这些内存不能被迁移
GFP_HIGHUSER_MOVEABLE 类似GFP_HIGHUSER,但是页面可以被迁移

上面表格中的类型标志都是非常常用的分配掩码组合,在实际使用的过程汇总需要注意以下事项。

  • GFP_KERNEL
    GFP_KERNEL是最常见的内存分配掩码之一,主要用于分配内核使用的的内存,需要注意的是分配过程中会引起睡眠,这在中断上下文以及不能睡眠的内核路径里调用该分配掩码需要特别警惕,因为会引起死锁或者其他系统异常

  • GFP_ATOMIC
    GFP_ATOMIC这个标志位正好和GFP_KERNEL相反,它可以使用在不能睡眠的内存分配路径上,比如中断处理程序、软中断以及tasklet等。GFP_KERNEL可以让调用者睡眠等待系统页面回收来释放一些内存,但是GFP_ATOMIC不可以,所以有可能会分配失败。

  • GFP_USERGFP_HIGHUSERGFP_HIGHUSER_MOVEABLE
    这三个标志位都是为用户空间进程分配内存的。不同之处在于,GFP_HIGHUSER首先使用高端内存,GFP_HIGHUSER_MOVEABLE首先使用高端内存并且分配的内存具有可迁移性

  • GFP_NOINGFP_NOFS
    这两个标志位都会产生阻塞,它们用来避免某些其他的操作。
    GFP_NOIO表示分配过程中绝不会启动任何磁盘I/O的操作。
    GFP_NOFS表示分配过程中绝不会启动文件系统的相关操作。
    举个例子,假设进程A在执行打开文件的操作中需要分配内存,这时内存短缺了,那么进程A会睡眠等待,系统的OOM Killer机制会选择一个进程杀掉。假设选择了进程B,而进程B退出时需要执行一些文件系统的操作,这些操作可能会去申请锁,而恰巧进程A持有这个锁,所以死锁就发生了。

常用类型标志的使用

待完成

Linux内核管理之分配掩码(三)相关推荐

  1. Linux内核管理风范

    Linux内核管理风范----Linux kernel management styleby Linus Torvalds http://wiki.woodpecker.org.cn/moin/Lin ...

  2. Linux内存管理 (4)分配物理页面

    专题:Linux内存管理专题 关键词:分配掩码.伙伴系统.水位(watermark).空闲伙伴块合并. 我们知道Linux内存管理是以页为单位进行的,对内存的管理是通过伙伴系统进行. 从Linux内存 ...

  3. linux 进城 io字节,(2)linux内核之内存分配与IO口操作

    /***************************************************分配内存******************************************** ...

  4. Linux内存管理(六): 分配物理内存alloc_pages

    基于Linux 5.10, 体系结构是aarch64 上文介绍了linux对物理内存的描述,本篇介绍linux下物理页面的分配函数alloc_pages 1.API接口 alloc_pages是内核中 ...

  5. linux内核包转发过程(三)NIC帧接收分析

    [版权声明:转载请保留源:blog.csdn.net/gentleliu.邮箱:shallnew*163.com] 每一个cpu都有队列来处理接收到的帧.都有其数据结构来处理入口和出口流量,因此.不同 ...

  6. Linux内核中内存分配函数

    1.原理说明 Linux内核 中采 用了一种同时适用于32位和64位系统的内 存分页模型,对于32位系统来说,两级页表足够用了,而在x86_64系 统中,用到了四级页表,如图2-1所示.四级页表分别为 ...

  7. Linux内存管理宏观篇(三)物理内存:物理页面

    前言 关于物理内存,物理,那肯定是事物,实实在在的东西.对于这种实在的,就需要进行管理,而管理肯定是软件来管理. 对于物理内存怎么管理? 涉及到的无非就是怎么分配内存.怎么回收整理内存.怎么样提高分配 ...

  8. linux内核dma内存分配,Linux 4.x 内核空间 DMA 虚拟内存地址

    Architecture: i386 32bit Machine Ubuntu 16.04 Linux version: 4.15.0-39-generic 目录 DMA 虚拟内存区 在 IA32 体 ...

  9. 深入分析linux内核的内存分配函数devm_kzalloc

    在分析驱动代码的时候,经常会遇到使用devm_kzalloc()为一个设备分配一片内存的情况.devm_kzalloc()是内核用来分配内存的函数,同样可以分配内存的内核函数还有devm_kmallo ...

最新文章

  1. ant PageHeaderWrapper 返回上一页
  2. 转:探讨SQL Server 2005的安全策略
  3. Difference between prop and attr in different version of jquery
  4. 全排列之递归与非递归算法实现总结
  5. MVC--Razor(1)
  6. 在C++中侦测内嵌型别的存在(rev#2)
  7. C语言中函数可变参数解析
  8. mysqlserver输入密码后闪退_iOS降级教程:iOS 14 后如何降级到ios13?
  9. php设置路径别名,设置别名php = / bin / php56,但今天它已恢复为原始路径:/ bin / php...
  10. POJ-2262 Goldbach's Conjecture
  11. 中孚计算机保密 卸载,智华计算机终端保密检查系统怎样卸载
  12. 良田摄像头 linux,良田万能摄像头高拍仪驱动下载|良田万能摄像头驱动 官方版 - 软件下载 - 绿茶软件园|33LC.com...
  13. 记录一次破解某加固APP的修改纪录
  14. android sqlite数据库 emoji表情,Android的Emoji表情
  15. uni-app 生成邀请二维码海报
  16. 中国象棋AI在线弈游戏源码
  17. 九步确定你的人生目标和制定达到目标的计划
  18. 天津科技大学计算机专业,天津科技大学计算机科学与信息工程学院介绍
  19. 计算机科学与技术反思录。
  20. ssh登录极路由后台_十八聊智能 篇一百一十:搭建个人云盘,蒲公英企业级路由G5评测:个人私有云+企业异地组网两大杀手锏_路由器...

热门文章

  1. 长沙湘江科技学校计算机信息,长沙湘江科技中等职业学校简介|长沙湘江科技中等职业学校介绍...
  2. 计算机科学与技术文科可以学么,文科生成绩一般,大学可以选择计算机吗?
  3. eclipse ide for c/c++_大众CC新款开启新的人生 辉煌报价钜惠 _车讯网chexun.com
  4. Python机器学习:线型回归法01简单线型回归法
  5. alidata mysql 卸载_mysql相关(一)、基本知识
  6. matlab的cylinder函数,matlab cylinder怎么用,Matlab cylinder 函数
  7. java.util.list 报错_Java 报错 .updateValue' has an unsupported return type: interface java.util.List...
  8. Endnote自定义参考文献格式锦集
  9. jemalloc mysql5.6_Mysql-5.6安装编译全教程
  10. 机器学习和深度学习_算法测评 | 机器学习VS深度学习