根据gfp_mask来获得对应的zone

gfp&内存分配学习 zone type:Zone从高到底是:ZONE_MOVABLE,ZONE_HIGHMEM,ZONE_NORMAL,ZONE_DMA32,ZONE_DMA 伙伴系统:在每个管理区,页框被伙伴系统的部分来处理。Linux的伙伴系统解决外碎片问题,把所有的空闲页框分组为11个块链表,每个链表块分别包含大小为1,2,4,8…1024个连续的页框, GFP_ZONE_TABLE:相关注释如下: * GF... 阅读详情

本篇文章只是分析一下gfp_mask到zone的对应关系在内核中的实现:

内核代码如下:(3.0) 

#define GFP_ZONE_TABLE	(ZONE_NORMAL << 0 * ZONES_SHIFT)				      \
	| (OPT_ZONE_DMA << ___GFP_DMA * ZONES_SHIFT)			      \
	| (OPT_ZONE_HIGHMEM << ___GFP_HIGHMEM * ZONES_SHIFT)		      \
	| (OPT_ZONE_DMA32 << ___GFP_DMA32 * ZONES_SHIFT)		      \
	| (ZONE_NORMAL << ___GFP_MOVABLE * ZONES_SHIFT)			      \
	| (OPT_ZONE_DMA << (___GFP_MOVABLE | ___GFP_DMA) * ZONES_SHIFT)	      \
	| (ZONE_MOVABLE << (___GFP_MOVABLE | ___GFP_HIGHMEM) * ZONES_SHIFT)   \
	| (OPT_ZONE_DMA32 << (___GFP_MOVABLE | ___GFP_DMA32) * ZONES_SHIFT)   \
)

static inline enum zone_type gfp_zone(gfp_t flags)
{
	enum zone_type z;
	int bit = (__force int) (flags & GFP_ZONEMASK);

	z = (GFP_ZONE_TABLE >> (bit * ZONES_SHIFT)) &
					 ((1 << ZONES_SHIFT) - 1);
	VM_BUG_ON((GFP_ZONE_BAD >> bit) & 1);
	return z;
}

分析一下gfp_zone函数,首先系统中的ZONE的个数,不超过2的ZONE_SHIFT次方,即可以用ZONE_SHIFT个BIT位来表示ZONE的值,

GFP_ZONEMASK定义的地方如下:

#define GFP_ZONEMASK	(__GFP_DMA|__GFP_HIGHMEM|__GFP_DMA32|__GFP_MOVABLE)

flags&GFP_ZONEMASK,是将与GFP_XXX无关的其他位清零,下面看一下GFP_ZONE_TABLE的定义,定义中包含的几个宏变量,定义如下:

#ifdef CONFIG_HIGHMEM
#define OPT_ZONE_HIGHMEM ZONE_HIGHMEM
#else
#define OPT_ZONE_HIGHMEM ZONE_NORMAL
#endif

#ifdef CONFIG_ZONE_DMA
#define OPT_ZONE_DMA ZONE_DMA
#else
#define OPT_ZONE_DMA ZONE_NORMAL
#endif

#ifdef CONFIG_ZONE_DMA32
#define OPT_ZONE_DMA32 ZONE_DMA32
#else
#define OPT_ZONE_DMA32 ZONE_NORMAL
#endif

从其定义可以看出,如果没有定义HIGHMEM,则ZONE_HIGHMEM自动指向ZONE_NORMAL,其他类似。GFP_ZONE_TABLE的定义,其实是将各个ZONE的值放到对应的BIT位上,ZONE_NORMAL放到[0,ZONE_SHIFT)位,GFP_DMA放到[ZONE_SHIFT, 2*ZONE_SHIFT)位上,依此类推。

知道了GFP_ZONE_TABLE的意义,下面的语句也就不难理解了,bit*ZONE_SHIFT即得到该ZONE所对应的BIT位,然后将GFP_ZONE_TABLE左移所得位数量,这时候得到的是从这个ZONE开始往上的所有BIT位,要将无关的ZONE清零,即只取低ZONE_SHIFT位,所以要&((1<<ZONE_SHITF) -1)。下面VM_BUG_ON内的语句只是做一下校验,读者可以自行分析一下,应该不难理解。



