最新资讯

  • [Linux]学习笔记系列 -- [drivers][dma]dma-buf

[Linux]学习笔记系列 -- [drivers][dma]dma-buf

2026-01-30 08:39:13 栏目:最新资讯 6 阅读


title: dma-buf
categories:

  • linux
  • drivers
  • dma
    tags:
  • linux
  • drivers
  • dma
    abbrlink: 1d3fd482
    date: 2025-10-03 09:01:49

https://github.com/wdfk-prog/linux-study

文章目录

  • Linux 内核 dma-buf 核心实现(drivers/dma-buf/dma-buf.c)全面解析
  • [drivers/dma-buf/dma-buf.c] [dma-buf 共享缓冲区框架核心] [跨子系统/设备共享 DMA 缓冲区 + 同步与 CPU 访问支持的核心对象与文件接口]
    • 介绍
    • 历史与背景
      • 这项技术是为了解决什么特定问题而诞生的?
      • 发展里程碑或版本迭代(从代码/文档可直接看到的能力点)
      • 社区活跃度与主流应用情况
    • 核心原理与设计
      • 核心工作原理是什么?
      • 主要优势体现在哪些方面?
      • 劣势、局限性或不适用性
    • 使用场景
      • 首选场景(举例)
      • 不推荐使用的场景(原因)
    • 对比分析
      • 1) dma-buf vs “普通共享内存/文件(memfd/shm/tmpfs)”
      • 2) dma-buf vs “每设备独立分配 + 自定义传递”
      • 3) dma-buf vs dma-heap(补充理解边界)
    • 总结
      • 关键特性
    • `dma-heap` 与 `dma-buf` 的职责关系:分配入口/内存池策略 vs 共享对象/语义核心
      • 1) `dma-buf` 是“共享对象与语义核心”
      • 2) `dma-heap` 更像“面向用户态申请 dma-buf 的分配入口/内存池策略”
      • 3) 两者如何“经常一起出现”
  • DMA-BUF 初始化与生命周期管理:`dma_buf_init` / `dmabuffs_dname` / `dma_buf_release` / `dma_buf_file_release`
    • `dma_buf_init`: 在子系统初始化阶段建立 dma-buf 的 sysfs/debugfs 与伪文件系统挂载
    • `dmabuffs_dname`: 为 dma-buf dentry 动态生成可读的路径名称
    • `dma_buf_release`: dentry 释放时销毁 dma-buf 对象并回收所有关联资源
    • `dma_buf_file_release`: dma-buf 文件关闭路径中的全局列表摘除
  • drivers/dma-buf/dma-fence.c DMA Fence(DMA 栅栏)同步机制
    • 介绍
      • 历史与背景
        • 这项技术为了解决什么问题而诞生
        • 重要里程碑或迭代点(从源码注释与近期讨论归纳)
        • 社区活跃度与主流应用情况
      • 核心原理与设计
        • 核心工作原理
        • 主要优势
        • 已知劣势、局限性与不适用点
      • 使用场景
        • 首选场景(举例)
        • 不推荐使用的场景
      • 对比分析
    • 总结
      • 关键特性
    • `dma_fence_init_stub`: 初始化并立即完成一个全局 stub fence,用于提供可用的默认同步对象
      • 核心原理概述
    • `__dma_fence_init` / `dma_fence_init`: 初始化 dma_fence 的身份、并发保护与回调容器
      • 核心原理概述
    • `dma_fence_signal_timestamp_locked` / `dma_fence_signal_timestamp` / `dma_fence_signal_locked` / `dma_fence_signal`: 以原子方式将 fence 从“未完成”转换为“已完成”,并执行回调链

Linux 内核 dma-buf 核心实现(drivers/dma-buf/dma-buf.c)全面解析

[drivers/dma-buf/dma-buf.c] [dma-buf 共享缓冲区框架核心] [跨子系统/设备共享 DMA 缓冲区 + 同步与 CPU 访问支持的核心对象与文件接口]

介绍

dma-buf 子系统提供一种跨多个驱动/子系统共享同一块底层缓冲区的内核框架,并配套处理异步硬件访问的同步(基于 dma-resv/dma-fence)以及CPU 访问一致性(begin/end CPU access、mmap、poll/notify 等)。官方文档把其定位为:共享用于硬件(DMA)访问的缓冲区,并同步异步硬件访问。
drivers/dma-buf/dma-buf.c 则是**dma-buf 核心对象(struct dma_buf)与其“文件描述符语义”**的主要实现:全局跟踪、fd 导出、attachment 管理、map/unmap、CPU access、poll、ioctl 等。


历史与背景

这项技术是为了解决什么特定问题而诞生的?

在图形、多媒体、相机、编解码等场景中,常见“一个子系统分配 buffer,另一个子系统/设备使用同一 buffer 做 DMA”。若各驱动各自定义共享方式,会导致:

  • 缓冲区传递机制碎片化(每对驱动一套接口)
  • 同步机制不统一(谁负责等待/信号?)
  • 缓冲区生命周期难以管理(引用计数/关闭 fd/释放顺序)

dma-buf 用统一的文件描述符(fd)载体来传递 buffer,并用 dma-resv/dma-fence 体系做隐式同步,降低跨子系统互操作成本。

发展里程碑或版本迭代(从代码/文档可直接看到的能力点)

不在这里强行给出“某版本引入某特性”的时间线(那需要进一步查 git log 才严谨),但从当前主线实现可确认这些关键能力已经稳定存在:

  • 全局 dma-buf 列表与迭代接口dmabuf_list + dma_buf_iter_begin()/dma_buf_iter_next(),并强调 list mutex 不保护 refcount,需要 file_ref_get() 方式安全拿引用。)
  • 明确的锁定约定:文档化说明“哪些 API 调用方必须/必须不持有 reservation lock”,将 deadlock 风险前置到接口契约层。)
  • map_attachment 路径集成 pin 语义dma_buf_map_attachment()might_sleep()dma_resv_assert_held(),并在需要时走 ops->pin(),对导出者错误行为做 WARN。)
  • CPU 访问路径显式等待隐式 fence:在 dma_buf_begin_cpu_access() 相关逻辑里,会等待隐式渲染 fences(通过 dma_resv_wait_timeout)。)
  • 官方文档持续更新(发布时间为近一周),说明仍是活跃维护的主流框架。

社区活跃度与主流应用情况

dma-buf 是 Linux 图形/多媒体栈里的核心基础设施,DRM、V4L2 等广泛依赖它进行 buffer 交换与同步(官方文档也明确点到这些典型使用)。


核心原理与设计

核心工作原理是什么?

可以按“对象模型 + 文件语义 + 同步模型 + 映射模型”来理解:

  1. 对象模型:struct dma_buf 作为共享对象
  • 导出者(exporter)实现 struct dma_buf_ops,决定底层内存如何分配、如何 map 成 sg_table、如何处理 CPU access 等。
  • 导入者(importer/user)通过 attachment 把该 dma-buf 绑定到某个设备,再把它映射成该设备可 DMA 的形式。
  1. 文件语义:dma-buf 作为 fd 传递
  • dma-buf 通过匿名 inode/伪文件系统的 file 对象呈现为 fd,从而在进程/子系统之间传递。代码中可以看到创建 pseudo file 的路径(alloc_file_pseudo),并设置 inode size 等信息。)
  • 代码维护全局 dmabuf 列表,并提供迭代:迭代时需要安全地“提升引用计数以防销毁”。)
  1. 同步模型:dma-resv / dma-fence 隐式同步
  • dma-buf 的 resv(reservation object)聚合 fences:读/写访问顺序由 fences 表达。
  • CPU 访问路径会等待隐式 fences,确保 CPU 读写看到一致数据(至少在指定范围/方向语义内)。)
  1. 映射模型:attachment + map/unmap
  • dma_buf_map_attachment() 要求调用方持有 reservation lock(代码里 dma_resv_assert_held),并可能 sleep。)
  • 它通过 exporter 的 ops->map_dma_buf() 返回 sg_table,供设备 DMA 使用;并在需要时结合 pin 语义提升“底层存储不可迁移/可访问性”约束。)
  1. 锁定约定(非常关键)
    源码中专门列出导入者约定:例如 dma_buf_map_attachment()/vmap() 这类需要持有 reservation lock,而 dma_buf_attach()/export()/fd/get/put 等则要求不持有。这个约定是排查死锁的第一优先级依据。)

主要优势体现在哪些方面?

  • 跨子系统统一共享模型:fd 传递 + 统一 attachment/map 语义,降低耦合(官方文档描述的核心目标)。
  • 统一的隐式同步基础设施:围绕 dma-resv/dma-fence 组织同步,CPU 访问路径也能通过等待 fences 保证一致性。)
  • 明确的调用方锁约束:把“谁持锁调用什么”写进契约,降低系统集成时的不可控并发问题。)

劣势、局限性或不适用性

  • 复杂度高:必须正确处理 exporter/importer 角色、reservation lock、fence 语义、CPU access begin/end、mmap/ioctl/poll 等一整套机制;错误通常表现为隐式同步失效或死锁。)
  • 不是“通用共享内存”接口:它面向 DMA buffer 共享与同步;若只是 CPU 侧共享数据结构,可能更适合其他 IPC/共享内存机制(取决于需求)。这一点需要你基于目标场景做判断。
  • 关键路径可能 sleep:例如 dma_buf_map_attachment() 明确 might_sleep(),因此调用上下文要满足可睡眠条件。)

使用场景

首选场景(举例)

  • DRM ↔ V4L2 / 编解码器 / ISP / 显示:图形与多媒体流水线中,一个组件产出帧缓冲,另一个组件消费;dma-buf 用 fd 传递 buffer,fence 做隐式同步,是典型路径(官方文档点名 DRM、V4L2 等互通)。
  • 跨设备共享同一底层存储:例如 GPU 渲染结果直接给显示/视频编码设备 DMA 使用,通过 attachment/map 取 sg_table。

不推荐使用的场景(原因)

  • 不涉及 DMA 的纯 CPU 数据共享:dma-buf 引入的同步/映射语义与实现复杂度可能是负担。
  • 无法接受隐式同步模型的系统:如果你需要显式控制每一步同步、或系统中同步策略与 dma-resv 机制冲突,使用 dma-buf 可能会增加调试难度(需要你对 fence/resv 语义非常熟)。

对比分析

这里选 3 类“相似但定位不同”的技术路线做对比(你学习时容易混淆的点):

1) dma-buf vs “普通共享内存/文件(memfd/shm/tmpfs)”

  • 实现方式

    • dma-buf:面向 DMA 缓冲区共享,核心是 exporter ops + attachment + sg_table + fence/resv。
    • memfd/shm:面向 CPU 地址空间共享,不提供统一的设备 DMA 映射与隐式同步语义。
  • 性能开销

    • dma-buf:在 map/unmap、同步等待、poll/notify 上有额外机制成本,但换来跨设备共享与正确同步。)
  • 资源占用

    • dma-buf:底层存储由 exporter 决定(可能是 pages、carveout、IOMMU 映射等),并伴随 resv/fence 元数据。
  • 隔离级别

    • dma-buf:以 fd 为句柄,权限由 fd 传递控制;设备访问能力通过 attachment 绑定设备。
  • 启动速度

    • dma-buf:建立共享关系通常要 export→fd→get→attach→map,多步骤;但这是为了明确控制共享与同步。

2) dma-buf vs “每设备独立分配 + 自定义传递”

  • dma-buf 的主要优势就是避免 N×M 的私有接口组合;并统一同步。
  • 代价是所有参与者都要遵循锁定约定与同步模型,否则系统性问题更隐蔽。)

3) dma-buf vs dma-heap(补充理解边界)

  • dma-heap 更像“面向用户态申请 dma-buf 的分配入口/内存池策略”,而 dma-buf.c 是“共享对象与语义核心”。两者经常一起出现,但职责不同。你在继续读源码时会很快感受到这一点(drivers/dma-buf/dma-heap.c 是另一条线)。

总结

关键特性

  • dma_buf 作为可通过 fd 传递的共享 DMA 缓冲区对象,并支持跨设备 attachment、映射为 sg_table。
  • dma-resv/dma-fence 为核心的隐式同步,CPU 访问路径会等待相关 fences。)
  • 明确的锁定约定,是正确使用与排障的第一要点。)
  • 核心实现还包含全局列表迭代、poll 支持、命名与统计等工程性能力。

