Memory protection in linux kernel ext2 function ext2_statfs ()

Can anyone explain why the linux kernel ext2 function int ext2_statfs (struct dentry * dentry, struct kstatfs * buf)

produces smp_rmb()

also smp_wmb()

in else if (sbi->s_blocks_last != le32_to_cpu(es->s_blocks_count)) {

case?

This was added to the original kernel commit 2235219b7721b8e74de6841e79240936561a2b63 which doesn't account for the unnecessary calculation of .statfs, but can't figure out why memory barriers were added.

+3


source to share


1 answer


Since the function starts by executing spin_lock (and unlocks at the end),

spin_lock(&sbi->s_lock);

      

it is protected from concurrent access. So why do we need smp_wmb and smp_rmb ...

As for the write operation,



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

      

it looks like smp_wmb will prevent any compiler or processor optimization (since there is no dependency between the two entries in terms of memory access) that will reverse the order of the two assignments. Since ext2_statfs does not have concurrent accesses, the problem may arise in another function that may have similar behavior, and check if there is a change in the number of blocks, and if not, use the overhead from sbi->s_overhead_last

- which would be wrong if another thread at the same time would be in another function, in the middle of two writes in the wrong order.

This is probably a precaution, as any similar write access to sbi properties will trigger it (with the same spinlock) beforehand. It also reinforces the fact that the two operations must be performed in this order.

With regard to read access, the need is less obvious and will require further analysis of the dependencies between the sbi and es blocks.

+3


source







All Articles