#Liunx内存管理# 页面分配器是按照什么方向来扫描zone的? 在 Linux 内核中,页面分配器(Page Allocator)扫描内存区域(Zone)的方向遵循 从高优先级到低优先级 的规则,具体逻辑如下: 内核根据 硬件兼容性 和 内存使用效率 预先定义了 Zone 的优先级顺序: 1.高优先级 → 低优先级 *典型顺序(以 x86_64 为例): ZONE_NORMAL → ZONE_DMA32 → ZONE_DMA *对于 32 位系统: ZONE_HIGHMEM → ZONE_NORMAL → ZONE_DMA *核心逻辑:优先从通用性高、访问速度快 阅读详情

相关推荐

__GFP_MOVABLE是怎样影响页框链表的分配分析【linux4.8.4】

首先让我们看下__GFP_MOVABLE的定义 #define __GFP_MOVABLE ((__force gfp_t)___GFP_MOVABLE) #define ___GFP_MOVABLE 0x08u 这个标志位在很多地方都有使用,如磁盘文件系统分配页缓存、用户态程序分配堆栈空间等。 那我们来看下,此类标志位是怎么影响页面分配的? 其余的先不分析,我们直接从分配物理页面的

weijinhua_123的博客 1266

如何从GFP确定最后申请的内存来自哪个zone?

申请内存时需要先确定两个值,分别是high_zoneidx和migratetype。这两个值从哪里获取到呢?都是利用上面传递过来的GFP flag。 对于high_zoneidx是通过gfp_zone函数获取的,而migratetype是通过gfpflags_to_migratetype来获取的。其中gfp_zone是利用的GFP标志位的bit[0-3]这4个bits来确定的,而migratetype是bit[3-4]这两个bits。需要注意他们中间是存在重复的__GFP_MOVABLE标志的,说明它不仅仅

程序猿Ricky的日常干货 1071

PCB布线避坑指南:晶振布局的5个致命错误(附正确示例图)

本文深入解析PCB布线中晶振布局的5个致命错误,包括底层布线、电容布局、地平面处理等关键问题,并提供实战解决方案。通过真实案例和量化数据,帮助硬件开发者避免常见陷阱,提升电路稳定性和性能。特别针对晶振这一高敏感元件,给出布线参数黄金法则和三维避让原则。

weixin_29215391的博客 428

gfp_mask转换成对应的zone和migratetype