dma-heapdma-buf 的职责关系:分配入口/内存池策略 vs 共享对象/语义核心

1) dma-buf 是“共享对象与语义核心”

dma-buf.c 这类代码主要在做两件事:

  • 定义共享对象 struct dma_buf 的生命周期与规则
    例如:引用计数、release 路径、attachments 管理、fence/同步语义、统计与 debug 导出等。
  • 提供跨驱动共享的通用接口
    例如:导出(export)、导入(attach/map/detach)、文件描述符关联、dentry/vfs 相关回调等。

也就是说:
dma-buf 不关心“这块内存来自哪个池子、怎么分配出来的”,它关心的是:
一旦你给我一个 buffer,我怎么把它变成一个可共享、可同步、可回收的‘共享对象’


2) dma-heap 更像“面向用户态申请 dma-buf 的分配入口/内存池策略”

dma-heap 的定位更偏“上游入口 + 策略”:

  • 它提供给用户态一个标准入口(通常是 /dev/dma_heap/ 这样的设备节点)
    用户态通过 ioctl 之类请求“给我分配一个 dma-buf”。
  • 它把“分配策略”抽象成不同 heap
    例如:system heap、cma heap、carveout heap(具体有哪些取决于内核实现/配置)。
  • 它最终会创建一个 dma-buf(或者包装成 dma-buf 导出的对象)返回给用户态。

也就是说:
dma-heap 的职责是:
决定从哪里分配、用什么策略分配、给用户态一个可用的 dma-buf fd


3) 两者如何“经常一起出现”

典型链路(概念上)是:

  1. 用户态:打开某个 heap 设备节点,请求分配
  2. dma-heap:选择对应 heap 的分配器,分配物理/页面/SG 列表等底层内存
  3. dma-heap:把分配结果“导出”为一个 dma-buf 对象(绑定 ops,形成共享语义)
  4. 返回给用户态:一个 dma-buf 的 fd
  5. 后续共享:别的驱动/子系统通过 dma-buf attach/map 等使用同一份底层内存

这里的分工就是:

  • dma-heap:分配与池化策略(入口、选择、分配)
  • dma-buf:共享与生命周期语义(对象、同步、引用、回收)

DMA-BUF 初始化与生命周期管理:dma_buf_init / dmabuffs_dname / dma_buf_release / dma_buf_file_release

先说明适用边界(与你要求的 STM32H750 单核无 MMU 视角直接相关):
这段代码属于 Linux 内核 dma-buf 子系统 + VFS(挂载、dentry、文件释放)+ sysfs/debugfs。它依赖内核的挂载体系、dentry 生命周期、模块引用计数、以及通常与虚拟内存映射相关的约束(例如 vmapping_counter)。因此在 STM32H750(ARMv7-M、无 MMU、裸机/RTOS) 场景中无法直接运行;但其中的“资源生命周期一致性”“引用计数与不变量检查”“并发保护(spinlock)”思想仍可用于你在嵌入式驱动/中间件里设计资源管理。


dma_buf_init: 在子系统初始化阶段建立 dma-buf 的 sysfs/debugfs 与伪文件系统挂载

此函数是dma-buf 子系统的启动入口,通过 subsys_initcall 在内核子系统初始化阶段执行。它的核心动作是:

  1. 初始化统计 sysfs 节点dma_buf_init_sysfs_statistics() 负责把 dma-buf 的统计信息以 sysfs 形式对外发布(失败即直接退出,避免半初始化状态)。
  2. 挂载 dma-buf 专用伪文件系统kern_mount(&dma_buf_fs_type) 创建并挂载一个仅供内核使用的 mount,用于承载 dma-buf 的匿名文件/dentry 管理(这是后续 dentry 回调能够生效的前提)。
  3. 初始化 debugfsdma_buf_init_debugfs() 用于调试信息导出;此处不影响核心功能但方便定位问题。

该函数体现的关键技巧是:把一个核心资源(dma_buf_mnt 挂载点)作为全局根对象建立起来,后续所有 dma-buf 文件对象的 dentry 生命周期都依赖它。


dmabuffs_dname: 为 dma-buf dentry 动态生成可读的路径名称

此函数是 dentry 的 .d_dname 回调,用于按需生成 dentry 的显示名称。其核心机制是:

  1. dentry->d_fsdata 取回 struct dma_buf:驱动/子系统把私有对象指针挂在 dentry 上,VFS 回调时再取回,这是典型的“对象挂接”模式。
  2. spin_lock 保护 name 读取dmabuf->name 可能被并发更新或释放,因此通过 dmabuf->name_lock 在读取期间保持一致性。
  3. 使用 dynamic_dname 输出格式化名称:返回值不是静态缓冲区,而是通过 dynamic_dname 在 VFS 需要时格式化输出(避免长期保存字符串导致额外生命周期管理复杂度)。

dma_buf_release: dentry 释放时销毁 dma-buf 对象并回收所有关联资源

此函数是 dentry 的 .d_release 回调,是 dma-buf 对象最终销毁路径 的关键部分。它的核心原则是:在释放前强制验证不变量,防止“仍在使用的对象被释放”

关键点(只讲关键技巧,不讲“代码怎么跑”的基础):

  1. 不变量检查(BUG_ON)

    • BUG_ON(dmabuf->vmapping_counter);:要求不存在仍在进行的 vmap 映射计数,否则释放会导致地址空间/引用悬挂。
    • BUG_ON(dmabuf->cb_in.active || dmabuf->cb_out.active);:要求不存在仍活跃的 fence 回调状态,否则说明异步完成路径存在引用不平衡或状态机错误。
  2. 先拆统计与驱动资源,再拆通用资源

    • dma_buf_stats_teardown(dmabuf):撤销统计信息,避免 sysfs/debugfs 仍引用已释放对象。
    • dmabuf->ops->release(dmabuf):调用导出方提供的 release,释放与底层 exporter 相关的资源。
  3. 处理内嵌 resv 对象的析构

    • dmabuf->resv 指向 &dmabuf[1](即紧随主结构体的内嵌对象),则需要 dma_resv_fini() 做对象析构。
  4. 确保附件链表为空并维护模块引用计数

    • WARN_ON(!list_empty(&dmabuf->attachments));:释放时不应仍有 attachment。
    • module_put(dmabuf->owner);:归还 exporter 模块引用,保证模块可卸载性与引用一致性。
  5. 最终释放内存:释放 name 字符串与 dmabuf 本体。


dma_buf_file_release: dma-buf 文件关闭路径中的全局列表摘除

此函数是 file 的释放路径(通常由 file_operations->release 触发),它的核心动作很集中:

  1. is_dma_buf_file(file):确认该 file 确实是 dma-buf 文件,避免误删。
  2. __dma_buf_list_del(file->private_data):从 dma-buf 的全局跟踪链表中移除该对象(属于“框架侧 bookkeeping”)。

/**
 * @brief dma-buf 子系统初始化入口函数
 *
 * 通过 subsys_initcall 在内核子系统初始化阶段执行,用于:
 * - 初始化 sysfs 统计导出
 * - 挂载 dma-buf 伪文件系统并保存挂载点
 * - 初始化 debugfs 调试导出
 *
 * @return 成功返回 0,失败返回负错误码
 */
static int __init dma_buf_init(void) /* 子系统初始化函数,仅在 init 阶段使用 */
{
	int ret; /* 保存各初始化步骤的返回值 */

	/* 初始化 dma-buf 统计的 sysfs 导出;失败则终止,避免进入半初始化状态 */
	ret = dma_buf_init_sysfs_statistics(); /* 建立 sysfs 统计节点 */
	if (ret) /* 若失败则直接返回错误码 */
		return ret; /* 向上层传播错误 */

	/* 挂载 dma-buf 的伪文件系统;该挂载点承载 dma-buf 文件对象的 dentry 生命周期 */
	dma_buf_mnt = kern_mount(&dma_buf_fs_type); /* 创建并挂载内核私有 mount */
	if (IS_ERR(dma_buf_mnt)) /* 若挂载返回错误指针 */
		return PTR_ERR(dma_buf_mnt); /* 返回对应负错误码 */

	/* 初始化 debugfs 导出;用于调试观测,不影响核心功能语义 */
	dma_buf_init_debugfs(); /* 建立 debugfs 节点 */
	return 0; /* 初始化成功 */
}
subsys_initcall(dma_buf_init); /* 指定在 subsys 初始化阶段调用 dma_buf_init */

/**
 * @brief 生成 dma-buf dentry 的动态显示名称
 *
 * 该函数被 VFS 在需要展示 dentry 名称时调用,通过 dentry->d_fsdata 取回 dmabuf,
 * 并在 name_lock 保护下读取 dmabuf->name,最终使用 dynamic_dname 格式化输出。
 *
 * @param dentry 需要生成名称的目录项
 * @param buffer 输出缓冲区
 * @param buflen 输出缓冲区长度
 * @return 返回由 dynamic_dname 生成的名称指针
 */
static char *dmabuffs_dname(struct dentry *dentry, char *buffer, int buflen)
{
	struct dma_buf *dmabuf; /* dma-buf 核心对象指针(挂在 dentry->d_fsdata) */
	char name[DMA_BUF_NAME_LEN]; /* 临时名称缓冲,用于拷贝 dmabuf->name */
	ssize_t ret = 0; /* strscpy 返回值:>0 表示成功拷贝长度,<=0 表示失败或空 */

	/* 从 dentry 私有数据取回 dmabuf 对象 */
	dmabuf = dentry->d_fsdata; /* d_fsdata 由创建 dentry 时设置,指向 struct dma_buf */

	/* 读取 dmabuf->name 需要并发保护,避免与更新/释放竞争 */
	spin_lock(&dmabuf->name_lock); /* 自旋锁保护 name 指针与其内容的一致性 */
	if (dmabuf->name) /* 若名称存在则拷贝到本地缓冲 */
		ret = strscpy(name, dmabuf->name, sizeof(name)); /* 拷贝名称,避免直接暴露指针生命周期 */
	spin_unlock(&dmabuf->name_lock); /* 结束保护区 */

	/* 生成形如 "/:" 的动态名称;若无 dmabuf->name 则使用空串 */
	return dynamic_dname(buffer, buflen, "/%s:%s",
			     dentry->d_name.name, ret > 0 ? name : ""); /* ret>0 才认为 name 有效 */
}

/**
 * @brief dentry 释放回调:销毁 dma-buf 对象并回收资源
 *
 * 该回调在 dentry 生命周期结束时触发。释放前必须满足关键不变量:
 * - 不存在仍在进行的 vmap 计数
 * - 不存在仍活跃的回调状态(cb_in/cb_out)
 * - attachments 列表应为空(否则说明仍被外部持有)
 *
 * @param dentry 被释放的目录项
 */
static void dma_buf_release(struct dentry *dentry)
{
	struct dma_buf *dmabuf; /* 待释放的 dma-buf 对象 */

	/* 从 dentry 私有数据取回 dmabuf */
	dmabuf = dentry->d_fsdata; /* d_fsdata 指向 struct dma_buf */
	if (unlikely(!dmabuf)) /* 若为空则无需处理(防御性检查) */
		return; /* 直接返回 */

	/* 强制要求不存在仍在进行的 vmap 映射引用 */
	BUG_ON(dmabuf->vmapping_counter); /* 若非 0,说明映射引用不平衡,释放会导致严重错误 */

	/* 强制要求不存在仍活跃的 fence 回调状态 */
	BUG_ON(dmabuf->cb_in.active || dmabuf->cb_out.active); /* 若为真,说明异步状态机不一致 */

	/* 拆除统计信息导出,避免外部观测接口继续引用该对象 */
	dma_buf_stats_teardown(dmabuf); /* 释放与统计相关的资源 */

	/* 调用 exporter 提供的 release,用于释放底层导出方持有的资源 */
	dmabuf->ops->release(dmabuf); /* exporter 释放:通常涉及底层 buffer/fence/映射等 */

	/* 若 resv 对象为内嵌(紧随 dmabuf 分配),则需要在此执行析构 */
	if (dmabuf->resv == (struct dma_resv *)&dmabuf[1]) /* 判断 resv 是否指向内嵌区域 */
		dma_resv_fini(dmabuf->resv); /* 完成 resv 对象析构 */

	/* 释放时不应仍存在 attachment;若存在,提示严重生命周期错误 */
	WARN_ON(!list_empty(&dmabuf->attachments)); /* attachment 非空意味着仍有外部引用关系未解除 */

	/* 归还 exporter 模块引用,维护模块卸载语义一致性 */
	module_put(dmabuf->owner); /* owner 为 exporter 模块,释放对应引用 */

	/* 释放名称字符串(若存在) */
	kfree(dmabuf->name); /* dmabuf->name 由 kmalloc 分配 */

	/* 释放 dmabuf 主对象内存 */
	kfree(dmabuf); /* dmabuf 本体释放,生命周期结束 */
}

