0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Linux内核中用GFP_ATOMIC申请内存意味着什么

Linux阅码场 来源:Linuxer 作者:Linuxer 2021-01-04 13:43 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

本文目的

本文补充校正一些Linux内核开发者关于GFP_ATOMIC的认知不完整的地方,阐述GFP_ATOMIC与free内存watermark的关系,并明确什么时候应该用GFP_ATOMIC申请内存。目录:

1. GFP_ATOMICvs. GFP_KERNEL

2. 内存水位,PF_MEMALLOC和GFP_ATOMIC

3. 何时使用GFP_ATOMIC(一个patch分析)

GFP_ATOMICvs. GFP_KERNEL

我们都知道,在中断、软中断、spinlock等原子上下文里面,申请内存,应该使用GFP_ATOMIC标记,譬如内核中有大量的kmalloc/GFP_ATOMIC的例子:

fd0acb90-4e4c-11eb-8b86-12bb97331649.png

对于不可睡眠的上下文,如果我们用常规的GFP_KERNEL这样的标记去申请内存,可能引发直接的内存reclaim,从而引起睡眠,所以GFP_KERNEL这种标记只适合进程上下文调用:

fd396c0c-4e4c-11eb-8b86-12bb97331649.png

GFP_KERNEL的标记可以引发直接的内存回收,从而导致进程阻塞睡眠,这在原子上下文显然是不允许的。

#define GFP_KERNEL (__GFP_RECLAIM | __GFP_IO | __GFP_FS) #define __GFP_RECLAIM ((__force gfp_t)(___GFP_DIRECT_RECLAIM|___GFP_KSWAPD_RECLAIM)

内存水位,PF_MEMALLOC和GFP_ATOMIC

那么GFP_ATOMIC是否仅仅意味着不能睡眠呢?档案是否定的,GFP_ATOMIC还与内存reclaim的水位相关。下面这个图是讲述水位watermark的一个著名的图,笔者懒得画了,直接从网下copy过来:

fda0690c-4e4c-11eb-8b86-12bb97331649.jpg

在Linux中,内存有3个水位:

HIGH:系统的free内存大于HIGH水位的时候,是一个相对保险的值,不需要急着做内存回收(reclaim);

LOW: 系统的free内存达到LOW水位的时候,启动后台kswapd进行内存回收,回收的目标是让空闲内存达到HIGH水位;

MIN:系统应该保有的最小free内存,当空闲内存达到这个值的时候,kswapd的后台回收可能来不及了,一般用户在申请内存的时候,进行DIRECT RECLAIM。

min水位一般是系统自动换算的,其具体值可以从/proc看出:

# cat /proc/sys/vm/min_free_kbytes 45056

而LOW水位一般是min*125%,HIGH 一般是min*150%。

MIN水位以下的内存,只能被紧急情况下的用户申请到,最著名的紧急用户莫过于PF_MEMALLOC用户,task_struct设置了这个标记表示忽略MIN水位。比如回收内存的代码本身也可能需要申请内存,这个时候我们应该给它无限制的申请能力。典型地,比如kswapd就设置了这个标记,这个代码里面的注释也非常精彩:

fddec24c-4e4c-11eb-8b86-12bb97331649.png

如果我们不允许回收内存的代码申请min以下的内存,则回收内存的代码可以触发回收内存,这样“子子孙孙,无穷匮也”。

当然,PF_MEMALLOC不是唯一的紧急用户,GFP_ATOMIC实际也是一个“半紧急”任务:

说它“紧急”,是因为如果原子上下文申请内存失败,往往意味着相应的中断、软中断、spinlock内部的代码就会执行失败,而我们又不会因为这种失败,而去尝试内存回收,这显然比较惨,我们应该尽可能让GFP_ATOMIC申请成功;

说它“半”,是因为它不至于紧急到PF_MEMALLOC这个程度,如果我们给它无限地申请到free内存为0的权力,则会导致PF_MEMALLOC没有内存了。想想,如果征粮队的人都饿死了,还怎么去征粮呢?

所以,内存的设计选择是,当有人用GFP_ATOMIC申请内存的时候,允许它从MIN水位以下,申请一定数量的内存。什么叫“一定数量”呢?就是不能让GFP_ATOMIC导致free 内存触底,GFP_ATOMIC还包含了高优先级的含义:

