c - linux 内核的 ext2 函数 ext2_statfs() 中的内存屏障

标签 c assembly linux-kernel memory-barriers ext2

谁能解释为什么 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_wmbsmp_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 属性的任何类似写访问都会事先自旋锁定它(使用相同的自旋锁)。它还增强了两个操作必须按此顺序完成的事实。

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

关于c - linux 内核的 ext2 函数 ext2_statfs() 中的内存屏障,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25590256/

相关文章:

windows - 带有 User32.dll 的 LoadLibraryA 在 ntdll.dll(x64 程序集)中崩溃

c - 是否可以删除/proc/<pid>/fd中的fd链接?

c - 如何向由 createProcess() 函数创建的进程调用的批处理文件提供参数?

c - getchar() 的意外输出

计算全局偏移表在arm文字池中的地址

c++ - android ndk asm编译错误: inconsistent operand constraints in an 'asm'

c - 修改内核模块中的控制寄存器

c - 如何从 Linux 内核空间向用户空间发送信号以通知输入硬件事件

c - C 中的结构成员排序优势

c - dirent 结构处理的文件/目录的最大数量