news 2026/4/24 10:43:59

Linux 内存管理:TLB ASID

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux 内存管理:TLB ASID

文章目录

  • 1. 前言
  • 2. TLB ASID 的硬件支持
    • 2.1 概念
    • 2.2 TLB 查找
  • 3. Linux 下 TLB ASID 管理
  • 4. 参考资料

1. 前言

限于作者能力水平,本文可能存在谬误,因此而给读者带来的损失,作者不做任何承诺。

2. TLB ASID 的硬件支持

2.1 概念

  • 什么是TLB
    TLBTranslation Lookaside Buffers的缩写,MMU 将虚拟地址(VA)翻译为物理地址(PA)时,要经过页表遍历(page table walk)过程,每访问一级页表就要一次内存访问,相对来说,这个延迟还是相对较大的。为了提高性能,硬件上引入了 TLB cache 缓存,首次访问一个 VA 后,将 MMU 转换的 PA 以对应的 VA 为 tag 缓存到 TLB 缓存,下次再访问同一 VA,就可以通过以 VA 为 tag 从 TLB 搜索提取对应的 TLB entry 了,不用再经历漫长的page table walk过程。当然,TLB 的容量有限,只能缓存有限个数 VA 翻译的 PA 地址,这就需要做一定的管理,在 TLB 耗尽时,通过某种算法,用新的 PA 将一些旧的缓存替换掉。

  • 什么是 TLB ASID?
    ASIDAddress Space Identifier的缩写,标识属于特定进程的TLB entries。那为什么需要它?前面说过,TLB 容量有限,在系统中属于珍贵资源;另外,在系统进程的切换过程中,会进行页表切换,而每个进程的页表不一样,那意味着,当前进程的 TLB 缓存的地址翻译内容,对新进程将失效,所以页表切换需要进行整个 TLB cache 的 flush,这会带来不小的性能损失。于是硬件上引入了nG(not Global)标志位 和ASID,来对该问题进行优化:nG=0标识 TLB entries 属于 ASID 标识的进程,nG=1标识 TLB entries 属于全局的内核空间地址(所有进程共享内核空间的页表映射)。这样,在切换进程的页表时候,只需要为新进程分配一个 ASID 来标识自己的 TLB entries,在 ASID 或 TLB cache entries 消耗完之前,都不需要刷 TLB cache 了。

2.2 TLB 查找

nG标志位同时位于最后一级页表的表项TLB entries中,然后首次内存访问某个地址时,记录到 TLB entries 中。而当前进程的ASID,会在进程页表切换时设置到TTBRx寄存器中,同时也会在首次访问某个VA地址时,记录到TLB entries中。当然,TLB entries 也记录访问VA地址的VA tag。这样,在后续访问某一VA地址时,首先比较 VA 地址 TLB entries VA tag,如果不匹配,则表示 TLB miss,要继续进行page table walk来翻译PA;如果相同,则继续查看 TLB entry 的nG位,如果为nG=0,则意味着是内核空间地址的 TLB entry,所有进程共享,即命中了 TLB,返回 TLB entry 保存的PA即可;如果nG=1,则表示是某进程特定的 TLB entry,通过 ASID 标识,则继续比较 TLB entry 的 ASID 和 TTBRx 寄存器存储的当前进程的 ASID,如果值相同,则标识命中,否则标识 TLB miss,否则要继续进行page table walk来翻译PA

3. Linux 下 TLB ASID 管理

ARMv7架构 +Linux 4.14.x内核简略的分析下TLB ASID的管理细节,来看代码:

