什么是RCU:用法

这篇文章  What is RCU? Part 2: Usage

作者:

Paul E. McKenney, IBM Linux Technology Center

这篇文章主要通过与几以下几类机制的比较,深入对RCU进行了分析:

  1. RCU与读写锁机制;
  2. RCU是一种严格引用计数机制 Restricted Reference-Counting Mechanism
  3. RCU与GC机制;
  4. RCU与Existence guarantees(出自论文Gamsa等。[PDF]
  5. RCU是一种事件等待机制;

RCU优势:

  • 性能优势:实验中与读写机制rwlock比较, 随着CPU增加RCU CPU开销没有明显增长;
  • 死锁免疫(Deadlock Immunity):由于读取端没有阻塞, 理论上不会有死锁。
  • 实时性、低延时:同样也是由于RCU读端的不阻塞,使他有更出色的实时性和低延时。
  • RCUreader与updater同时运行Comparison of RCU and rwlock update latency.

rwlock保证读者总是读到更新后的数据, 但是作者也提到了现实中类似路由表的应用, 对于旧数据影响并时不时很大,而rwlock这种机制也依赖于reader/writer优先级的设定

  • 可以方便的替换rwlock
 1 struct el {                          1 struct el {
 2   struct list_head list;             2   struct list_head list;
 3   long key;                          3   long key;
 4   spinlock_t mutex;                  4   spinlock_t mutex;
 5   int data;                          5   int data;
 6   /* Other data fields */            6   /* Other data fields */
 7 };                                   7 };
 8 rwlock_t listmutex;                  8 spinlock_t listmutex;
 9 struct el head;                      9 struct el head;
 1 int search(long key, int *result)    1 int search(long key, int *result)
 2 {                                    2 {
 3   struct list_head *lp;              3   struct list_head *lp;
 4   struct el *p;                      4   struct el *p;
 5                                      5
 6   read_lock(&listmutex);             6   rcu_read_lock();
 7   list_for_each_entry(p, head, lp) { 7   list_for_each_entry_rcu(p, head, lp) {
 8     if (p->key == key) {             8     if (p->key == key) {
 9       *result = p->data;             9       *result = p->data;
10       read_unlock(&listmutex);      10       rcu_read_unlock();
11       return 1;                     11       return 1;
12     }                               12     }
13   }                                 13   }
14   read_unlock(&listmutex);          14   rcu_read_unlock();
15   return 0;                         15   return 0;
16 }                                   16 }
 1 int delete(long key)                 1 int delete(long key)
 2 {                                    2 {
 3   struct el *p;                      3   struct el *p;
 4                                      4
 5   write_lock(&listmutex);            5   spin_lock(&listmutex);
 6   list_for_each_entry(p, head, lp) { 6   list_for_each_entry(p, head, lp) {
 7     if (p->key == key) {             7     if (p->key == key) {
 8       list_del(&p->list);            8       list_del_rcu(&p->list);
 9       write_unlock(&listmutex);      9       spin_unlock(&listmutex);
                                       10       synchronize_rcu();
10       kfree(p);                     11       kfree(p);
11       return 1;                     12       return 1;
12     }                               13     }
13   }                                 14   }
14   write_unlock(&listmutex);         15   spin_unlock(&listmutex);
15   return 0;                         16   return 0;
16 }                                   17 }

                   example taken from Wikipedia.

  • 可以方便的替换rwlock
  • 参考计数机制 Reference-Counting Mechanism:看上去和rwlock模式一致
 
 1 rcu_read_lock();  /* acquire reference. */
  2 p = rcu_dereference(head);
  3 /* do something with p. */
  4 rcu_read_unlock();  /* release reference. */
  1 spin_lock(&mylock);
  2 p = head;
  3 head = NULL;
  4 spin_unlock(&mylock);
  5 synchronize_rcu();  /* Wait for all references to be released. */
  6 kfree(p);

但是由于要求读不阻塞, 所以在与rwlock进行性能比较时大概在4个cpu时rcu与rwlock的cpu开销已经趋于一致。

  • RCU 批量参考计数机制,由于器轻量级的读取,对于大量数据结构生成锁这里还提到 SRCU

RCU的核心是提供以下功能的API:

  1. 对新数据一个订阅发布机制;
  2. 等待订阅这完成;
  3. 多版本的发布不破坏现有订阅进程的并发读取。

作者认为 RCU可以应用于读写锁,引用计数,存在保证 等场景。

这篇文章是发表于2007年, 在后续linux kernel实践过程中遇到了很多实际问题, RCU’s First-Ever CVE, and How I Lived to Tell the Tale          这个演讲中描述了RCU 相关结构的演进,还有详细的修复CVE列表。

参考:

Linux 2.6内核中新的锁机制–RCU


							

Be First to Comment

发表回复