news 2026/10/2 13:53:13

tlb finish_asid_transition

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
tlb finish_asid_transition

finish_asid_transition是 AMD 广播 TLB 失效(Broadcast TLB Invalidation)补丁集中的关键同步函数。它的核心任务是:在完成一次广播 TLB 刷新后,确认所有正在运行该进程的 CPU 都已经切换到了新的全局 ASID,然后清除“ASID 过渡中”标志。

核心作用:确认过渡完成

当内核为某个多线程进程分配全局 ASID 后,该进程进入一个过渡期:部分 CPU 可能还在使用旧的本地 ASID,而另一部分 CPU 已经加载了新的全局 ASID。在这个过渡期内,所有 TLB 刷新都必须走广播路径(而非基于 IPI 的精确刷新),以确保仍在用旧 ASID 的 CPU 也能被正确刷新。

finish_asid_transition负责在过渡期结束时“收尾”:遍历mm_cpumask中的所有 CPU,确认它们都在使用全局 ASID,然后清除mm->context.asid_transition标志,宣告过渡完成。

代码逻辑解析

static void finish_asid_transition(struct flush_tlb_info *info) { struct mm_struct *mm = info->mm; int bc_asid = mm_global_asid(mm); int cpu; if (!READ_ONCE(mm->context.asid_transition)) return; for_each_cpu(cpu, mm_cpumask(mm)) { /* * The remote CPU is context switching. Wait for that to * finish, to catch the unlikely case of it switching to * the target mm with an out of date ASID. */ while (READ_ONCE(per_cpu(cpu_tlbstate.loaded_mm, cpu)) == LOADED_MM_SWITCHING) cpu_relax(); if (READ_ONCE(per_cpu(cpu_tlbstate.loaded_mm, cpu)) != mm) continue; /* * If at least one CPU is not using the global ASID yet, * send a TLB flush IPI. The IPI should cause stragglers * to transition soon. */ if (READ_ONCE(per_cpu(cpu_tlbstate.loaded_mm_asid, cpu)) != bc_asid) { flush_tlb_multi(mm_cpumask(info->mm), info); return; } } /* All the CPUs running this process are using the global ASID. */ WRITE_ONCE(mm->context.asid_transition, false); }

关键步骤:

  1. 快速退出:如果asid_transition已经为 false,说明过渡早已完成,直接返回。

  2. 遍历 CPU:对于mm_cpumask中的每个 CPU,检查它当前加载的 ASID 是否为全局 ASID(bc_asid)。

  3. 等待上下文切换完成:如果某个 CPU 正处于上下文切换中(loaded_mm == LOADED_MM_SWITCHING),函数会自旋等待。这是为了防止一种罕见但危险的竞态:CPU 正在切换到这个进程,但使用的是过期的 ASID。等待切换完成后,再判断它最终加载的是哪个 ASID。

  4. 发现“掉队者”:如果某个正在运行该进程的 CPU 仍在使用非全局 ASID,函数会发送一次 TLB 刷新 IPI(flush_tlb_multi),然后直接返回,不清除asid_transition标志。注释解释说:“IPI 应该会让掉队者很快完成过渡。”下一次广播 TLB 刷新时,finish_asid_transition会再次被调用,重新检查。

  5. 清除标志:只有当所有 CPU 都使用全局 ASID 时,才通过WRITE_ONCE将asid_transition置为 false,宣告过渡正式完成。

调用关系与设计意图

broadcast_tlb_flush() └── finish_asid_transition() // 在广播刷新完成后调用

finish_asid_transition由broadcast_tlb_flush调用,后者在处理flush_tlb_mm_range时,如果进程拥有全局 ASID,就走广播路径。

这个函数的“返回而不清标志”设计非常巧妙:它把过渡完成的确认与正常的 TLB 刷新流程解耦。过渡的完成不依赖于某一次特定的刷新操作,而是通过“检查-发送 IPI-再次检查”的循环逐步收敛。如果某次检查发现有 CPU 未跟上,就发 IPI 推它一把,然后等下一次广播刷新时再检查。这种设计避免了在 TLB 刷新路径中引入复杂的等待或同步逻辑,同时保证了最终一致性。

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

西安本地中小商户的线上获客:从付费投放看长期数字资产

这两年我在陕西正方元网络科技有限公司做本地数字化服务,日常打交道的多是西安本地的实体门店和中小企业经营者。下面是一个不算新鲜的观察:越是把获客全部押在付费投放上的商家,越容易在停投之后感到被动。一、传统本地线上运营的现存痛点西…

作者头像 李华
网站建设 2026/10/2 13:52:22

后台扫描器用什么节奏发现位腐:30 天这个数字怎么读

一块盘写入时是好的,三个月后读出来才发现中间有几位变成了别的。这种损坏在写入路径上永远不会被发现,因为写进去的那个字节就是坏的那个。能发现它的只有一条路:在没人读写的时候,把数据重新读一遍、算一遍校验。RustFS 的后台扫…

作者头像 李华
网站建设 2026/10/2 13:52:10

STM32F767ZG+DRV8818PWPR步进电机控制方案:从选型到调试全解析

做机器人运动控制这些年,我最常被问到的问题其实是:在预算有限、又要保证现场稳定性的工业和机器人项目里,步进电机这套方案到底还能不能扛?我的回答通常很直接:能,但前提是选对驱动器和控制核心。我现在不…

作者头像 李华
网站建设 2026/10/2 13:51:51

一文搞懂LangChain vs LlamaIndex,大模型应用框架怎么选?

本文对比了LangChain和LlamaIndex两大框架的核心定位与优势。LangChain擅长Agent、工作流编排和工具调用,适合复杂任务编排;LlamaIndex则专注于文档索引、知识库检索和RAG优化,助力模型精准“查资料”。文章通过实战案例演示了如何在LangChai…

作者头像 李华
网站建设 2026/10/2 13:51:06

AccessDatabaseEngine_X64与Office 2007冲突:从检测原理到安装解决路径

简介:针对在六十四位Windows 7系统下安装三十二位Office 2007后,再安装六十四位AccessDatabaseEngine 2010时常遇到的安装冲突问题,这份资源提供了一套可行的解决思路,尤其适合IT运维、系统管理员以及需要同时使用Office与Access数…

作者头像 李华
网站建设 2026/10/2 13:50:23

短视频链接解析实战:从MD5签名到Python爬虫实现

做短视频链接解析接口,听起来像是个挺小众的需求,但真正写起来,你会发现它几乎涵盖了爬虫入门到进阶的所有经典要素:链接处理、正则提取、参数拼接、MD5签名、请求伪造、异常兜底。我最早接触这个案例的时候,纯粹是因为…

作者头像 李华