今日重点:🏷️ 术语卡——前几篇术语卡学的是「一组互不相关的词」, 或者「一个概念的两个名字」。今天换个学法:一个词根长出来的一族词。 dma_buf 家族五个成员全都以 dma_ 开头,长得像亲兄弟, 但它们在句子里干的事完全不同。认角色,比背中文译名有用得多—— 因为翻译会变,角色不会。

📖 原文(真实定义,逐字引用)

/ section
This represents a shared buffer, created by calling dma_buf_export(). The userspace representation is a normal file descriptor, which can be created by calling dma_buf_fd().
This is a container for dma_fence objects which needs to handle multiple use cases.

出处:前一段取自内核树 include/linux/dma-buf.h 的 kerneldoc,后一段取自 include/linux/dma-resv.h。另有一支是今天刚被文档化的—— Pavel Begunkov 的 [PATCH v2 2/2] dma-buf-io: document dma_buf_io_init_map。 每条定义下方都给了溯源链接。

🏷️ 角色一:dma_buf —— 那个「东西」

/ column

★ dma_buf(共享缓冲区对象)

家族里唯一一个「实体」

原文定义 This represents a shared buffer, created by calling dma_buf_export(). The userspace representation is a normal file descriptor, which can be created by calling dma_buf_fd().
中文与角色 一个跨驱动共享的缓冲区对象。关键在第二句:它在用户态就是一个普通的文件描述符——所以用户态可以对它 read/write、可以传给别人、可以被 poll。它是这一族里唯一一个「东西」:其余四个都是围绕它派生出来的关系、状态或容器。
顺带一句,作者当场把两件事分开了 定义紧接着还有一句:Device DMA access is handled by the separate &struct dma_buf_attachment.(设备侧的 DMA 访问由另一个对象单独负责。)这句话就是这一族词的分界线:dma_buf 是「这块内存」,attachment 是「某设备对它的挂接」。
溯源 include/linux/dma-buf.h · git.kernel.org

🏷️ 角色二:dma_buf_attachment —— 那段「关系」

/ column

★ dma_buf_attachment(设备—缓冲区挂接)

一个设备一份,不是缓冲区的一部分

原文定义 This structure holds the attachment information between the dma_buf buffer and its user device(s). The list contains one attachment struct per device attached to the buffer. / An attachment is created by calling dma_buf_attach(), and released again by calling dma_buf_detach().
中文与角色 它描述的不是内存,而是「某个设备挂到了这块缓冲区上」这件事。注意 one attachment struct per device——一个设备一份,所以同一个 dma_buf 被三个设备用,就有三个 attachment。中文常译「附件」,但更准的理解是「挂接关系」:它存在的前提是两边都在。
为什么值得单独记 新手最容易把 attachment 当成缓冲区的一部分去理解,于是看不懂「为什么 detach 之后 buffer 还在」。东西和关系是两种生命周期——记住这一条,dma-buf 的一半代码就顺了。
溯源 include/linux/dma-buf.h · git.kernel.org

🏷️ 角色三:dma_fence —— 那份「同步」

/ column

★ dma_fence(软件同步原语)

回答「这件事做完了没」

原文定义 struct dma_fence - software synchronization primitive
中文与角色 内核里的软件同步原语。名字叫 fence(栅栏),语义是「跨过这道栅栏,说明前面的活儿干完了」——它不是数据,是一个完成信号。所以它既不描述内存也不描述设备,只描述进度。今天日报里 Rust 的 DRM JobQueue 那几封信全都在修 DmaFence 的生命周期,可见这一类对象最容易出错的地方就是「什么时候能把它释放掉」。
记忆钩子 看到 fence,问自己「这道栅栏拦的是什么操作」,而不是「它里面装了什么数据」。
溯源 include/linux/dma-fence.h · git.kernel.org

🏷️ 角色四:dma_resv —— 那个「容器」

/ column

★ dma_resv(预留对象 / reservation object)

把散落的 fence 收进一个对象