#define GFP_ATOMIC (__GFP_HIGH|__GFP_ATOMIC|__GFP_KSWAPD_RECLAIM)

注意这个里面的__GFP_HIGH不是HIGHMEM高端内存的意思,而是高优先级。

当我们用GFP_ATOMIC申请内存的时候,内核的水位检查代码,会允许我们触及到MIN水位以下的1/2:

fe13730c-4e4c-11eb-8b86-12bb97331649.png

那么,“魔鬼”就是在画红圈的2行代码。但是,如果我们进一步深究,会发现,GFP_ATOMIC不只是触及1/2*min,它甚至可以触及1/4*min,因为GFP_ATOMIC中的__GFP_HIGH让ALLOC_HIGH成立,而__GFP_ATOMIC让ALLOC_HARDER成立:

fe5222dc-4e4c-11eb-8b86-12bb97331649.png

所以,“魔鬼”又隐藏在了gfp_to_alloc_flags()的细节里。

一个patch的例子

在具体的工程实战中,我们建议:

原子上下文使用GFP_ATOMIC

比如在网络设备驱动drivers/net/ethernet中,就有大量的案例

fe6582dc-4e4c-11eb-8b86-12bb97331649.png

在内存紧急的路径上(比如不想睡眠,要求低延迟;或者要求内存吃紧的情况下,仍然可以从min水位以下申请内存),哪怕是进程上下文,我们也建议可以考虑使用GFP_ATOMIC

比如田涛童鞋最近在mm/zswap.c发的RFC patch:

https://lore.kernel.org/linux-mm/1608894171-54174-2-git-send-email-tiantao6@hisilicon.com/

fe85c902-4e4c-11eb-8b86-12bb97331649.png

fea50934-4e4c-11eb-8b86-12bb97331649.png

上面2个地方,其实都是可以睡眠的进程上下文,但是我们认为在frontendswap的路径上,我们对延迟敏感,对swap内存过程中进一步引发内存回收也担忧,因此,这里哪怕是非原子上下文,我们也没有使用GFP_KERNEL。

责任编辑:xj

原文标题:宋宝华:Linux内核中用GFP_ATOMIC申请内存究竟意味着什么?

文章出处:【微信公众号:Linuxer】欢迎添加关注!文章转载请注明出处。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 内核
    +关注

    关注

    4

    文章

    1436

    浏览量

    42505
  • Linux
    +关注

    关注

    88

    文章

    11628

    浏览量

    218016
  • GFP
    GFP
    +关注

    关注

    0

    文章

    5

    浏览量

    1559

原文标题:宋宝华:Linux内核中用GFP_ATOMIC申请内存究竟意味着什么?