/**
 * @brief file release 回调:从 dma-buf 全局列表中摘除该文件关联对象
 *
 * @param inode 文件 inode
 * @param file  文件对象
 * @return 成功返回 0;若 file 不是 dma-buf 文件则返回 -EINVAL
 */
static int dma_buf_file_release(struct inode *inode, struct file *file)
{
	/* 确认该 file 为 dma-buf file,避免误删 */
	if (!is_dma_buf_file(file)) /* 检查 file 类型 */
		return -EINVAL; /* 非 dma-buf 文件,拒绝处理 */

	/* 从 dma-buf 全局列表中移除与该 file 关联的对象 */
	__dma_buf_list_del(file->private_data); /* private_data 持有列表节点或关联对象指针 */

	return 0; /* 释放流程完成 */
}

/**
 * @brief dma-buf dentry 操作集
 *
 * 将 dentry 的动态命名与释放回调绑定到 dma-buf 的 dentry 上:
 * - d_dname:用于动态生成显示名称
 * - d_release:用于在 dentry 释放时销毁 dmabuf
 */
static const struct dentry_operations dma_buf_dentry_ops = {
	.d_dname = dmabuffs_dname, /* 动态名称生成回调 */
	.d_release = dma_buf_release, /* dentry 释放回调 */
};

/** @brief dma-buf 伪文件系统的挂载点,全局唯一,用于承载 dma-buf 的 dentry/文件对象 */
static struct vfsmount *dma_buf_mnt; /* 由 dma_buf_init 中 kern_mount 初始化 */

drivers/dma-buf/dma-fence.c DMA Fence(DMA 栅栏)同步机制

[功能概述] 为异步 DMA 硬件操作提供内核内的统一同步原语(可跨驱动、可跨进程边界通过用户态载体传递),并与 dma-buf/dma-resv 形成显式/隐式同步体系。

介绍

dma-fence 用 struct dma_fence 表示,是 Linux 内核中面向异步硬件工作(GPU 渲染、视频编解码、显示等)的同步原语:通过 dma_fence_init() 初始化,通过 dma_fence_signal()(或带时间戳的变体)标记完成;同一 context 上的 fence 具有全序关系,并可用于显式 fencing(sync_file)、子系统封装(如 DRM syncobj),以及隐式 fencing(挂在 dma_buf 的 dma_resv 上)。


历史与背景

这项技术为了解决什么问题而诞生

核心问题是:共享 buffer 的多设备/多驱动异步访问需要统一的“完成信号”语义,否则容易出现数据竞争、重复写、读到未完成结果等问题。dma-buf 文档明确把 dma-fence 定义为“指示异步硬件操作何时完成”的机制,并与 dma-resv 一起实现隐式同步。

重要里程碑或迭代点(从源码注释与近期讨论归纳)
  • 2012 年左右进入主线生态:源码头部版权与作者信息显示该机制至少在 2012 年已形成并由多方维护。
  • 跨驱动契约(cross-driver contract)与 lockdep 注解体系:源码文档强调“跨驱动一致规则”、超时/恢复、以及用 dma_fence_begin_signalling()/dma_fence_end_signalling() 标注可能影响 dma_fence_signal() 路径的临界区,以便 lockdep 检查死锁风险。
  • 显式同步用户态载体 sync_file 成熟:sync_file 文档把它定义为 fences 的载体,用于驱动与用户态之间传递同步点,从而实现跨进程边界的显式 fencing。
  • 新增“deadline hint”提示机制(优化调度/等待体验):源码中专门描述了可通过 dma_fence_set_deadline(以及用户态 ioctl 间接路径)提供“紧迫性提示”。
  • 2025 年关于 dma_fence 模块卸载/RCU 保护的持续改进:LWN 转发的补丁讨论指出:fence 可能泄漏到外部驱动并在 signaled 后仍延迟释放,导致发行者模块卸载后 dma_fence_ops 不可用而崩溃,补丁集尝试用 RCU 保护 ops 并允许 fence 更“自包含”。
社区活跃度与主流应用情况
  • 主流应用:dma-buf 文档点名 DRM 大量使用 dma-buf 交换 buffer,并与 V4L2 等子系统交互;其中同步体系的三大原语就包含 dma-fence。
  • 活跃度:内核官方文档页面近期仍在更新(docs.kernel.org 页面显示近期发布/抓取),并且 2025 年仍有围绕 dma_fence 的设计问题在 dri-devel 等社区持续讨论。

核心原理与设计

核心工作原理
  1. 对象模型struct dma_fence 表示一个同步点,具有“未完成/已完成”状态;初始化用 dma_fence_init(),完成用 dma_fence_signal()(或 dma_fence_signal_timestamp() 记录完成时间戳)。
  2. context + seqno 的全序语义:通过 dma_fence_context_alloc() 分配 context,同一 context 上 fence 全序。源码用一个全局 atomic64 计数器分配 context。
  3. 等待与唤醒路径dma_fence_wait_timeout() 会进行可睡眠检查,并在等待前调用 dma_fence_enable_sw_signaling() 触发“尽快完成”的软件信号支持(内部会调用 dma_fence_ops.enable_signaling)。
  4. 回调机制:fence 支持注册 callback;源码也明确警告取消 callback 风险高(容易引入死锁/竞态),通常仅用于硬件卡死恢复等场景。
  5. 跨驱动契约约束:源码文档强调“必须在合理时间内完成”“需要 hang recovery”“等待场景下的锁/内存分配限制”等,目的是避免跨子系统组合时产生不可控死锁与回收路径问题。
主要优势
  • 跨驱动同步契约统一:把“异步硬件完成”抽象成跨驱动可理解的对象,降低多子系统协作成本。
  • 显式/隐式同步都能承载:既能通过 sync_file 走显式 fencing(跨进程传递),也能通过 dma_resv 走隐式 fencing(buffer 附带同步点)。
  • 调试与可观测性:源码导出 tracepoint(如 dma_fence_emit/dma_fence_signaled 等),便于跟踪同步行为。
已知劣势、局限性与不适用点
  • 设计上强依赖“发行者必须可靠完成/恢复”:如果硬件/驱动无法保证 fence 在合理时间完成,或缺失 hang recovery,系统整体等待链条会放大风险。
  • 回调取消与复杂锁层级容易出错:源码对取消 callback 的风险做了强提示;此外还需要遵循锁注解与 dma_resv 锁层级规则。
  • 模块卸载边界问题:共享 buffer 会让 fence “流入外部驱动”,signaled 后仍可能延迟释放,导致发行者模块卸载带来 ops 指针失效风险;社区仍在通过 RCU 等手段改进。

使用场景

首选场景(举例)
  • 图形/显示管线:DRM 在进程/上下文之间交换 buffer,需要用 fence 表达“GPU 渲染完成/scanout 完成”等同步点。
  • 媒体处理:与 V4L2 等协作时,在 producer/consumer 间传递 buffer,并用 fence 保证读写顺序。
  • 用户态显式同步(Vulkan/OpenGL/媒体栈互操作):用 sync_file 把 fence 作为 fd 传递,实现跨进程显式 fencing。
不推荐使用的场景
  • 纯驱动内部、无跨设备共享需求的简单同步:优先用 completion/waitqueue 等更直接的内核同步原语(更少契约约束、更少与 dma_resv/用户态交互复杂度)。
  • 无法提供可靠超时与恢复路径的硬件任务:因为跨驱动等待链条会把“不可完成 fence”的风险放大到系统层面。

对比分析

维度dma_fencecompletion / waitqueue(典型内核同步)sync_file
定位异步 DMA 同步点(跨驱动契约)通用内核同步(多用于同一子系统/驱动内部)fence 的用户态载体(fd 传递)
实现方式struct dma_fence + ops + callback + waitwaitqueue/completion 结构 + 唤醒file 对象包装一个/多个 fence,并提供导入导出流程
性能开销创建轻量,但启用 signalling/等待会触发 ops 与回调管理;强调可观测性与契约约束通常更直接、更少跨子系统约束增加 file/fd 管理与跨进程传递成本
资源占用fence 对象 + 回调链 + 可能的追踪/注解;共享场景下生命周期更复杂一般更少对象间外溢额外的 file 结构与 fd 生命周期
隔离级别可跨驱动、可跨进程边界(借助载体)通常局限在内核内部调用关系面向用户态边界的显式同步
“启动速度”(可理解为创建/投入使用的时延)dma_fence_init() 初始化即可发布;但要遵循发布时机与 lockdep 注解规则通常更快更直接需要创建 file、安装 fd 等步骤

补充:drm_syncobj 属于 DRM 子系统提供的显式 fencing 原语,相比 sync_file,其特点是允许底层 fence 被更新(源码在 overview 中点到这一差异)。


总结

关键特性

  • struct dma_fence 作为异步 DMA 完成信号的统一抽象;context 保证同一执行序列全序。
  • 支持等待/回调;等待前可触发软件 signalling;取消回调需极谨慎。
  • 面向跨驱动组合的严格契约:超时与恢复、锁与内存分配上下文约束、lockdep 注解。
  • 与 dma-buf/dma-resv 形成显式(sync_file)与隐式同步体系。

dma_fence_init_stub: 初始化并立即完成一个全局 stub fence,用于提供可用的默认同步对象

在内核子系统初始化阶段,构造一个全局的“stub fence”,并把它立即 signal(完成)。这样做的目的不是表示真实的异步 DMA 工作,而是提供一个始终已完成、且具备合法 dma_fence 语义的默认对象,供框架在某些“需要 fence 但当前没有真实 fence”或“需要一个占位且永不阻塞”的路径中使用。

这段代码背后的关键点是 dma_fence 的跨驱动契约:

  • fence 必须可等待、可 signal、可识别(driver/timeline 名称)
  • fence 必须遵循统一的锁与回调规则,以便跨设备、跨子系统进行同步
    stub fence 的存在可以让框架在缺省情况下仍保持这些规则成立。

核心原理概述

  1. 提供最小可用的 dma_fence_ops
    通过 dma_fence_stub_ops 提供 .get_driver_name.get_timeline_name,确保该 fence 在调试/追踪时具备可识别的名称。

  2. 初始化 fence 的核心字段与锁
    dma_fence_init() 会把 fence 与 ops、lock、context、seqno 绑定,建立 fence 的基础身份与并发保护策略。

  3. 打开 signal 能力位并立即 signal
    DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT 允许 fence 走 signal 路径;随后立刻 dma_fence_signal(),使该 fence 永远处于“已完成”状态。

  4. 在 subsys_initcall 阶段完成初始化
    通过 subsys_initcall(dma_fence_init_stub) 保证该 stub 在大量子系统使用 fence 之前就已就绪,避免早期路径拿到未初始化对象。


/*
 * dma_fence_stub_get_name: 返回 stub fence 的固定名称
 * @fence: 当前 fence 对象
 *
 * 该函数用于同时作为 driver name 与 timeline name 的获取回调,
 * 以保证 stub fence 在调试、追踪与输出中具备可识别的名字。
 */
static const char *dma_fence_stub_get_name(struct dma_fence *fence)
{
        return "stub";
}

/*
 * dma_fence_stub_ops: stub fence 的操作集
 *
 * stub fence 并不表示真实硬件队列或真实时间线,
 * 其目的只是提供最小的可识别信息,使其符合 dma_fence 的基本接口契约。
 */
static const struct dma_fence_ops dma_fence_stub_ops = {
	.get_driver_name = dma_fence_stub_get_name,   /* 返回驱动名称 */
	.get_timeline_name = dma_fence_stub_get_name, /* 返回时间线名称 */
};

/*
 * dma_fence_init_stub: 初始化并完成全局 stub fence
 *
 * 在内核子系统初始化阶段构造一个全局 dma_fence:
 * - 使用 stub ops 与全局锁初始化其核心字段
 * - 设置允许 signal 的标志位
 * - 立即 signal,使其永久处于完成状态
 */
