为什么 kfifo 在 4.9.37 版本的内核中即使使用 spin_lock_irqsave 也需要 smp_wmb

问题描述 投票:0回答:1

kernel lib/kfifo.c中有两段代码如下:

#define kfifo_in_spinlocked(fifo, buf, n, lock) \
({ \
    unsigned long __flags; \
    unsigned int __ret; \
    spin_lock_irqsave(lock, __flags); \
    __ret = kfifo_in(fifo, buf, n); \
    spin_unlock_irqrestore(lock, __flags); \
    __ret; \
})
static void kfifo_copy_in(struct __kfifo *fifo, const void *src,
    unsigned int len, unsigned int off) {
    unsigned int size = fifo->mask + 1;
    unsigned int esize = fifo->esize;
    unsigned int l;

    off &= fifo->mask;
    if (esize != 1) {
        off *= esize;
        size *= esize;
        len *= esize;
    }
    l = min(len, size - off);

    memcpy(fifo->data + off, src, l);
    memcpy(fifo->data, src + l, len - l);
    /*
     * make sure that the data in the fifo is up to date before
     * incrementing the fifo->in index counter
     */
    smp_wmb();
}

kfifo_in

中的函数
kfifo_in_spinlocked
最终会调用
kfifo_copy_in
函数,我的问题是为什么即使有了
spin_lock_irqsave
,还需要
smp_wmb
? cpu获得自旋锁会使其他cpu停顿,因此它可以独占修改变量和数据地址,当它解锁时,其他cpu可以获取最新的数据和数据地址吗?为什么需要
smp_wmb

c linux linux-kernel queue barrier
1个回答
0
投票
实际上,kfifo 在 SPSC 模型中提供了无锁访问(

Single Producer Single Consumer)。内存屏障适用于来自 readerwriter 的并发访问。

如果有多个生产者(编写者),则需要额外的

编写者之间的同步,因此一次只有一个编写者处于活动状态。

函数

kfifo_in_spinlocked

提供了一种在编写器之间进行同步的方法:自旋锁。

实际上,锁定方面在

kfifo.h 标头的最顶部进行了描述:

/* * Note about locking: There is no locking required until only one reader * and one writer is using the fifo and no kfifo_reset() will be called. * kfifo_reset_out() can be safely used, until it will be only called * in the reader thread. * For multiple writer and one reader there is only a need to lock the writer. * And vice versa for only one writer and multiple reader there is only a need * to lock the reader. */
    
© www.soinside.com 2019 - 2024. All rights reserved.