【问题标题】:memory barrier in linux kernel's ext2 function ext2_statfs()Linux内核的ext2函数ext2_statfs()中的内存屏障
【发布时间】:2014-10-24 18:18:33
【问题描述】:

谁能解释一下为什么linux内核的ext2函数 int ext2_statfs (struct dentry * dentry, struct kstatfs * buf)

问题smp_rmb()smp_wmb()else if (sbi->s_blocks_last != le32_to_cpu(es->s_blocks_count)) { 案例?

这是在上游内核提交 2235219b7721b8e74de6841e79240936561a2b63 中添加的,它省略了不必要的 .statfs 计算,但无法理解为什么要添加内存屏障。

【问题讨论】:

  • 谢谢,添加到 kernel.org 的链接。

标签: c assembly linux-kernel memory-barriers ext2


【解决方案1】:

由于函数以执行 spin_lock 开始(并在最后解锁),

spin_lock(&sbi->s_lock);

它受到保护以防止并发访问。那么为什么需要smp_wmbsmp_rmb...

至于写操作,

    sbi->s_overhead_last = overhead;
    smp_wmb();
    sbi->s_blocks_last = le32_to_cpu(es->s_blocks_count);

似乎 smp_wmb 会阻止任何编译器或处理器优化(因为在内存访问方面两次写入之间没有依赖关系),这会改变两个分配的顺序。由于 ext2_statfs 中没有并发访问,因此问题可能发生在另一个可能具有类似行为的函数中,并检查是否存在块计数更改,如果没有,则使用来自 sbi->s_overhead_last 的开销- 如果此时另一个线程在另一个函数中,在两个写操作的中间顺序错误,那将是错误的。

这可能是一种预防措施,因为对 sbi 属性的任何类似写入访问都会事先spin_lock(使用相同的自旋锁)。它还增强了两个操作必须按此顺序完成的事实。

至于读取访问的需求不太明显,需要进一步分析 sbies 块之间的依赖关系。

【讨论】:

  • 由于自旋锁,确实没有并发。但是,先前执行相同函数(或修改相关数据的任何其他内容)的结果可能对当前 cpu 尚不可见。屏障确保此函数始终看到当前状态(由于锁定而无法更改),并确保在释放锁定之前提交结果。
  • 对,你的两个回答/评论对我来说都很有意义,但由于自旋锁(我相信)对许多拱门也有 mb 的影响,不应该写类似函数的人(如果检查和更新类似)将来可能只使用相同的原始自旋锁(超级块->锁)而不是关心编译器可能优化的排序?
  • # 我相信这就是 ring0 答案的后面部分所暗示的。 -> “这可能是一种预防措施,因为任何类似的对 sbi 属性的写访问都会事先将其自旋锁定(使用相同的自旋锁)。”
猜你喜欢
  • 1970-01-01
  • 2013-06-03
  • 2011-12-15
  • 2015-04-01
  • 2011-09-27
  • 1970-01-01
  • 2017-08-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多