static int __init dma_fence_init_stub(void)
{
	/*
	 * 初始化 dma_fence 核心字段:
	 * - &dma_fence_stub: 全局 stub fence 对象
	 * - &dma_fence_stub_ops: 操作集,用于获取名称等
	 * - &dma_fence_stub_lock: fence 内部并发保护锁
	 * - context=0, seqno=0: 使用固定上下文与序号作为占位身份
	 *
	 * 对单核 STM32H750 视角的关键点:
	 * - 单核不意味着无并发:内核仍存在抢占/中断等并发语义
	 * - 因此 fence 仍必须依赖锁来保证状态转换一致性
	 */
	dma_fence_init(&dma_fence_stub, &dma_fence_stub_ops,
		       &dma_fence_stub_lock, 0, 0);

	/*
	 * 设置允许 signal 的标志位。
	 *
	 * DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT 用于控制 fence 是否允许进入 signal 路径,
	 * 避免某些 fence 类型在未准备好回调机制时被错误地 signal。
	 */
	set_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT,
		&dma_fence_stub.flags);

	/*
	 * 立即 signal,使该 fence 永久处于“已完成”状态。
	 *
	 * 这样任何对该 fence 的 wait 都不会阻塞,
	 * 可用于框架内部需要 fence 语义但不希望引入等待的缺省路径。
	 */
	dma_fence_signal(&dma_fence_stub);
	return 0;
}
subsys_initcall(dma_fence_init_stub);

__dma_fence_init / dma_fence_init: 初始化 dma_fence 的身份、并发保护与回调容器

这段代码的核心作用是:把一个已分配的 struct dma_fence 对象初始化成“可被框架安全使用的同步原语实例”。它不负责 signal、不负责等待,只负责建立最关键的三类基础设施:

  1. 生命周期基础:初始化引用计数 refcount,让 fence 能被跨子系统安全持有与释放。
  2. 并发一致性基础:绑定 lock,规定后续所有状态转换(signal、回调链处理等)必须在该锁保护下完成。
  3. 语义比较基础:设置 contextseqno,让 fence 之间可以通过 dma_fence_later() 这类比较函数建立有序关系(同一 context 内要求完全有序)。

核心原理概述

  1. 严格的前置条件检查(BUG_ON)

    • lock 必须存在:否则后续 signal/wait/callback 的并发一致性不可保证。
    • ops 必须提供 get_driver_name/get_timeline_name:这是跨驱动契约的一部分,用于诊断、跟踪与一致的接口语义。缺失会导致框架在 debug/trace/输出路径上出现不可接受的不确定性。
  2. 引用计数初始化(kref_init)

    • fence 的引用计数是其“跨模块共享”的基本机制。
    • 后续任何 attach/等待/回调注册都可能持有 fence,必须依赖 refcount 保证对象不被提前释放。
  3. 回调链表容器初始化(cb_list)

    • INIT_LIST_HEAD(&fence->cb_list) 建立回调链表头。
    • 这使得 dma_fence_add_callback() 能在 fence 未 signal 时挂回调;signal 时可遍历并执行。
  4. 并发保护锁绑定(fence->lock)

    • 该指针定义 fence 的“互斥域”。
    • signal 与 add_callback 的竞态处理依赖这把锁的语义:必须是 irqsafe,以便在可能的中断上下文中也能安全使用。
  5. context/seqno 初始化(有序语义基础)

    • context 表示执行上下文(例如某个硬件队列/时间线)。
    • seqno 在同一 context 内单调递增,用于比较“哪个 fence 更晚”。
    • 这为 dma_fence_later() 提供数学意义上的偏序关系:同一 context 可全序比较,不同 context 不保证可比。
  6. flags 与 error 初始化

    • flags 保存 fence 的状态标志(例如是否允许 enable_signaling 等)。
    • error = 0 表示初始无错误,后续可以通过 signal 带错误完成语义。
  7. trace 钩子

    • trace_dma_fence_init(fence) 用于追踪初始化事件,便于定位生命周期与竞态问题。

/*
 * __dma_fence_init: 初始化 dma_fence 的内部字段
 * @fence: 需要初始化的 fence 对象
 * @ops:   fence 的操作集,提供跨驱动统一的接口实现入口
 * @lock:  fence 的 irqsafe 自旋锁,用于保护该 fence 的状态与回调链
 * @context: fence 所属执行上下文(同 context 内的 fence 必须全序)
 * @seqno:   该 context 内单调递增的序列号,用于 fence 先后比较
 * @flags:   fence 初始标志位集合
 */
static void
__dma_fence_init(struct dma_fence *fence, const struct dma_fence_ops *ops,
	         spinlock_t *lock, u64 context, u64 seqno, unsigned long flags)
{
	/* lock 必须存在,否则无法保证 signal/callback 路径的并发一致性 */
	BUG_ON(!lock);

	/*
	 * ops 必须存在,且至少要能提供 driver 名与 timeline 名:
	 * 这既是调试/追踪要求,也是跨驱动契约的一部分。
	 */
	BUG_ON(!ops || !ops->get_driver_name || !ops->get_timeline_name);

	/* 初始化引用计数,支持 fence 在跨子系统共享时的生命周期管理 */
	kref_init(&fence->refcount);

	/* 绑定操作集:后续查询、打印、以及可选的 enable_signaling 等行为通过 ops 扩展 */
	fence->ops = ops;

	/* 初始化回调链表头:用于 dma_fence_add_callback() 注册回调 */
	INIT_LIST_HEAD(&fence->cb_list);

	/* 绑定并发保护锁:规定 fence 的状态转换与回调链操作必须在该锁保护下进行 */
	fence->lock = lock;

	/* 设置 fence 的执行上下文与序列号,用于同一 context 内的先后比较 */
	fence->context = context;
	fence->seqno = seqno;

	/* 设置初始标志位 */
	fence->flags = flags;

	/* 初始错误码为 0;若后续异步任务失败,可通过 error 语义完成 */
	fence->error = 0;

	/* 记录初始化事件,便于追踪 fence 生命周期 */
	trace_dma_fence_init(fence);
}

/*
 * dma_fence_init: 初始化一个自定义 fence(对外 API)
 * @fence:   需要初始化的 fence 对象
 * @ops:     fence 的操作集
 * @lock:    fence 的 irqsafe 自旋锁
 * @context: fence 所属执行上下文
 * @seqno:   该 context 内单调递增序列号
 *
 * 该函数是对 __dma_fence_init 的封装,flags 固定为 0。
 */
void
dma_fence_init(struct dma_fence *fence, const struct dma_fence_ops *ops,
	       spinlock_t *lock, u64 context, u64 seqno)
{
	/* flags=0 表示以默认初始标志初始化 fence */
	__dma_fence_init(fence, ops, lock, context, seqno, 0UL);
}
EXPORT_SYMBOL(dma_fence_init);

dma_fence_signal_timestamp_locked / dma_fence_signal_timestamp / dma_fence_signal_locked / dma_fence_signal: 以原子方式将 fence 从“未完成”转换为“已完成”,并执行回调链

这组函数实现的是 dma_fence 最核心的状态转换:signal(完成)。它们的共同语义是:

  • 将 fence 的状态从“未 signaled”变为“已 signaled”(只允许一次)
  • 设置完成时间戳(timestamp 版本)
  • 解除所有 dma_fence_wait() 的阻塞条件
  • 执行所有通过 dma_fence_add_callback() 注册的回调
  • 并且用锁与原子位操作保证:signal 与回调注册之间不会出现丢回调、重复回调或释放后访问

这段代码最关键的技巧有三个:

  1. 一次性状态转换的原子保证test_and_set_bit(SIGNALED_BIT) 保证只有第一个调用者能成功 signal,后续调用直接失败返回。
  2. 回调链“先摘链后执行”:用 list_replacefence->cb_list 原子地换成一个临时链表 cb_list,然后在锁保护外(或锁内的后半段)安全遍历执行,避免回调执行过程中破坏 fence 内部链表结构或造成死锁/递归。
  3. 锁的两层封装*_locked 版本要求调用者已持锁,非 locked 版本负责 spin_lock_irqsave/restore,保证在中断上下文与普通上下文都成立。

在 STM32H750(单核、无 MMU)视角下需要强调:

  • 单核不意味着没有并发:中断、抢占、软中断/工作队列都能产生并发交错,因此 spin_lock_irqsave 与原子位仍然必要。
  • irqsave 的意义不是“多核同步”,而是“禁止本 CPU 中断导致的重入竞态”。

/*
 * dma_fence_signal_timestamp_locked: 在已持 fence->lock 的条件下 signal fence 并设置时间戳
 * @fence: 需要 signal 的 fence
 * @timestamp: 使用 CLOCK_MONOTONIC 域的完成时间戳
 *
 * 返回:
 *  0     - 成功 signal(第一次生效)
 * -EINVAL- fence 已经 signaled(再次调用不生效)
 */
int dma_fence_signal_timestamp_locked(struct dma_fence *fence,
				      ktime_t timestamp)
{
	struct dma_fence_cb *cur, *tmp; /* 回调节点遍历指针 */
	struct list_head cb_list;       /* 临时回调链表头,用于“摘链执行” */

	/* 断言调用者已持有 fence->lock,用于保证状态转换与回调链操作的原子性 */
	lockdep_assert_held(fence->lock);

	/*
	 * 将 SIGNALED 位从 0 原子设置为 1,并返回旧值。
	 * - 若旧值为 1,说明已经 signal 过,本次返回 -EINVAL
	 * - 若旧值为 0,本次成为“唯一有效 signal”
	 *
	 * 这是 fence “只能从未完成->已完成一次”的硬性语义保证。
	 */
	if (unlikely(test_and_set_bit(DMA_FENCE_FLAG_SIGNALED_BIT,
				      &fence->flags)))
		return -EINVAL;

	/*
	 * 在写入 timestamp 前,先把 fence->cb_list “摘出来”。
	 *
	 * list_replace 的效果:
	 * - 把 fence->cb_list 的链表内容整体移交给局部变量 cb_list
	 * - fence->cb_list 自身被替换成一个空链表头(仍然可用)
	 *
	 * 这样做的关键目的:
	 * 1) 回调执行过程中不再触碰 fence->cb_list,避免回调递归/并发修改破坏内部结构
	 * 2) signal 与 add_callback 的竞态能被严格界定:signal 成功后,后续回调注册必须走“立即执行/失败返回”的路径
	 */
	list_replace(&fence->cb_list, &cb_list);

	/* 写入完成时间戳,并设置“timestamp 有效”标志位 */
	fence->timestamp = timestamp;
	set_bit(DMA_FENCE_FLAG_TIMESTAMP_BIT, &fence->flags);

	/* 记录 trace:用于性能分析与事件追踪 */
	trace_dma_fence_signaled(fence);

	/*
	 * 执行所有回调(安全遍历)。
	 *
	 * list_for_each_entry_safe 允许在遍历时删除节点;
	 * 这里先把 cur->node 重新 INIT_LIST_HEAD,确保该回调节点脱离链表,避免重复执行与悬挂指针。
	 */
	list_for_each_entry_safe(cur, tmp, &cb_list, node) {
		INIT_LIST_HEAD(&cur->node); /* 标记该回调节点已从链表摘除 */
		cur->func(fence, cur);      /* 执行回调:由注册方提供的函数 */
	}

	return 0;
}
EXPORT_SYMBOL(dma_fence_signal_timestamp_locked);

/*
 * dma_fence_signal_timestamp: 在未持锁条件下 signal fence,并设置指定时间戳
 * @fence: 需要 signal 的 fence
 * @timestamp: 完成时间戳(CLOCK_MONOTONIC 域)
 *
 * 该函数负责加锁(irqsave)并调用 *_locked 版本完成实际工作。
 */
int dma_fence_signal_timestamp(struct dma_fence *fence, ktime_t timestamp)
{
	unsigned long flags; /* irqsave 保存的中断标志 */
	int ret;             /* 返回值 */

	/* fence 为空属于调用者错误,返回 -EINVAL 并产生警告 */
	if (WARN_ON(!fence))
		return -EINVAL;

	/*
	 * 使用 spin_lock_irqsave:
	 * - 自旋锁保证与其他上下文对同一 fence 的并发操作互斥
	 * - irqsave 防止本 CPU 中断打断导致的重入竞态
	 */
	spin_lock_irqsave(fence->lock, flags);
	ret = dma_fence_signal_timestamp_locked(fence, timestamp); /* 真正的状态转换与回调执行 */
	spin_unlock_irqrestore(fence->lock, flags);

	return ret;
}
EXPORT_SYMBOL(dma_fence_signal_timestamp);