typedefstruct{#ifdefCONFIG_CPU_HAS_ASIDatomic64_tid;/* ASID: generation | HW ASID */#else...#endif...}mm_context_t;
voidcheck_and_switch_context(structmm_struct*mm,structtask_struct*tsk){unsignedlongflags;unsignedintcpu=smp_processor_id();u64 asid;...asid=atomic64_read(&mm->context.id);/* 读取新进程的 ASID *//* * a. !((asid ^ atomic64_read(&asid_generation)) >> ASID_BITS * 新进程 asid 属于/分配自 当前 generation * b. atomic64_xchg(&per_cpu(active_asids, cpu), asid) * a.成立的条件下, 顺便设定 当前 CPU 激活的 (进程的) asid, * 然后就可以进入页表的切换过程了. */if(!((asid^atomic64_read(&asid_generation))>>ASID_BITS)&&atomic64_xchg(&per_cpu(active_asids,cpu),asid))gotoswitch_mm_fastpath;/* ASID 无需更新,直接进入页表切换过程 */raw_spin_lock_irqsave(&cpu_asid_lock,flags);/* Check that our ASID belongs to the current generation. */asid=atomic64_read(&mm->context.id);/* 新进程 asid 不 属于/分配自 当前 generation, 要重新从当前 generation 为新进程分配 asid */if((asid^atomic64_read(&asid_generation))>>ASID_BITS){asid=new_context(mm,cpu);/* ASID 管理操作 */atomic64_set(&mm->context.id,asid);/* 为 进程 分配的 ASID 记录到 进程的 mm_struct */}/* 当前 generation ASID 耗尽,需要刷掉所有的 TLB cache */if(cpumask_test_and_clear_cpu(cpu,&tlb_flush_pending)){local_flush_bp_all();local_flush_tlb_all();}atomic64_set(&per_cpu(active_asids,cpu),asid);/* 当前 CPU 激活的 (进程的) asid */cpumask_set_cpu(cpu,mm_cpumask(mm));raw_spin_unlock_irqrestore(&cpu_asid_lock,flags);}staticu64new_context(structmm_struct*mm,unsignedintcpu){staticu32 cur_idx=1;u64 asid=atomic64_read(&mm->context.id);u64 generation=atomic64_read(&asid_generation);/* * 在创建新的进程的时候会分配一个新的 mm, 其(mm->context.id)初始化为 0. * 如果 asid 不等于 0, 那么说明这个 mm 之前就已经分配过 software asid * (generation + hw asid)了. */if(asid!=0){u64 newasid=generation|(asid&~ASID_MASK);/* * If our current ASID was active during a rollover, we * can continue to use it and this was just a false alarm. */if(check_update_reserved_asid(asid,newasid))returnnewasid;/* * We had a valid ASID in a previous life, so try to re-use * it if possible., *//* 如果新 generation 中旧的 asid 还未被分配出去, 重用它 */asid&=~ASID_MASK;if(!__test_and_set_bit(asid,asid_map))returnnewasid;/* 返回更新了 generation 的 asid */}/* * 如果 asid 等于 0, 说明我们的确是需要分配一个新的 HW asid, * 这时候首先要找一个空闲的 HW asid, 如果能够找到, 那么直接返 * 回 software asid (当前 generation + 新分配的 hw asid); 否则, * 表示 asid 消耗完了,生成新的 generation 并重新进行分配??? */asid=find_next_zero_bit(asid_map,NUM_USER_ASIDS,cur_idx);if(asid==NUM_USER_ASIDS){/* ASID 消耗完了,需重新分配 */generation=atomic64_add_return(ASID_FIRST_VERSION,&asid_generation);/* 递增 ASID generation */flush_context(cpu);asid=find_next_zero_bit(asid_map,NUM_USER_ASIDS,1);}__set_bit(asid,asid_map);/* 更新 ASID 分配位图: 标记 asid 已经被分配 */cur_idx=asid;cpumask_clear(mm_cpumask(mm));returnasid|generation;/* 返回新分配的 asid */}staticvoidflush_context(unsignedintcpu){inti;u64 asid;/* Update the list of reserved ASIDs and the ASID bitmap. */bitmap_clear(asid_map,0,NUM_USER_ASIDS);for_each_possible_cpu(i){asid=atomic64_xchg(&per_cpu(active_asids,i),0);/* * If this CPU has already been through a * rollover, but hasn't run another task in * the meantime, we must preserve its reserved * ASID, as this is the only trace we have of * the process it is still running. */if(asid==0)asid=per_cpu(reserved_asids,i);__set_bit(asid&~ASID_MASK,asid_map);per_cpu(reserved_asids,i)=asid;}/* Queue a TLB invalidate and flush the I-cache if necessary. */cpumask_setall(&tlb_flush_pending);/* 当前 generation 的 asid 耗尽, 更新 generation, 标记要刷 TLB */if(icache_is_vivt_asid_tagged())__flush_icache_all();}

4. 参考资料

[1] DDI0406C_d_armv7ar_arm.pdf
[2] TLB原理

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/24 6:49:33

langchain agent动态变更系统prompt

一.背景 LangChain Agent 作为大语言模型(LLM)驱动的智能体核心,** 系统 Prompt(提示词)** 是其行为准则与决策逻辑的 “顶层设计”—— 它定义了 Agent 的角色定位(如 “智能客服”“数据分析师”&#xf…

作者头像 李华
网站建设 2026/4/23 12:45:55

springboot+jspm电力监测报修服务平台_34gate3m

目录已开发项目效果实现截图开发技术介绍系统开发工具:核心代码参考示例1.建立用户稀疏矩阵,用于用户相似度计算【相似度矩阵】2.计算目标用户与其他用户的相似度系统测试总结源码文档获取/同行可拿货,招校园代理 :文章底部获取博主联系方式&…

作者头像 李华
网站建设 2026/4/22 10:29:08

基于PSO - BP的时间序列预测:一键出图的奇妙之旅

基于粒子群优化算法优化BP神经网络(PSO-BP)的时间序列预测 PSO-BP时间序列 一键出图,只需替换成自己数据集即可,有教程。在数据的海洋中,时间序列预测一直是众多领域关注的焦点。今天咱就唠唠基于粒子群优化算法(PSO)优…

作者头像 李华
网站建设 2026/4/18 3:28:19

LAMMPS-VMD耦合:基于tcl语言反应力场分析化学键生成的成键数目研究工具

LAMMPS反应力场分子动力学模拟成键分析程序 基于vmd的tcl语言脚本支持反应力场原子成键数目分析。 主要用于统计化学反应涉及化学键生成和断裂的体系,比如煤燃烧,石墨烯合成过程等等。 用法简单,指定待计算的元素对即可得到对应键数目随模拟时…

作者头像 李华
网站建设 2026/4/22 15:34:14

ASO优化如何“顺时而为”?从节日到四季的全年优化指南

应用商店优化 (ASO) 中的季节性因素包括新年、圣诞节、情人节、万圣节、黑色星期五、网络星期一…… 能够提升应用流量的机会数不胜数。再加上体育赛季的开始、电视剧的首播、大型促销活动以及当地的节日——所有这些因素加起来,就构成了我们所说的:季节…

作者头像 李华
网站建设 2026/4/18 3:34:52

飞算JavaAI一键修复器:漏洞自动检测+精准修复,告别手动踩坑

在Java开发领域,代码安全始终是开发者不可逾越的核心议题。然而,随着项目规模持续扩大、业务逻辑日渐复杂,代码中的安全漏洞也随之滋生,给项目稳定运行埋下隐患。通用AI模型虽能识别部分常见漏洞代码模式,但在提供可直…

作者头像 李华