Seq-locks vs RCU vs Per-CPU用例

Gre*_*etr 5 kernel device-driver linux-kernel

我试图了解一些内核同步机制的不同用例(顺序锁与RCU(读取 - 复制 - 更新)与每CPU锁)建议用于编写设备驱动程序或内核模块.任何例子将不胜感激.

ask*_*skb 6

顺序锁定这是一种聪明的锁定方法,其中编写者获得自旋锁,读者可以完全避免锁定,代价是不得不重复不一致的读取.这种方法最适用于经常读取数据但很少更新的情况.这里多次读取不会产生副作用,这与任何读写器锁定和更新类似,不会同时混淆读者.搜索使用/包含API/headers/data结构的内核代码:

#include <linux/seqlock.h>
typedef struct {
    unsigned seq;  ===> seq is incremented every-time a writer acquires a lock
    spinlock_t lock;
} seqlock_t;
write_seqlock(), write_sequnlock()
read_seqlock(), read_sequnlock()
Run Code Online (Sandbox Code Playgroud)

注意:每次编写器获取锁定时,seq no都会递增,读取器,记录seq编号的副本,然后执行读取,重新检查序列号(使用read_seqretry()),如果seq编号不一致,然后读者必须重新阅读.对于有争议的读者来说,冗余读取并不比"旋转"CPU更糟糕,对于无争议的读者来说,可以一起避免自旋锁.

RCU(读取 - 复制 - 更新)分隔了更新和回收信息,读者和编写者都可以完全避免锁定.RCU主要用于处理动态分配的数据结构,例如链表.RCU编写器不会修改数据,而是分配一个新元素,它使用更新的数据进行初始化.

PER-CPU变量这些主要用于CPU特定结构,可以避免全局锁定.请注意,这些仍必须与ISR同步.同理:

#include <linux/percpi.h>
DEFINE_PER_CPU()
per_cpu(var,cpu)
get_cpu_var(), put_cpu_var()
Run Code Online (Sandbox Code Playgroud)