/*
 * dma_fence_signal_locked: 在已持锁条件下 signal fence(使用当前时间戳)
 * @fence: 需要 signal 的 fence
 *
 * 这是对 dma_fence_signal_timestamp_locked 的简化封装。
 */
int dma_fence_signal_locked(struct dma_fence *fence)
{
	/* 使用 ktime_get() 获取当前 CLOCK_MONOTONIC 时间戳 */
	return dma_fence_signal_timestamp_locked(fence, ktime_get());
}
EXPORT_SYMBOL(dma_fence_signal_locked);

/*
 * dma_fence_signal: 在未持锁条件下 signal fence(使用当前时间戳),并标注 signalling 区间
 * @fence: 需要 signal 的 fence
 *
 * 相比 dma_fence_signal_timestamp,该函数额外使用:
 * - dma_fence_begin_signalling / dma_fence_end_signalling
 * 用于标注“可能导致 fence 完成”的代码区间,辅助避免死锁与锁依赖问题(lockdep/规则契约)。
 */
int dma_fence_signal(struct dma_fence *fence)
{
	unsigned long flags; /* irqsave 保存的中断标志 */
	int ret;             /* signal 返回值 */
	bool tmp;            /* begin_signalling 的返回值,用于 end_signalling 配对 */

	/* fence 为空属于调用者错误 */
	if (WARN_ON(!fence))
		return -EINVAL;

	/*
	 * 标注进入 signalling 区间。
	 * 该机制属于跨驱动契约的一部分,用于帮助识别“等待路径与完成路径”的锁依赖关系,降低死锁风险。
	 */
	tmp = dma_fence_begin_signalling();

	/* 加锁并完成实际 signal 逻辑 */
	spin_lock_irqsave(fence->lock, flags);
	ret = dma_fence_signal_timestamp_locked(fence, ktime_get());
	spin_unlock_irqrestore(fence->lock, flags);

	/* 标注退出 signalling 区间,与 begin 成对 */
	dma_fence_end_signalling(tmp);

	return ret;
}
EXPORT_SYMBOL(dma_fence_signal);

本文地址:https://www.yitenyun.com/3041.html

搜索文章

Tags

