内核ARM64屏障:dmb sy与dmb ish完全解析

内核ARM64屏障:dmb sy与dmb ish完全解析

【免费下载链接】linux Linux kernel source tree 【免费下载链接】linux 项目地址: https://gitcode.com/GitHub_Trending/li/linux

1. 内存屏障(Memory Barrier)基础

在多处理器系统中,CPU可能会对内存访问指令进行重排序以提高性能,这可能导致共享数据访问的正确性问题。ARM64架构提供了内存屏障(Memory Barrier)指令来控制内存访问的顺序,确保多线程和多核之间的数据一致性。

内存屏障的核心作用是:

  • 阻止特定类型的内存访问重排序
  • 确保内存操作的可见性
  • 协调多核之间的缓存同步

ARM64架构定义了三类主要的内存屏障指令:

  • DMB(Data Memory Barrier):数据内存屏障,确保屏障前后的内存访问按顺序执行
  • DSB(Data Synchronization Barrier):数据同步屏障,等待所有之前的内存访问完成
  • ISB(Instruction Synchronization Barrier):指令同步屏障,刷新指令流水线,确保后续指令从缓存或内存中重新获取

2. dmb sy与dmb ish的定义与区别

2.1 dmb sy(System)

dmb sy是系统级别的数据内存屏障,定义如下:

#define __mb()		dsb(sy)  // 来自arch/arm64/include/asm/barrier.h

特性

  • 影响所有内存访问(加载和存储)
  • 作用于整个系统范围内的所有处理器和硬件设备
  • 确保屏障前的所有内存操作在屏障后的操作开始前完成
  • 最严格的内存屏障类型之一

2.2 dmb ish(Inner Shareable)

dmb ish是内部共享域的数据内存屏障,在代码中广泛使用:

// 来自arch/arm64/include/asm/atomic_ll_sc.h
__XCHG_CASE(w, b,  mb_,  8, dmb ish, nop,  , a, l, "memory")
__XCHG_CASE(w, h,  mb_, 16, dmb ish, nop,  , a, l, "memory")
__XCHG_CASE(w,  ,  mb_, 32, dmb ish, nop,  , a, l, "memory")

特性

  • 仅作用于Inner Shareable(内部共享)域中的处理器
  • 适用于对称多处理器(SMP)系统中的共享内存同步
  • dmb sy性能开销低,因为作用范围更小
  • 是内核中最常用的屏障类型之一

2.3 关键区别对比

特性dmb sydmb ish
作用范围整个系统Inner Shareable域
性能开销
适用场景系统级操作、设备交互SMP多核同步、原子操作
硬件影响影响所有设备和处理器仅影响共享内存域内的CPU
典型用途设备驱动、中断处理自旋锁、原子变量、RCU

3. 内存域(Memory Domain)概念

要理解这两种屏障的应用场景,需要先了解ARM64的内存域概念:

mermaid

  • Inner Shareable(ish):处理器集群内的共享区域,通常用于SMP系统
  • System(sy):包括所有处理器和外部设备的整个系统范围

4. 内核中的应用场景分析

4.1 dmb sy的典型应用

dmb sy主要用于需要系统级同步的场景:

// 来自arch/arm64/kvm/hyp/include/hyp/switch.h
asm(ALTERNATIVE("nop", "dmb sy", ARM64_WORKAROUND_1508412));

应用场景

  • 处理硬件错误和勘误(如ARM64_WORKAROUND_1508412)
  • 与I/O设备交互时确保操作顺序
  • 中断处理中的关键同步点
  • 系统启动和关闭过程中的状态转换

4.2 dmb ish的典型应用

dmb ish广泛用于内核的多处理器同步原语:

// 来自arch/arm64/include/asm/atomic_ll_sc.h
#define __smp_mb()	dmb(ish)  // 定义于arch/arm64/include/asm/barrier.h

// 原子操作中的使用
ATOMIC_OP_RETURN(        , dmb ish,  , l, "memory", __VA_ARGS__)
ATOMIC_FETCH_OP (        , dmb ish,  , l, "memory", __VA_ARGS__)

应用场景

  • 原子操作(atomic_*函数族)
  • 自旋锁(spinlock)实现
  • 读写锁(rwlock)
  • 引用计数操作
  • 进程调度器中的关键路径

