内核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_spinlocked
中的函数kfifo_in
最终会调用kfifo_copy_in
函数,我的问题是,为什么还要使用spin_lock_irqsave
,smp_wmb
?CPU获得自旋锁使其他CPU停顿,因此它可以独占地修改变量和数据地址,当它解锁时,其他CPU可以获得最新的数据和数据地址?为什么需要smp_wmb
?