1.node的转换 在分配内存时,都会带分配参数比如GPF_KERNEL等等,那么,一次内存分配从哪个zone分配了? 这里就必需把mask转换成zone,gfp_mask低4位用于表示分配的zone static inline enum zone_type gfp_zone(gfp_t flags) {     enum zone_type z;     int bit = (__forc...

bin_linux96的专栏 3201

贝莱德(BlackRock)—— 阿拉丁(Aladdin)平台的 AI 赋能升级

全称(资产、负债、债务与衍生品投资网络),是贝莱德自主研发的一体化投资管理与风险管理技术平台,被誉为全球资管行业的 “

xm_mm的博客 1727

Linux中Hadoop 集群搭建

零、下载Hadoop: http://archive.cloudera.com/cdh5/cdh/5/?tdsourcetag=s_pctim_aiomsg 一、集群规划: 搭建的 hadoop 集群由 3 台服务器组成,分别叫做 master,salve1 和 slave2。其中 master 作为主节点,slave1 和 slave2 作为从节点。 二、网络配置: 1.查看 3 个节点的主机名...

白墨的小白博客 3992

深入linux设备驱动程序内核机制(第三章) 读书笔记

第三章 分配内存     内存的管理总体上可以分为两大类:一是对物理内存的管理, 二是对虚拟内存的管理. 前者是用于特定的平台     构架上实际物理内存空间管理, 后者用于特定处理器体系架构上虚拟地址空间的管理. 本文欢迎转载 本文出处:blog.youkuaiyun.com/dyron 3.1 物理内存的管理     物理内存定义方面, 内存节点, 内存区域和内存页. 对物

随风 2501

CCF CSP历年题解(python)

菜鸡一枚,没参加过算法竞赛,单纯为了抵研究生考试复试才刷题,通过写博客记录下来,希望能和大家互相交流,代码质量不高,大家见谅。 因为考研等原因,题目不定期更新… 第一题 201312-1出现最多次数的数 ...

weixin_44690402的博客 5004

buddy伙伴系统

Linux内存管理简述 Linux的内存管理不仅与处理器的架构相关,还要综合考虑性能需求。在Linux内核内存管理的框架中,最底层的page allocator是对物理内存进行管理的模块,负责管理所有的物理内存,分配和释放都是以page为单位,大小是2^N个连续的物理内存页。所有的内存管理都是以page allocator为基础,采用的算法为经典的Buddy(伙伴算法)。 对于UMA架构,比如SMP,只有一个物理内存节点,但是对于服务器的NUMA架构,会有多个物理内存节点。Linux为了管理所有内存节点的物

weixin_44395686的博客 1278

人形机器人核心架构梳理

定义:机器人是能进行运动、操纵或定位且具有一定程度自主能力的可编程执行机构。按外在形态分类可分为传统机器人和人形机器人,其中人形机器人是一种利用人工智能和机器人技术制造的具有类似人类外观和行为的机器人。

小海聊智造 1万+

微信群“智”变:扣子机器人无缝接入实战

本文介绍了如何将扣子(Coze)机器人接入微信群实现智能化管理。文章首先阐述了扣子机器人的自然语言处理、自动分类和多模态交互等功能特点,以及其深度学习模型和持续学习能力的技术优势。随后详细讲解了接入步骤:从微信公众号配置、扣子平台机器人创建,到使用Flask框架实现消息转发功能的关键代码。通过电商客服和技术社群两个实际案例,展示了扣子机器人在提升响应效率、优化社群运营方面的显著效果。最后展望了未来在智能推荐、多模态交互等领域的发展潜力,为微信群智能化管理提供了实用解决方案。

远程部署调试 运行安装 项目调试 二次开发 项目技术新 持续迭代 部分源码免费分享 831

#Linux 内存管理# 在页面分配器中,如何从分配掩码(gfp_mask)中确定可以从哪些zone中分配内存?

在Linux内核中,页面分配器通过 gfp_mask(分配掩码) 确定可以从哪些内存区域(zone)分配内存。

sinat_37817094的博客 1123

【学前须知】推荐阅读顺序

AUTOSAR学习笔记专栏文章推荐阅读顺序

weixin_47571898的博客 744

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

在Linux2.6.24内核中,为了解决外碎片化的问题,引入了迁移类型,因此在分配内存时也需要指定所分配的页面具有哪些移动属性。对于内核开发者或者驱动开发者来说,要正确使用这些标志位是一件很困难的事情,因此定义了一些常用的分配掩码的组合,成为。内存管理区修饰符使用gfp_mask的最低4个比特位来表示。类型标志提供了内核开发中常用的分配掩码的组合,推荐开发者使用这些类型标志。主要用来指示分配出来的页面具有的移动属性。开头的(没有下划线)的就是类型标志。开头的就为分配掩码,

2401_86023443的博客 1437

Dify搭建AI测试用例生成器

1、获取产品需求文档2、解读、分析、挖掘需求点,提炼为测试点3、依据测试点,生成详细的测试用例4、输出测试用例1、打开 Dify 控制台,依次点击【工作室】-【ChatFlow】-【创建空白应用】。

十二测试录 1371

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

gfp_mask含义

gfp_mask标志在alloc_page,kmalloc函数中都有用到。该标志可以分为三类:行为修饰符,区修饰符,类型修饰符。        行为修饰符表示内核应当如何分配所需的内存,在某些特定的情况下,只能使用某些特定的方法分配内存,例如,中断处理程序就要求内核在分配内存时不能睡眠(因为中断处理程序不能被重新调度)。常用标志值有__GPF_WAIT(分配器可以睡眠),__GFP_IO(分

You are what you output 6386

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

gfp_mask是0代表什么?

之前写的博客有一个遗留问题,find_get_page函数里指定了gfp_mask是0,这个0代表什么含义呢? 内核的gfp.h文件里其实已经给出了答案: /* * GFP_ZONE_TABLE is a word size bitstring that is used for looking up the * zone to use given the lowest 4 bits of gfp_t. Entries are GFP_ZONES_SHIFT * bits long and there

kaka__55的博客 536

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

内存申请标记注意区分___GFP_HIGH和___GFP_HIGHMEM

背景 经常在看内存管理这块的代码时会看到这两个标记,有时候稍微不注意就会把他们搞混了,本篇博客就来聊聊他们的区别。 定义 首先这两个标记的定义如下,由此可见他们两个是不同的两个标记,表示的当然也是不同的意义: #define ___GFP_HIGH 0x20u #define ___GFP_HIGHMEM 0x02u 对于___GFP_HIGHMEM 标记来说,它是用来在内存申请时确定要从哪个目标zone中申请内存的。具体可以参考我的博文: 《如何从GFP确定最后申请的内存来自

程序猿Ricky的日常干货 1877

#Linux内存管理# 为用户进程分配物理内存,分配掩码应该选用GFP_KERNEL,还是GFP_HIGHUSER_MOVABLE呢?

在为用户进程分配物理内存时,需根据具体场景和需求选择分配掩码(gfp_mask),核心区别如下: 主要用于内核自身数据结构(如 task_struct、socket buffer)的分配。 行为特点: 允许阻塞(__GFP_RECLAIM 标志生效),若当前内存不足,可能触发直接内存回收(Direct Reclaim)或进入睡眠等待。 允许休眠(通过__GFP_WAIT)、允许触发文件系统回写(__GFP_FS) 默认从 ZONE_NORMAL 分配,物理页不可移动(MIGRATE_UNMOVABLE)

sinat_37817094的博客 1213

Linux 内存区域(Zone)划分详解

Zone 是物理地址的逻辑划分,为了解决 DMA 寻址限制和 32 位内核虚拟地址空间不足的问题。常见 ZoneZONE_DMAZONE_DMA32。每个 Zone 有独立的伙伴系统和水位线,内存分配请求会按照 fallback 顺序尝试不同的 Zone。64 位系统没有 ZONE_HIGHMEM,且 ZONE_NORMAL 覆盖绝大部分物理内存。通过可以查看各 Zone 的详细状态。

qq_32768419的博客 500

Linux内存分配核心:gfp_mask到zonelist的映射与zone遍历机制

内存分配是操作系统性能的关键环节,物理内存被划分为多个zone以满足不同硬件访问限制。内核通过gfp_mask中的标志位控制分配行为,并借助zonelist将候选zone按优先级排列。gfp_mask到zone类型的映射由gfp_zone()查表完成,而get_page_from_freelist()则遍历zonelist,结合水位检查决定最终取页位置。理解这一路径有助于排查page allocation failure、优化NUMA访问延迟,并为内核驱动开发提供有力支撑。以源码为主线拆解这一动态决策过程,

weixin_33178839的博客 314

Linux的ZONE_DMA,ZONE_NORMAL,ZONE_HIGHMEM及分配页释放页函数的简单介绍

Linux的ZONE_DMA,ZONE_NORMAL,ZONE_HIGHMEM及分配页释放页函数的简单介绍

aoeaoao的博客 1546

Linux内核gfp_mask到zonelist转换:页面分配优先级与陷阱

在Linux内核中,内存分配请求通过gfp_mask标志传递语义,但buddy分配器真正执行前,必须先将这些标志转换成具体的zone类型,并在对应的zonelist上按优先级遍历。这一转换过程决定了分配请求优先使用哪个内存区域、能否fallback到DMA或DMA32、是否允许跨NUMA节点,以及是否进入ZONE_MOVABLE。理解gfp_mask到zonelist的链路,是掌握内存分配器行为的关键,也是排查嵌入式系统、NUMA环境下“内存充足却分配失败”问题的核心。内核通过gfp_zone()将GFP标

weixin_33979203的博客 309

Linux内核gfp_mask到zonelist映射:内存分配优先级与fallback机制解析

Linux内核内存管理中,内存分配行为由gfp_mask标志位控制,而zonelist则决定了分配失败时的fallback顺序。gfp_mask中的zone相关位通过gfp_zone()映射为首选zone类型,build_zonelists()再根据NUMA节点距离和zone级别构建优先级链表。遍历分配时,get_page_from_freelist()沿zonelist依次检查水位并尝试分配,最终影响GFP_DMA为何优先低端内存、NUMA场景下本地节点优先等关键行为。掌握这一机制,开发者能深入理解内核页

weixin_34221654的博客 245
上一篇: Android联系人模块分析(二)
下一篇: Android联系人模块分析(三)
jiang_lostcode
博客等级 码龄18年 45粉丝 17原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值