谁能解释为什么 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 计算,但无法理解为什么要添加内存屏障。
最佳答案
由于该函数通过执行spin_lock(并在最后解锁)开始,
spin_lock(&sbi->s_lock);
它受到保护以防止并发访问。那么为什么需要 smp_wmb 和 smp_rmb...
至于写操作,
sbi->s_overhead_last = overhead;
smp_wmb();
sbi->s_blocks_last = le32_to_cpu(es->s_blocks_count);
看起来 smp_wmb 会阻止任何编译器或处理器优化(因为在内存访问方面两次写入之间没有依赖性),这会改变两个分配的顺序。由于 ext2_statfs 中没有并发访问,问题可能发生在另一个可能具有类似行为的函数中,并检查是否有 block 计数更改,如果没有,则使用 的开销sbi->s_overhead_last
- 如果此时另一个线程在另一个函数中,以错误的顺序处于两个写入操作的中间,这将是错误的。
这可能是一种预防措施,因为对 sbi 属性的任何类似写访问都会事先自旋锁定它(使用相同的自旋锁)。它还增强了两个操作必须按此顺序完成的事实。
至于读取访问,需求不太明显,需要进一步分析 sbi 和 es block 之间的依赖关系。
关于c - linux 内核的 ext2 函数 ext2_statfs() 中的内存屏障,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25590256/