文章出处:【微信号:LinuxDev,微信公众号:Linux阅码场】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    Linux-RT特点及简单应用

    :CFS调度器的设计重点是优化多任务系统的整体吞吐量和响应时间,而不是严格保证任务的实时性。这意味着在高负载情况下,某些任务可能会经历延迟或不确定的响应时间。 不可预测性:由于CFS调度器的非实时性质
    发表于 12-05 07:37

    电能质量在线监测装置通过了CQC认证意味着什么?

    LZ-100电能质量在线监测装置 电能质量在线监测装置通过CQC 认证(中国质量认证中心认证),意味着该装置在合规性、技术性能、安全性、可靠性等核心维度,均符合国家 / 行业相关标准及 CQC 认证
    的头像 发表于 09-03 15:57 433次阅读
    电能质量在线监测装置通过了CQC认证<b class='flag-5'>意味着</b>什么?

    IMU的精度对无人机姿态控制意味着什么?

    IMU的精度对无人机姿态控制至关重要,是决定无人机飞行稳定安全、响应性和任务执行能力的关键因素之一, IMU(包含三轴加速度计和三轴陀螺仪)是飞控系统实时估算无人机姿态(俯仰、横滚、偏航角)的核心传感器,直接决定了飞控系统“感知”自身姿态变化的准确性和及时性。 ER-MIMU-043的技术优势直击无人机对“小体积、高精度、低功耗”的需求,带外壳尺寸仅40×40×42mm(80g),内台体压缩至27×26×34mm(40g),可轻松集成于各类无人机中,大幅降
    的头像 发表于 07-25 17:01 555次阅读

    自动驾驶“单车智能”并不意味着不联网?

    [首发于智驾最前沿微信公众号]随着资金投入的不断加大,越来越多车企选择自研智驾系统,这也就意味着单车智能的技术路径成为行业的普遍选择。从概念上来看,单车智能就是让单个车辆的感知、决策和控制能力
    的头像 发表于 06-17 08:56 601次阅读
    自动驾驶“单车智能”并不<b class='flag-5'>意味着</b>不联网?

    如何配置和验证Linux内核参数

    Linux系统运维和性能优化中,内核参数(sysctl)的配置至关重要。合理的参数调整可以显著提升网络性能、系统稳定性及资源利用率。然而,仅仅修改参数是不够的,如何验证这些参数是否生效同样关键。
    的头像 发表于 05-29 17:40 794次阅读

    如何维护i.MX6ULL的安全内核

    。 5.15 内核系列将维护到 2026 年 12 月,这意味着将发布新版本,从而关闭已知漏洞。 不幸的是,据我所知,linux-imx 分支原则上不会使用较新的微版本进行更新;5.15.71 仍然是
    发表于 04-01 08:28

    树莓派4 性能大比拼:标准Linux与实时Linux 4.19内核的延迟测试

    引言本文是对我之前关于RaspberryPi3同一主题的帖子的更新。与之前的帖子一样,我使用的是随Raspbian镜像提供的标准内核,以及应用了RT补丁的相似内核版本。对于实时版,我
    的头像 发表于 03-25 09:39 659次阅读
    树莓派4 性能大比拼:标准<b class='flag-5'>Linux</b>与实时<b class='flag-5'>Linux</b> 4.19<b class='flag-5'>内核</b>的延迟测试

    嵌入式学习-飞凌嵌入式ElfBoard ELF 1板卡-驱动基本介绍

    驱动程序到内核意味着将驱动代码与内核代码合并,并通过重新编译整个内核将其包含在内核镜像中。这种方式将驱动程序与
    发表于 03-10 17:03

    飞凌嵌入式ElfBoard ELF 1板卡-驱动基本介绍

    驱动程序到内核意味着将驱动代码与内核代码合并,并通过重新编译整个内核将其包含在内核镜像中。这种方式将驱动程序与
    发表于 03-07 10:19

    AFE0064芯片手册中把所有的地引脚都表示为GND,是不是就意味着不分数字地和模拟地呢?

    最近在用AFE0064设计一款产品,再画版图的时候遇到了问题,就是AFE0064芯片手册中把所有的地引脚都表示为GND,是不是就意味着不分数字地和模拟地呢?如果后端AD分数字地和模拟地,为了达到更好的性能,GND应该和数字地相连,还是模拟地链接呢?
    发表于 01-10 07:06

    ADS7230有两个电源和两个地,是不是意味着芯片内部模拟部分和数字部分是隔离的?

    ADS7230有两个电源和两个地,是不是意味着芯片内部模拟部分和数字部分是隔离的?或者是非隔离,只做电平转换的?忘各位大侠解答,小弟不甚感激!!!
    发表于 01-08 08:21

    腾讯云内核团队修复Linux关键Bug

    Maintainer深感棘手的关键内核bug。 这一改进方案经过严格评审和测试,最终被合并进入后续的Linux LTS(长期支持)版本中,标志腾讯云在操作系统内核领域的技术实力得到了
    的头像 发表于 12-31 10:58 917次阅读

    ADS1274没有DRDY信号输出,是否意味着芯片已经损坏?

    ADS1274有CLK信号,但是没有DRDY信号输出,是否意味着芯片已经损坏? 芯片工作正常应该一直有DRDY信号输出的,之前芯片一直是正常的,接了个传感器加载测试结果DRDY就没输出了,传感器
    发表于 12-31 07:34

    ADS8671 datasheet里写的是小信号输入-3db带宽为15KHz,是不是意味着正常信号超过10K衰减已经很厉害了?

    ADS8671这个芯片,datasheet里写的是小信号输入-3db带宽为15KHz,是不是意味着正常信号超过10K衰减已经很厉害了,那要1MSPS这么高的采样速率有什么用?
    发表于 12-20 07:54

    飞凌嵌入式ElfBoard ELF 1板卡-Linux内核移植之内核简介

    学到本章节,大家应该对Linux操作系统都有了一定的了解,但可能还不知道我们拿到手的内核源码都经历了什么。linux有一个庞大的开源社区,每个人都可以向开源社区提交代码。由于linux
    发表于 12-13 09:03