#语言模型 #服务器 #人工智能 #大模型 #ai #ai大模型 #agent #飞书 #python #pip #conda #微信 #log4j #ollama #AI编程 #ios面试 #ios弱网 #断点续传 #ios开发 #objective-c #ios #ios缓存 #远程工作 #Trae #IDE #AI 原生集成开发环境 #Trae AI #kylin #docker #arm #运维 #AI #飞牛nas #fnos #学习 #产品经理 #AI大模型 #大模型学习 #大模型教程 香港站群服务器 多IP服务器 香港站群 站群服务器 #mongodb #linux #数据库 #算法 #数据结构 #PyTorch #深度学习 #模型训练 #星图GPU #银河麒麟高级服务器操作系统安装 #银河麒麟高级服务器V11配置 #设置基础软件仓库时出错 #银河麒高级服务器系统的实操教程 #生产级部署银河麒麟服务系统教程 #Linux系统的快速上手教程 #ssh #kubernetes #笔记 #平面 #容器 #学习方法 #fastapi #html #css #云计算 #云原生 #科技 #自然语言处理 #神经网络 #自动化 #ansible #大数据 #职场和发展 #程序员创富 #ARM服务器 # GLM-4.6V # 多模态推理 #ubuntu #音视频 #私有化部署 #pytorch #hadoop #hbase #hive #zookeeper #spark #kafka #flink #vscode #ide #java #开发语言 #前端 #javascript #架构 #大模型入门 #低代码 #爬虫 #gitee #区块链 #测试用例 #生活 #华为云 #部署上线 #动静分离 #Nginx #新人首发 #langchain #MobaXterm #物联网 #websocket #gemini #gemini国内访问 #gemini api #gemini中转搭建 #Cloudflare #llama #opencv #fabric #postgresql #openHiTLS #TLCP #DTLCP #密码学 #商用密码算法 #sql #AIGC #agi #http #mcp #mcp server #AI实战 #项目 #高并发 #java-ee #经验分享 #安卓 #阿里云 #node.js #分布式 #配置中心 #SpringCloud #Apollo #nginx #开源 #C++ #Reactor #CFD #机器学习 #mysql #aws #数学建模 #分库分表 #垂直分库 #水平分表 #雪花算法 #分布式ID #跨库查询 #windows #iventoy #VmWare #OpenEuler #大语言模型 #长文本处理 #GLM-4 #Triton推理 #github #git #网络 #tcp/ip #多个客户端访问 #IO多路复用 #回显服务器 #TCP相关API #分阶段策略 #模型协议 #pycharm #驱动开发 #c++ #Ansible # 自动化部署 # VibeThinker #腾讯云 #矩阵 #线性代数 #AI运算 #向量 #harmonyos #鸿蒙PC #流程图 #论文阅读 #信息可视化 #重构 #计算机视觉 #word #umeditor粘贴word #ueditor粘贴word #ueditor复制word #ueditor上传word图片 #flutter #鸿蒙 #进程控制 #RTP over RTSP #RTP over TCP #RTSP服务器 #RTP #TCP发送RTP #mvp #个人开发 #设计模式 #android #cpolar #vue上传解决方案 #vue断点续传 #vue分片上传下载 #vue分块上传下载 #https #安全 #华为 #ci/cd #jenkins #gitlab #后端 #c# #rocketmq #stm32 #Windows 更新 #SSM 框架 #孕期健康 #产品服务推荐 #推荐系统 #用户交互 #数信院生信服务器 #Rstudio #生信入门 #生信云服务器 #dify #web安全 #正则 #正则表达式 #qt #Conda # 私有索引 # 包管理 #课程设计 #spring boot #程序员 #Linux #TCP #线程 #线程池 #unity #游戏引擎 #iBMC #UltraISO #性能优化 #rag #serverless #程序人生 #科研 #博士 #RAGFlow #DeepSeek-R1 #Harbor #风控模型 #决策盲区 #vue.js #spring #能源 #microsoft #牛客周赛 #内存治理 #django #文心一言 #AI智能体 #springboot #超算服务器 #算力 #高性能计算 #仿真分析工作站 #centos #svn #堡垒机 #安恒明御堡垒机 #windterm #时序数据库 #儿童书籍 #儿童诗歌 #童话故事 #经典好书 #儿童文学 #好书推荐 #经典文学作品 #jar #c语言 #搜索引擎 #导航网 #企业开发 #ERP #项目实践 #.NET开发 #C#编程 #编程与数学 #缓存 #redis #华为od #华为od机考真题 #华为od机试真题 #华为OD上机考试真题 #华为OD机试双机位C卷 #华为OD上机考试双机位C卷 #华为ODFLASH坏块监测系统 #ecmascript #elementui #Agent #开源软件 #硬件工程 #Canal #php #测试工具 #网络协议 #mcu #YOLO #maven #内网穿透 #ai agent #ai大小模型 #小模型 #开源小模型 #8b模型 #国产大模型 #SOTA #HCIA-Datacom #H12-811 #题库 #最新题库 #spring cloud #json #lvs #负载均衡 #信息与通信 #rpa #实时互动 #Telegram机器人 #ClawdBot #多模态翻译 #大模型推理 #servlet #RAG #RAG调优 #RAG系统 #召回 #ui #团队开发 #墨刀 #figma #uni-app #小程序 #notepad++ #MCP #MCP服务器 #mobaxterm #FL Studio #FLStudio #FL Studio2025 #FL Studio2026 #FL Studio25 #FL Studio26 #水果软件 #进程 #jetty #电脑 #shell #CPU利用率 #udp #FTP服务器 #select #FaceFusion # Token调度 # 显存优化 #es安装 #prometheus #毕业设计 #网络安全 #PyCharm # 远程调试 # YOLOFuse #pjsip #2026年美赛C题代码 #2026年美赛 #vim #gcc #yum #论文 #毕设 #推荐算法 #DeepSeek #服务器繁忙 #设备驱动 #芯片资料 #网卡 #diskinfo # TensorFlow # 磁盘健康 #边缘计算 #java大文件上传 #java大文件秒传 #java大文件上传下载 #java文件传输解决方案 #嵌入式 #企业微信 #AI办公 #智能助手 #web #webdav #蓝桥杯 #SSH # ProxyJump # 跳板机 #散列表 #哈希算法 #服务器架构 #AI推理芯片 #我的世界 #游戏私服 #云服务器 #微服务 #Oauth2 #计算机网络 #全能视频处理软件 #视频裁剪工具 #视频合并工具 #视频压缩工具 #视频字幕提取 #视频处理工具 #scrapy #ESXi #Ubuntu服务器 #硬盘扩容 #命令行操作 #VMware #golang #数据结构与算法 #jvm #学习笔记 #jdk #压枪 #Dell #PowerEdge620 #内存 #硬盘 #RAID5 #鸭科夫 #逃离鸭科夫 #鸭科夫联机 #鸭科夫异地联机 #游戏 #开服 #PowerBI #企业 #le audio #蓝牙 #低功耗音频 #通信 #连接 #LLM #远程连接 #转行 #ssl #深度优先 #DFS #jmeter #功能测试 #软件测试 #自动化测试 #职场发展 #chatgpt #DS随心转 #新浪微博 #前端框架 #matlab #支持向量机 #autosar #FRP #线性回归 #SSE #AI写作 #处理器模块 #现货库存 #价格优惠 #PM864AK01 #3BSE018161R1 #PLC #控制器模块 #openclaw #实在Agent #swiftui #swift #Android #Bluedroid #分类 #社科数据 #数据分析 #数据挖掘 #数据统计 #经管数据 #gitea #pdf #dubbo #创业创新 #论文笔记 #钉钉 #机器人 #bytebase #lstm #零售 #压力测试 #css3 #3d #whisper #就业指南 #思维模型 #认知框架 #认知 #系统架构 #AI大模型应用开发 #ffmpeg #电商 #powerpoint #Com #游戏美术 #技术美术 #游戏策划 #游戏程序 #用户体验 #LabVIEW #光谱仪 #串口通信 #AQ6370 #flask #Java面试 #Java程序员 #后端开发 #Redis #分布式锁 #健康医疗 #金融 #教育电商 #媒体 #prompt #DisM++ # 系统维护 #gpu算力 #arm开发 #嵌入式硬件 #googlecloud #transformer #excel #敏捷流程 #架构师 #软考 #系统架构师 #海外服务器安装宝塔面板 #macos #汽车 #chrome #ISP Pipeline #行缓冲 #leetcode #单片机 #visual studio code #postman #easyui #目标检测 #pyqt #单目测距 #速度估计 #pyqt界面 #注意力机制 #dreamweaver #AI产品经理 #大模型开发 #elasticsearch #版本控制 #Git入门 #开发工具 #代码托管 #爱心代码 #表白代码 #爱心 #tkinter #情人节表白代码 #京东云 #Redisson #abtest #防毒口罩 #防尘口罩 #具身智能 #发展心理学 #运动控制 #内在动机 #镜像神经元 #交叉学科 #数列 #数学 #数论 #洛谷 #聚类 #CNAS #CMA #程序文件 #oracle #中间件 #车辆排放 #面试 #逻辑回归 #list #智能路由器 #自动驾驶 #echarts #信号处理 #目标跟踪 #酒店客房管理系统 #sglang #laravel #微信小程序 #智慧校园一体化平台 #智慧校园管理系统 #合肥自友科技-智慧校园 #智慧校园源头厂家 #智慧校园软件供应商 #智慧校园平台服务商 #高性价比智慧校园系统 #结构体 #Moltbot #阻塞队列 #生产者消费者模型 #服务器崩坏原因 #wsl #L2C #勒让德到切比雪夫 #电脑故障 #文件系统 #多线程 #数组 #链表 #性能调优策略 #双锁实现细节 #动态分配节点内存 #vue3 #天地图 #403 Forbidden #天地图403错误 #服务器403问题 #天地图API #部署报错 #测试覆盖率 #单元测试 #可用性测试 #考研 #软件工程 #GB/T4857 #GB/T4857.17 #GB/T4857测试 #bash #wps #Cpolar #国庆假期 #服务器告警 #操作系统 #Moltbook #Clawdbot #OBC #xss #selenium #twitter #mmap #nio #svm #amdgpu #kfd #ROCm #Java #Spring #Spring Boot #Modbus-TCP #语音识别 #测评 #幼儿园 #园长 #幼教 #蓝耘智算 #rabbitmq #protobuf #ssm #rpc #若依 #quartz #框架 #智能手机 #tomcat #firefox #STL #string #笔试 #银河麒麟 #人大金仓 #Kingbase ##程序员和算法的浪漫 #fastmcp #.netcore #部署 #epoll #openresty #lua #AI运维 #企业微信集成 #DevOps自动化 #贪心算法 #阳台种菜 #园艺手扎 #Gemini #Nano Banana Pro #sqlserver #todesk #高仿永硕E盘的个人网盘系统源码 #测试流程 #金融项目实战 #P2P #IPMI #webrtc #windows11 #系统修复 #android-studio #android studio #android runtime #vue #跳槽 #业界资讯 #投标 #标书制作 #asp.net #交互 #CISSP #CISSP考点 #信息安全 #CISSP哪里考 #公众号:厦门微思网络 #+微信号:xmweisi #Chat平台 #ARM架构 #本地部署 #clickhouse #智能体从0到1 #新手入门 #DHCP #apache #cnn #数据集 #图像分类 #图像分割 #yolo26算法 #其他 #SEO优化 #vllm #Streamlit #Qwen #AI聊天机器人 #windbg分析蓝屏教程 #单例模式 #wpf #数字化转型 #实体经济 #中小企业 #商业模式 #软件开发 #青蓝送水模式 #创业干货 #社交智慧 #职场生存 #系统思维 #身体管理 #商务宴请 #拒绝油腻 #清醒日常 #RAID #磁盘 #系统管理 #服务 #mybatis #后端 #ai编程 #ProCAST2025 #ProCast #脱模 #顶出 #应力计算 #铸造仿真 #变形计算 #源代码管理 #sql注入 #编辑器 #数模美赛 #余行补位 #意义对谈 #余行论 #领导者定义计划 #国产化OS #守护进程 #复用 #screen #就业 #Keycloak #Quarkus #AI编程需求分析 #研发管理 #禅道 #禅道云端部署 #设计规范 #放大电路 #winscp #Deepseek #gpt-3 #YOLO26 #YOLO11 #计算机 #连锁药店 #连锁店 #企业架构治理 #电力企业IT架构 #IT架构设计 #百度 #百度文库 #爱企查 #旋转验证码 #验证码识别 #图像识别 #流量运营 #用户运营 #网络攻击模型 #bootstrap #visual studio #知识图谱 #azure #OpenAI #高可用 #故障 #优化 #双指针 #TURN # WebRTC # HiChatBox #考试系统 #在线考试 #培训考试 #考试练习 #可信计算技术 #Playbook #AI服务器 #OCR #文字检测 #Smokeping #微PE # GLM-4.6V-Flash-WEB # AI部署 #AB包 #长文本理解 #glm-4 #推理部署 #wordpress #雨云 #pipeline #Transformers #NLP #Tracker 服务器 #响应最快 #torrent 下载 #2026年 #Aria2 可用 #迅雷可用 #BT工具通用 #麒麟 #国产化 #电气工程 #C# # IndexTTS 2.0 # 自动化运维 #everything #运营 #Puppet # IndexTTS2 # TTS #SSH Agent Forwarding # PyTorch # 容器化 #数据仓库 #启发式算法 #未加引号服务路径 #三维 #3D #三维重建 #react.js #CVE-2025-61686 #漏洞 #路径遍历高危漏洞 #需求分析 #5G #平板 #制造 #交通物流 #智能硬件 #junit #IO #排序算法 #插入排序 # GPU租赁 # 自建服务器 #MinIO服务器启动与配置详解 #AI论文写作工具 #学术论文创作 #论文效率提升 #MBA论文写作 #claude #js逆向 #逆向 #混淆 #stl #并发 #nmodbus4类库使用教程 #数据采集 #memcache #Buck #NVIDIA #交错并联 #DGX #clawdbot #QQbot #QQ #mariadb #系统升级 #信创 #anaconda #虚拟环境 #求职招聘 #RPA #影刀RPA #内容运营 #产品运营 #编程助手 #超时设置 #客户端/服务器 #网络编程 #ambari #硬盘克隆 #DiskGenius #mapreduce #uv #里氏替换原则 #SQL #金融投资Agent #ida #n8n #osg #政务 #glibc #三种参数 #参数的校验 #fastAPI #LE Audio #BAP #sizeof和strlen区别 #sizeof #strlen #计算数据类型字节数 #计算字符串长度 #可再生能源 #绿色算力 #风电 #gpt #智能体来了 #RAID技术 #存储 #.net #七年级上册数学 #有理数 #有理数的加法法则 #绝对值 # 双因素认证 #肿瘤相关巨噬细胞 #CXCL5 #信号通路 #胃癌 #mTOR #乐备实 #labex #clamav #kong #Kong Audio #Kong Audio3 #KongAudio3 #空音3 #空音 #中国民乐 #计算机外设 #iphone #mybatis #spine #文生视频 #CogVideoX #AI部署 #llm #树莓派4b安装系统 #图像处理 #yolo #web3.py #行为模式分析 #数据 #应用层 #跨领域 #敏感信息 #我的世界服务器搭建 #minecraft #numpy #scikit-learn #matplotlib #FutureWarning #pve #生信 #梁辰兴 #传输连接管理 #计算机网络基础 #JAVA #几何学 #拓扑学 #全栈 #全链路优化 #实战教程 #Tetrazine-Acid #1380500-92-4 #UEFI #BIOS #Legacy BIOS #1panel #vmware #python学习路线 #python基础 #python进阶 #python标准库 #adb #esp32 arduino #ICPC #sqlite #简单数论 #埃氏筛法 #paddlepaddle #homelab #Lattepanda #Jellyfin #Plex #Emby #Kodi #yolov12 #研究生life #聊天小程序 #codex #cursor #广播 #组播 #并发服务器 #TensorRT # Triton # 推理优化 #ueditor导入word #ueditor导入pdf #gpu #nvcc #cuda #nvidia #区间dp #二进制枚举 #图论 #google #search #scala #域名注册 #新媒体运营 #网站建设 #国外域名 #HBA卡 #RAID卡 #debian #1024程序员节 #改行学it #HeyGem # 服务器IP # 端口7860 #Coze工作流 #AI Agent指挥官 #多智能体系统 #健身房预约系统 #健身房管理系统 #健身管理系统 #ThingsBoard MCP #window10 #window11 #病毒 #DCOM进程 #系统进程资源占用高 # 服务器IP访问 # 端口映射 # CUDA #智慧城市 #GPU服务器 #8U #硬件架构 #openEuler #CANN #机器视觉 #6D位姿 #dba #mssql #数据安全 #注入漏洞 #risc-v #claude code #code cli #ccusage #硬件 #PyTorch 特性 #动态计算图 #张量(Tensor) #自动求导Autograd #GPU 加速 #生态系统与社区支持 #与其他框架的对比 #LoRA # RTX 3090 # lora-scripts #Node.js #漏洞检测 #CVE-2025-27210 # 局域网访问 # 批量处理 #copilot #fiddler #Ascend #MindIE #tensorflow #ddos #KMP #TRO #TRO侵权 #TRO和解 #银河麒麟操作系统 #openssh #华为交换机 #信创终端 #360AI图片精简版 #看图工具 #电脑看图工具 #360看图工具 #AI看图工具 #vnstat #监控 #ESP32 # OTA升级 # 黄山派 #gerrit #打卡 #计算机英语翻译 #rust #Rust #Tokio #异步编程 #系统编程 #Pin #http服务器 #支付 #GB28181 #SIP信令 #SpringBoot #视频监控 #WT-2026-0001 #QVD-2026-4572 #smartermail #防火墙 #ModelEngine #蓝湖 #Axure原型发布 #SEO #galeweather.cn #高精度天气预报数据 #光伏功率预测 #风电功率预测 #高精度气象 #react native #Modbus # 串口服务器 # NPort5630 #Ubuntu #汇编 #WIN32汇编 #xeon #Gunicorn #WSGI #Flask #并发模型 #容器化 #Python #性能调优 #SRS #流媒体 #直播 #Python办公自动化 #Python办公 #ceph #UDP套接字编程 #UDP协议 #网络测试 #知识 #SAP #ebs #metaerp #oracle ebs #科普 #JT/T808 #车联网 #车载终端 #模拟器 #仿真器 #开发测试 #AI赋能盾构隧道巡检 #开启基建安全新篇章 #以注意力为核心 #YOLOv12 #AI隧道盾构场景 #盾构管壁缺陷病害异常检测预警 #隧道病害缺陷检测 #910B #昇腾 #框架搭建 #AI技术 #MQTT协议 #C语言 #Nacos #卷积神经网络 #参数估计 #矩估计 #概率论 #鸿蒙系统 #系统安全 #车载系统 #安全架构 #ONLYOFFICE #MCP 服务器 #Kuikly #openharmony #虚幻 #ue5 #zabbix #LabVIEW知识 #LabVIEW程序 #LabVIEW功能 #labview #高级IO #reactor反应堆 #STUN # TURN # NAT穿透 #xlwings #Excel #东方仙盟 #仙盟创梦IDE #rustdesk #静脉曲张 #腿部健康 #运动 #idea #迁移重构 #代码迁移 #Claude #进程创建与终止 #Steam #饥荒联机版 #零代码平台 #AI开发 #榛樿鍒嗙被 #命令模式 #unity3d #服务器框架 #Fantasy #文件管理 #NAS #文件服务器 #环境搭建 #scanf #printf #getchar #putchar #cin #cout #pandas #pytest #mamba #CPU #监测 #ShaderGraph #图形 #Taiji #凤希AI伴侣 #esp32教程 #RustDesk # 黑屏模式 # TTS服务器 #数码相机 #ipv6 #fpga开发 #IndexTTS 2.0 #本地化部署 #文件IO #输入输出流 #麒麟OS #串口服务器 #工业级串口服务器 #串口转以太网 #串口设备联网通讯模块 #串口服务器选型 #tcpdump #高品质会员管理系统 #收银系统 #同城配送 #最好用的电商系统 #最好用的系统 #推荐的前十系统 #JAVA PHP 小程序 #以太网温湿度气体多参量传感器 #以太网多合一传感器 #以太网环境监测终端 #可定制气体监测模组 #流量监控 #Spring源码 #Spring AI #STDIO协议 #Streamable-HTTP #McpTool注解 #服务器能力 #AI助手 #轻量大模型 #paddleocr #iot #pencil #pencil.dev #设计 #Dify #轻量化 #低配服务器 #工具集 #ue4 #DedicatedServer #独立服务器 #专用服务器 #无人机 #MC #语义搜索 #嵌入模型 #Qwen3 #AI推理 #链表的销毁 #链表的排序 #链表倒置 #判断链表是否有环 #sentinel #journalctl #LobeChat #vLLM #GPU加速 #Triton #p2p #黑客技术 #挖漏洞 #日志分析 #intellij-idea #database #儿童AI #图像生成 #eBPF #web3 #集成学习 #EMC存储 #存储维护 #NetApp存储 #grafana #embedding #人脸识别 #人脸核身 #活体检测 #身份认证与人脸对比 #H5 #微信公众号 #kmeans #openlayers #bmap #tile #server #开发环境搭建 #ip #n8n解惑 #计算机现代史 #智慧校园解决方案 #智慧校园选型 #智慧校园采购 #智慧校园软件 #智慧校园专项资金 #智慧校园定制开发 #LangGraph #模型上下文协议 #MultiServerMCPC #load_mcp_tools #load_mcp_prompt #asp.net大文件上传 #asp.net大文件上传下载 #asp.net大文件上传源码 #ASP.NET断点续传 #asp.net上传文件夹 #SSH反向隧道 # Miniconda # Jupyter远程访问 #SSH别名 # 显卡驱动备份 #客户端 #DIY机器人工房 #uvicorn #uvloop #asgi #event #状态模式 #智能化测试 #质量效能 #skills #playwright #持续测试 #职业和发展 #企业存储 #RustFS #对象存储 #2026AI元年 #年度趋势 #信令服务器 #Janus #MediaSoup #ping通服务器 #读不了内网数据库 #bug菌问答团队 #GPU #AutoDL ##租显卡 #vuejs # 远程访问 # 服务器IP配置 #捷配 #pcb工艺 #Llama-Factory # 大模型推理 #Jetty # CosyVoice3 # 嵌入式服务器 #模块 #Android16 #音频性能实战 #音频进阶 #markdown #建站 #建筑缺陷 #红外 #wireshark #VS Code调试配置 #Deepoc #具身模型 #开发板 #未来 # 公钥认证 #收银台开源 #收银台接口 #商业开源 #K8s #镜像 #集群自动化 #空间计算 #原型模式 #题解 #图 #dijkstra #迪杰斯特拉 #戴尔服务器 #戴尔730 #装系统 #tdengine #涛思数据 #模型微调 #代理 #ajax #自动化运维 #工厂模式 #Proxmox VE #虚拟化 #海外短剧 #海外短剧app开发 #海外短剧系统开发 #短剧APP #短剧APP开发 #短剧系统开发 #海外短剧项目 #comfyui #网路编程 #百万并发 #rtmp #GATT服务器 #蓝牙低功耗 #银河麒麟部署 #银河麒麟部署文档 #银河麒麟linux #银河麒麟linux部署教程 #deepseek #SAM3 #江协 #瑞萨 #OLED屏幕移植 #Fun-ASR # 语音识别 # WebUI #密码 #cpp #CUDA #GNC #控制 #姿轨控 #hdfs #SSH公钥认证 # 安全加固 #ROS #SSH免密登录 #docker-compose #跨域 #发布上线后跨域报错 #请求接口跨域问题解决 #跨域请求代理配置 #request浏览器跨域 #React #Next #CVE-2025-55182 #RSC #游戏机 #JumpServer #UDP的API使用 #集成测试 #IFix #spring native #远程访问 #远程办公 #飞网 #安全高效 #配置简单 #旅游推荐管理系统 #旅游攻略 #typescript #振镜 #振镜焊接 #公共MQTT服务器 #screen 命令 #运维开发 #逆向工程 #claudeCode #content7 #xshell #host key # 目标检测 #chat #黑群晖 #虚拟机 #无U盘 #纯小白 #指针 #LVDS #高速ADC #DDR #视频 # 服务器配置 # GPU #openvino #手机检测 #课堂手机检测 #非标机械设计 #挖矿 #Linux病毒 #管道Pipe #system V #贴图 #材质 #设计师 #uvx #uv pip #npx #Ruff #个人博客 # 键鼠锁定 #jupyter #汇智网盘系统 #企业级云存储 #智能协作 #JavaScript #WinSCP 下载安装教程 #SFTP #FTP工具 #服务器文件传输 #muduo库 #GESP4级 #GESP四级 #sort #滑动窗口 #字符串 #nas #AI-native #音乐分类 #音频分析 #ViT模型 #Gradio应用 #鼠大侠网络验证系统源码 #SSH跳转 #TTS #go # IndexTTS # GPU集群 #娱乐 #计算机毕业设计 #程序定制 #毕设代做 #大作业 #课设 #Anaconda配置云虚拟环境 #数据迁移 #测速 #iperf #iperf3 #学术生涯规划 #CCF目录 #基金申请 #职称评定 #论文发表 #科研评价 #顶会顶刊 #powerbi #vivado license #CVE-2025-68143 #CVE-2025-68144 #CVE-2025-68145 #嵌入式编译 #ccache #distcc #带宽 #流量 #大带宽 #html5 #计算几何 #斜率 #方向归一化 #叉积 #cocos2d #图形渲染 #IT #技术 #智能体 #后端框架 #ARM64 # DDColor # ComfyUI #puppeteer #Fluentd #Sonic #日志采集 # 数字人系统 # 远程部署 #GLM-4.6V-Flash-WEB # AI视觉 # 本地部署 #restful #连接数据库报错 #视频去字幕 #Miniconda #Docker #flume #外卖配送 #DNS #Discord机器人 #云部署 #程序那些事 #Karalon #AI Test #YOLOv8 # Docker镜像 #运维工具 #YOLOFuse # Base64编码 # 多模态检测 #领域驱动 #SPA #单页应用 #服务器IO模型 #非阻塞轮询模型 #多任务并发模型 #异步信号模型 #多路复用模型 #SA-PEKS # 关键词猜测攻击 # 盲签名 # 限速机制 #ipmitool #BMC #模版 #函数 #类 #工程实践 #强化学习 #策略梯度 #REINFORCE #蒙特卡洛 #WEB #CMake #Make #C/C++ #swagger #IndexTTS2 # 阿里云安骑士 # 木马查杀 #同步WebServer服务器 #ESP32网页服务器 #轻量级http服务器 #ESP32物联网 #排序 # 高并发部署 #vps #simulink #寄存器 #aiohttp #asyncio #异步 #CLI #langgraph.json #软件 #本地生活 #电商系统 #商城 #vrrp #脑裂 #keepalived主备 #高可用主备都持有VIP #企业级存储 #网络设备 #SMP(软件制作平台) #EOM(企业经营模型) #应用系统 #软件需求 #学术写作辅助 #论文创作效率提升 #AI写论文实测 #飞牛NAS #NVR #EasyNVR #知识库 #项目申报系统 #项目申报管理 #项目申报 #企业项目申报 #C₃₂H₄₅N₇O₁₁S₂ #Anything-LLM #IDC服务器 #webpack #大模型应用 #API调用 #PyInstaller打包运行 #服务端部署 #欧拉 #Aluminium #Google #学工管理系统 #学工一体化平台 #学工软件二次开发 #学工平台定制开发 #学工系统服务商 #学工系统源头厂家 #智慧校园学工系统 #I/O #Lenyiin #Shiro #反序列化漏洞 #CVE-2016-4437 # 水冷服务器 # 风冷服务器 #二值化 #Canny边缘检测 #轮廓检测 #透视变换 #cocoa #React安全 #漏洞分析 #Next.js #AI生成 # outputs目录 # 自动化 #联机教程 #局域网联机 #局域网联机教程 #局域网游戏 #翻译 #开源工具 #SSH保活 #远程开发 #rdp #eclipse #elk #视觉检测 #决策树 #大模型部署 #mindie #ComfyUI # 推理服务器 #libosinfo #webgl #模拟退火算法 #Hadoop #npm #VPS #搭建 #土地承包延包 #领码SPARK #aPaaS+iPaaS #智能审核 #档案数字化 #eureka #turn #ICE #信创国产化 #达梦数据库 #nacos #银河麒麟aarch64 #MS #Materials #创业管理 #财务管理 #团队协作 #创始人必修课 #数字化决策 #经营管理 #国产PLM #瑞华丽PLM #瑞华丽 #PLM #网站 #截图工具 #批量处理图片 #图片格式转换 #图片裁剪 #dash #树莓派 #温湿度监控 #WhatsApp通知 #IoT #MySQL #rtsp #转发 #SMTP # 内容安全 # Qwen3Guard #X11转发 #可撤销IBE #服务器辅助 #私钥更新 #安全性证明 #双线性Diffie-Hellman #muduo #EventLoop #RXT4090显卡 #RTX4090 #深度学习服务器 #硬件选型 #vision pro #群晖 #音乐 #动态规划 #时间复杂度 #空间复杂度 # AI翻译机 # 实时翻译 #DDD #tdd #idm #私域运营 #sqlmap #web服务器 #插件 #策略模式 #r-tree #VibeVoice # 语音合成 # 云服务器 #心理健康服务平台 #心理健康系统 #心理服务平台 #心理健康小程序 # 远程运维 #性能测试 #LoadRunner #遛狗 #TFTP #数据访问 #编程语言 #SQL调优 #EXPLAIN #慢查询日志 #分布式架构 #dynadot #域名 #N8N #旅游 #北京百思可瑞教育 #百思可瑞教育 #北京百思教育 #log #NPU #MOXA #ms-swift # 一锤定音 # 大模型微调 #UOS #海光K100 #统信 #提词器 #spring ai #oauth2 #浏览器自动化 #python #6G #太赫兹 #无线通信 #频谱 #无线 #cascadeur #SSH代理转发 #夏天云 #夏天云数据 #大剑师 #nodejs面试题 #C2000 #TI #实时控制MCU #AI服务器电源 #经济学 #企业微信机器人 #本地大模型 #Qwen3-14B # 大模型部署 # 私有化AI #内网 #智能一卡通 #门禁一卡通 #梯控一卡通 #电梯一卡通 #消费一卡通 #一卡通 #考勤一卡通 #c++20 #快递盒检测检测系统 #远程桌面 #远程控制 #RK3576 #瑞芯微 #硬件设计 #攻防演练 #Java web #红队 #浏览器指纹 #opc ua #opc #ngrok # 环境迁移 #vp9 #API限流 # 频率限制 # 令牌桶算法 #工作 #TTS私有化 # 音色克隆 #gRPC #注册中心 #AutoDL使用教程 #AI大模型训练 #linux常用命令 #PaddleOCR训练 #edge #迭代器模式 #观察者模式 #智能家居 #网络配置实战 #Web/FTP 服务访问 #计算机网络实验 #外网访问内网服务器 #Cisco 路由器配置 #静态端口映射 #网络运维 #国企混改 #国企混改咨询 #国企混改战略规划 #曦望 # GLM-TTS # 数据安全 #istio #服务发现 #gateway #OSS #CDN #最佳实践 #视觉理解 #Moondream2 #多模态AI #TcpServer #accept #高并发服务器 #screen命令 #渗透测试 #网安应急响应 #LangFlow # 轻量化镜像 # 边缘计算 # GLM # 服务连通性 #青少年编程 #milvus #web server #请求处理流程 #门禁 #梯控 #智能梯控 #勒索病毒 #勒索软件 #加密算法 #.bixi勒索病毒 #数据加密 #OPCUA #CA证书 #星际航行 #agentic bi # 高并发 #论文复现 #opc模拟服务器 #数据恢复 #视频恢复 #视频修复 #RAID5恢复 #流媒体服务器恢复 #工程设计 #预混 #扩散 #燃烧知识 #层流 #湍流 #b/s架构 #移动学习平台 #tcp/ip #智能路由器 #Host #SSRF # 批量部署 # 大模型 # ms-swift #服务器线程 # SSL通信 # 动态结构体 #超算中心 #PBS #lsf #服务器开启 TLS v1.2 #IISCrypto 使用教程 #TLS 协议配置 #IIS 安全设置 #服务器运维工具 #报表制作 #职场 #数据可视化 #用数据讲故事 #语音生成 #mtgsig #美团医药 #美团医药mtgsig #美团医药mtgsig1.2 #个人助理 #数字员工 #Socket #套接字 #I/O多路复用 #字节序 #weston #x11 #x11显示服务器 #RSO #机器人操作系统 #漏洞挖掘 #Exchange #证书 #MapGIS #云服务 #云门户 #IGServer #KMS #slmgr #宝塔面板部署RustDesk #RustDesk远程控制手机 #手机远程控制 #铁路桥梁 #DIC技术 #箱梁试验 #裂纹监测 #四点弯曲 #节日 #ESP32编译服务器 #Ping #DNS域名解析 #麦克风权限 #访问麦克风并录制音频 #麦克风录制音频后在线播放 #用户拒绝访问麦克风权限怎么办 #uniapp 安卓 苹果ios #将音频保存本地或上传服务器 #moltbot #地理 #遥感 #IPv6 #面向对象 #MCP服务器注解 #异步支持 #方法筛选 #声明式编程 #自动筛选机制 #taro #AI应用编程 #dlms #dlms协议 #逻辑设备 #逻辑设置间权限 # REST API #JNI #芦笋提词器 #CCE #Dify-LLM #Flexus # keep-alive #安全威胁分析 #源码 #闲置物品交易系统 #期刊 #SCI #前端开发 #EN4FE #api #key #AI作画 #自由表达演说平台 #演说 #nfs #iscsi #AI Agent #开发者工具 #Minecraft #Minecraft服务器 #PaperMC #我的世界服务器 #范式 #UDP #国产开源制品管理工具 #Hadess #一文上手 #C #TCP服务器 #语音控制 #移动端h5网页 #调用浏览器摄像头并拍照 #开启摄像头权限 #拍照后查看与上传服务器端 #摄像头黑屏打不开问题 #ET模式 #非阻塞 #防排烟监控 #消防风机一体化 #BA楼宇自控 #DDC控制器 #IBMS集成系统 #入侵 #日志排查 #格式工厂 #KMS激活 # 硬件配置 #算力一体机 #ai算力服务器 #API # 模型训练 #租显卡 #训练推理 #synchronized #锁 #reentrantlock #LED #设备树 #GPIO #多进程 #python技巧 #coffeescript #CSDN #H3C #传统行业 #AI赋能 #bigtop #hdp #hue #kerberos #zotero #WebDAV #同步失败 #代理模式 #tornado #raid #raid阵列 #数智红包 #商业变革 #材料工程 #智能电视 #语义检索 #文本向量化 #GTE-Pro #企业AI #攻击溯源 #编程 #blender #warp #reactjs #proc #网络 #Go并发 #高并发架构 #Goroutine #系统设计 #鲲鹏 #net core #kestrel #web-server #asp.net-core #Syslog #系统日志 #日志监控 #生产服务器问题查询 #日志过滤 #Autodl私有云 #深度服务器配置 #math #homework #FASTMCP #多接口并发 #首页优化 #因果学习 #VoxCPM-1.5-TTS # 云端GPU # PyCharm宕机 #seata #TC/TM/RM #漏洞修复 #IIS Crypto #SIP服务器 #语音服务器 #VoIP #SIP协议 #交换机 #三层交换机 #高斯溅射 #MC群组服务器 #数字营销 #seo #HistoryServer #Spark #YARN #jobhistory #说话人验证 #声纹识别 #CAM++ #ZooKeeper #ZooKeeper面试题 #面试宝典 #深入解析 #云开发 #KMS 激活 #AI智能棋盘 #Rock Pi S #内存接口 # 澜起科技 # 服务器主板 #unix #一人公司 #独立开发者 #c++高并发 #CS2 #debian13 #BoringSSL #云计算运维 #asp.net上传大文件 #claude-code #高精度农业气象 #PTP_1588 #gPTP #农产品物流管理 #物流管理系统 #农产品物流系统 #农产品物流 # ARM服务器 # 鲲鹏 #4U8卡 AI 服务器 ##AI 服务器选型指南 #GPU 互联 #GPU算力 # 服务器迁移 # 回滚方案 #http头信息 #VSCode # SSH #uip #k8s #文件传输 #电脑文件传输 #电脑传输文件 #电脑怎么传输文件到另一台电脑 #电脑传输文件到另一台电脑 #Windows #性能 #RAM #文本生成 #CPU推理 #x86_64 #数字人系统 #开发实战 #贝叶斯优化深度学习 #MIMO #OFDM #技术原理 #通信算法 #进程等待 #wait #waitpid # 离线AI #算法备案 #IntelliJ IDEA #neo4j #NoSQL #Coturn #文件上传漏洞 #Kylin-Server #国产操作系统 #服务器安装 #短剧 #短剧小程序 #短剧系统 #微剧 #hibernate #nosql #结构与算法 #扩展屏应用开发 #SMARC #ARM #CTF #TLS协议 #HTTPS #运维安全 # 代理转发 #大学生 #万悟 #联通元景 # GPU服务器 # tmux #程序开发 #程序设计 #mvc #idc # 智能运维 # 性能瓶颈分析 #esp32 #mosquito #效率神器 #办公技巧 #自动化工具 #Windows技巧 #打工人必备 #Comate #bug #I/O模型 #水平触发、边缘触发 #多路复用 #服务器解析漏洞 #nodejs #云服务器选购 #Saas #NFC #智能公交 #服务器计费 #FP-增长 #outlook #错误代码2603 #无网络连接 #2603 #练习 #基础练习 #循环 #九九乘法表 #计算机实现 #数字孪生 #三维可视化 # 远程开发 # Qwen3Guard-Gen-8B #磁盘配额 #存储管理 #形考作业 #国家开放大学 #系统运维 #ETL管道 #向量存储 #数据预处理 #DocumentReader #C++ UA Server #SDK #跨平台开发 #esb接口 #走处理类报异常 #arm64 #SSH密钥 #SSH复用 #zygote #应用进程 #smtp #smtp服务器 #PHP #intellij idea #晶振 #WinDbg #Windows调试 #内存转储分析 #开源社区 #国产基础软件 #AI框架 #春秋云境 #CVE-2020-5515 #随机森林 #西门子 #汇川 #Blazor #cosmic #运维 #safari #OpenManage #AI视频创作系统 #AI视频创作 #AI创作系统 #AI视频生成 #AI工具 #AI创作工具 #fs7TF #华为od机试 #华为od机考 #华为od最新上机考试题库 #华为OD题库 #od机考题库 #AI+ #coze #AI入门 #计组 #数电 #昇腾300I DUO #铬锐特 #uv胶 #紫外线胶水 #光固化胶水 #胶粘剂 #Python3.11 #AI 推理 #NV #npu #处理器 # 远程连接 #上下文工程 #langgraph #意图识别 #ansys #ansys问题解决办法 #统信UOS #服务器操作系统 #win10 #qemu #远程软件 #WRF #WRFDA #teamviewer #HarmonyOS #rsync # 数据同步 #vertx #vert.x #vertx4 #runOnContext #分布式数据库 #集中式数据库 #业务需求 #选型误 #传感器 #MicroPython # Connection refused #Socket网络编程 #机器人学习 #CosyVoice3 # IP配置 # 0.0.0.0 #雨云服务器 #教程 #MCSM面板 #Apple AI #Apple 人工智能 #FoundationModel #Summarize #SwiftUI #SSH跳板机 # Python3.11 #一周会议与活动 #ICLR #CCF #appche #搜狗输入法 #语音合成 #c #算法笔记 #路由器 #主板 #电源 #OpenHarmony #CS336 #Assignment #Experiments #TinyStories #Ablation #实时音视频 #SEW #赛威 #SEW变频器 #ftp #sftp #cpu #量子计算 #智慧社区 #管理系统 #华为机试 #PN 结 #ARMv8 #内存模型 #内存屏障 #ArkUI #ArkTS #鸿蒙开发 #RWK35xx #语音流 #实时传输 #node #反向代理 #uniapp #合法域名校验出错 #服务器域名配置不生效 #request域名配置 #已经配置好了但还是报错 #uniapp微信小程序 #Java生成PDF #Freemarker转PDF #PDFBox转图片 #HTML转PDF乱码解决 #AE #手机h5网页浏览器 #安卓app #苹果ios APP #手机电脑开启摄像头并排查 #ASR #SenseVoice #canvas层级太高 #canvas遮挡问题 #盖住其他元素 #苹果ios手机 #安卓手机 #调整画布层级 #AITechLab #cpp-python #CUDA版本 #samba # 批量管理 #系统安装 #express #cherry studio #gmssh #宝塔 #POC #问答 #交付 #图书馆 #自习室 #pxe #游戏服务器断线 #基础语法 #标识符 #常量与变量 #数据类型 #运算符与表达式 #Archcraft #MinIO #Linly-Talker # 数字人 # 服务器稳定性 #全文检索 #总体设计 #电源树 #框图 #free #vmstat #sar #向量嵌入 #r语言 #边缘AI # Kontron # SMARC-sAMX8 #okhttp #STDIO传输 #SSE传输 #WebMVC #WebFlux #程序员转型 #人脸活体检测 #live-pusher #动作引导 #张嘴眨眼摇头 #苹果ios安卓完美兼容 #gnu #remote-ssh #小艺 #搜索 #glances #duckdb #AI应用 #高考 #多模态 #微调 #超参 #LLamafactory #阿里云RDS #Linux多线程 #Spring AOP #cesium #可视化 #V11 #kylinos #信息收集 # 模型微调 #gpio #Langchain-Chatchat # 国产化服务器 # 信创 #VMware创建虚拟机 #Cesium #交互设计 #智能避障 #docker安装seata #Qwen3-VL # 服务状态监控 # 视觉语言模型 #m3u8 #HLS #移动端H5网页 #APP安卓苹果ios #监控画面 直播视频流 #Zabbix #tekton #人脸识别sdk #视频编解码 #传媒 #隐函数 #常微分方程 #偏微分方程 #线性微分方程 #线性方程组 #非线性方程组 #复变函数 #UDP服务器 #recvfrom函数 #身体实验室 #健康认知重构 #微行动 #NEAT效应 #亚健康自救 #ICT人 #Termux #Samba #Ward #直流无刷电机 #六步换相 #递归 #线性dp #日志模块 #VMware Workstation16 #开关电源 #热敏电阻 #PTC热敏电阻 #读卡器 #门禁读卡器 #梯控读卡器 #IC卡读卡器 #音诺ai翻译机 #AI翻译机 # Ampere Altra Max #sklearn # 权限修复 #WAN2.2 #大模型呼叫 #外呼系统 #AI外呼 #外呼系统推荐 #智能客服 #外呼 #银河麒麟服务器系统 #奈飞工厂算法挑战赛 #SQL注入主机 #xml #GitPuk #国产开源免费代码管理工具 #Arbess #cicd工具 #H5网页 #网页白屏 #H5页面空白 #资源加载问题 #打包部署后网页打不开 #HBuilderX #A2A #GenAI #前端界面 #VMWare Tool #回归 #网络安全大赛 #devops #智能制造 #供应链管理 #工业工程 #库存管理 #实时检测 #DAG #NSP #下一状态预测 #aigc #算力建设 #HarmonyOS APP #RK3588 #RK3588J #评估板 #核心板 #嵌入式开发 #EtherCAT #XMC4800 #工业自动化 #lucene #声源定位 #MUSIC #AI电商客服 #resnet50 #分类识别训练 #b树 #HTML #web前端 #网页开发 # ControlMaster #ServBay # 树莓派 # ARM架构 #Xshell #Finalshell #生物信息学 #组学 #Spire.Office #隐私合规 #网络安全保险 #法律风险 #风险管理 #memory mcp #Cursor #容斥原理 # 网络延迟 #ranger #MySQL8.0 #智能体对传统行业冲击 #行业转型 #代理服务器 #Matrox MIL #二次开发 #水性三防漆 #UV三防漆 #有机硅三防漆 #聚氨酯三防漆 #醇酸树脂三防漆 #丙烯酸三防漆 #0day漏洞 #DDoS攻击 #漏洞排查 #懒汉式 #恶汉式 #odoo #win11 #在线培训系统 # DIY主机 # 交叉编译 ##python学习笔记 #python中with语句详解 #基金 #股票 #Zernike #hcipy #光学设计 #像差仿真 #智能合约 #车载嵌入式 #ossinsight #Gateway #认证服务器集成详解 #adobe #小智 #usb #通信协议 #ocr #lprnet #车牌识别 #crnn #车牌检测 # child_process #分子动力学 #化工仿真 #session #安全性测试 #标准化事件委托 #工序流程工艺路径 #业务流程标准化 #电子电气架构 #系统工程与系统架构的内涵 #Routine #starrocks #RTSP #Live555 #流媒体服务器 #L6 #L10 #L9 #千问 #测试网 #erc-20 #独立链 #polkadot #Beidou #北斗 #SSR #composer #symfony #java-zookeeper #poll #AirDrop #远程更新 #缓存更新 #多指令适配 #物料关联计划 #个性化推荐 #BERT模型 #Prometheus #DooTask #防毒面罩 #防尘面罩 #Highcharts #插件封装 #个人电脑 #思爱普 #SAP S/4HANA #ABAP #NetWeaver #r语言-4.2.1 #语言 #泛型 #接口 #抽象类 #面向对象设计 #人形机器人 #人机交互 #软件构建 #统信操作系统 #vncdotool #链接VNC服务器 #如何隐藏光标 #电梯 #电梯运力 #电梯门禁 #数据报系统 #FHSS #bond #服务器链路聚合 #网卡绑定 #IO编程 #omv8 #can # 高温监控 #AI工具集成 #容器化部署 #2025年 #AI教程 #CMC #自动化巡检 #YOLO识别 #YOLO环境搭建Windows #YOLO环境搭建Ubuntu #jquery #fork函数 #进程创建 #进程终止 #JADX-AI 插件 #boltbot #DuckDB #协议 #Arduino BLDC #核辐射区域探测机器人