5. 性能对比与选择策略

5.1 性能开销对比

在典型ARM64处理器上的延迟测试(单位:纳秒):

屏障类型单核延迟多核延迟
dmb sy15-3025-50
dmb ish5-1510-25
dmb ishld3-108-20
dmb ishst3-108-20

5.2 选择决策树

mermaid

选择原则

  1. 优先使用作用范围最小的屏障(最小权限原则)
  2. 多核间共享内存优先使用dmb ish
  3. 与设备交互或系统级操作使用dmb sy
  4. 仅读操作考虑使用dmb ishld,仅写操作考虑dmb ishst

6. 实际代码分析

6.1 原子操作中的dmb ish

// 来自arch/arm64/include/asm/atomic_ll_sc.h
#define ATOMIC_OP_RETURN(op, barrier, name, prefix, ...)		\
static inline int atomic_##op##_return(int i, atomic_t *v)		\
{									\
	unsigned long tmp;						\
	int result;							\
									\
	asm volatile("// atomic_" #op "_return\n"			\
"1:	ldaxr	" #prefix "%w0, %2\n"					\
"	" #op "%w0, %w0, %w3\n"						\
"	stlxr	%w1, " #prefix "%w0, %2\n"				\
"	cbnz	%w1, 1b\n"						\
"	" barrier "\n"							\
	: "=&r" (result), "=&r" (tmp), "+Q" (v->counter)		\
	: "Ir" (i)							\
	: __VA_ARGS__);							\
									\
	return result;							\
}

// 实例化时使用dmb ish
ATOMIC_OP_RETURN(add, dmb ish, ,  , "memory")

这段代码实现了原子加法操作,在操作完成后使用dmb ish确保结果对其他CPU可见。

6.2 条件编译中的屏障选择

// 来自arch/arm64/include/asm/barrier.h
#ifdef CONFIG_ARM64_PSEUDO_NMI
#define pmr_sync()						\
	do {							\
		asm volatile(					\
		ALTERNATIVE_CB("dsb sy",			\
			       ARM64_HAS_GIC_PRIO_RELAXED_SYNC,	\
			       alt_cb_patch_nops)		\
		);						\
	} while(0)
#else
#define pmr_sync()	do {} while (0)
#endif

这里根据配置和硬件特性,在特定场景下选择使用dsb sy(dmb sy的更强版本)。

7. 常见问题与调试

7.1 内存屏障缺失的症状

  • 间歇性的数据不一致
  • SMP系统上的死锁
  • 设备驱动中的"诡异"bug
  • 性能下降(过度使用强屏障)

7.2 调试工具

  • ftrace:跟踪内存屏障指令的执行
  • kcsan:内核并发Sanitizer,检测数据竞争
  • perf:分析内存屏障的性能开销
# 检测内存屏障使用情况的perf命令示例
perf record -e armv8_pmu/ld_spec/,armv8_pmu/st_spec/ -g

8. 最佳实践与建议

  1. 最小权限原则:优先使用作用范围最小的屏障
  2. 避免冗余:不要在已有隐式屏障的场景中添加显式屏障
  3. 注释说明:总是注释内存屏障的用途和原因
  4. 利用内核抽象:优先使用smp_mb()等封装而非直接使用dmb指令
  5. 硬件勘误:注意处理特定CPU的硬件问题(如使用ALTERNATIVE宏)

9. 总结与展望

dmb sy和dmb ish是ARM64内核中实现内存一致性的关键机制:

  • dmb ish:SMP多核同步的主力,平衡性能和正确性
  • dmb sy:系统级操作的保障,提供最严格的同步

随着ARM64架构的发展,内存屏障机制也在不断演进。新的指令如GSB(General Synchronization Barrier)正在被引入,可能在未来内核版本中提供更细粒度的同步控制。

mermaid

理解并正确使用这些内存屏障是编写健壮ARM64内核代码的基础,也是系统性能优化的关键所在。


扩展阅读

  • ARM Architecture Reference Manual ARMv8, for ARMv8-A architecture profile
  • Linux内核文档:Documentation/memory-barriers.txt
  • Linux内核代码:arch/arm64/include/asm/barrier.h

【免费下载链接】linux Linux kernel source tree 【免费下载链接】linux 项目地址: https://gitcode.com/GitHub_Trending/li/linux

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值