原文定义 This is a container for dma_fence objects which needs to handle multiple use cases.
中文与角色 内核原话就是 container for dma_fence objects——它是一个专门用来装 fence 的容器。一块缓冲区上可能同时排着好几个未完成的活儿(GPU 在渲染、显示控制器在读),这些 fence 需要一个地方统一管理,dma_resv 就是那个地方。名字里的 resv 来自 reservation(预留),因为它最早是从 TTM 显存管理里长出来的。
记忆钩子 这一族的角色分工可以一句话串起来:dma_buf 是东西,attachment 是关系,fence 是进度,resv 是装进度的盒子。
溯源 include/linux/dma-resv.h · git.kernel.org

🏷️ 角色五:dma_buf_io —— 今天新长出的一支

/ column

★ dma_buf_io / dma_buf_io_init_map(新支)

今天刚被文档化,是这一族的最新成员

原文定义 Importer's helper that initialises @map for the provided I/O context and scatter-gather table. The importer should call it once for each map on creation.
中文与角色 这一支解决的是「让 dma_buf 直接当 I/O 缓冲用」的场景(同一天还有 fs: support dma-buf backed direct I/O 和 nvme/io_uring: enable dma-buf backed passthrough I/O 两条 RFC 在推)。这里的 map 是一层新的映射对象,init_map 负责把它初始化好。注意定义里的 importer——dma-buf 世界把「提供缓冲的一方」叫 exporter、「使用缓冲的一方」叫 importer,这两个词值得单独记住。
怎么用 读新 API 的 kerneldoc 时,先找主语是谁:这里 Importer's helper 一句话就告诉你「这是给 importer 用的」,比读函数签名快。
溯源 今天的 docs 补丁 · lore.kernel.org

✨ 辅助彩蛋:backing —— 最难直译的一个词

/ section

★ backing scatter-gather table

别去查中文对应词,先问「它在支撑谁」

原句 @sgt: [in] the backing scatter-gather table
中文与语境 backing 直译是「背衬 / 支撑」,但它在内核英文里的实际含义是:在背后真正提供数据或存储的那个东西。同族还有 backing store(后端存储)、backing device(承载设备)、backing file(后备文件)。中文没有统一译法——硬译成「后端」在有些语境里会失真。值得留意的是这处措辞本身:同一个函数,描述句里写的是 the provided I/O context and scatter-gather table,而 @sgt 参数的说明里写的是 the backing scatter-gather table——同一个对象,正式描述里不加修饰,参数说明里才点明它是「底层支撑」。
怎么用 看到 backing,不要找中文对应词,直接问一句:它在支撑谁。写作时想说「底层那个 XX」,backing 往往比 underlying 更贴:underlying 强调层次关系,backing 强调「它在提供实质内容」。

✍️ 今日练习

/ column
✍️ 用今天这一族词回答三问(英文作答):① GPU 驱动要把一块 dma_buf 映射到自己的设备上做 DMA,它创建的是家族里哪个对象、用哪两个函数创建与释放?② 这块缓冲区上还排着别的驱动没做完的活,由哪个对象记录?它们的容器又是谁?③ 今天新文档化的那个函数,它的 @sgt 参数在注释里被称为什么(用原文的词)?
💡 显示答案
参考作答(仿写示范,非原文):① It creates a dma_buf_attachment -- the list contains one attachment struct per device attached to the buffer; it is created by dma_buf_attach() and released by dma_buf_detach(). ② The outstanding work is recorded as dma_fence objects, described in the header as a software synchronization primitive; the container that manages those fences for a buffer is the dma_resv, which the header defines as a container for dma_fence objects. ③ The @sgt parameter is documented as the backing scatter-gather table -- the function description itself says only "the provided I/O context and scatter-gather table".
📖 原文:Importer's helper that initialises @map for the provided I/O context and scatter-gather table. The importer should call it once for each map on creation. / @sgt: [in] the backing scatter-gather table
📎 原文引用

每日一句:When a family of names shares a root, learn the roles, not the translations — roles survive the next rename.

仿写示范