什么是RCU :API

这篇文章 RCU part 3: the RCU API 作者: Paul E. McKenney, IBM Linux Technology Center 做为 “What is RCU”系列文章的最后一篇, 第三篇文章主要介绍了RCU API设计 基本操作 rcu_read_lock() 读者在读取由RCU保护的共享数据时使用该函数标记它进入读端临界区。 rcu_read_unlock() 该函数与rcu_read_lock配对使用,用以标记读者退出读端临界区。 synchronsize_rcu() 该函数由RCU写端调用,它将阻塞写者,直到经过grace period后,即所有的读者已经完成读端临界区,写者才可以继续下一步操作。 call_rcu() 写端调用不会阻塞 链表操作 list_for_each_entry_rcu() 链表遍历 list_add_rcu() list_add_tail_rcu() list_del_rcu() list_replace_rcu() list_splice_init_rcu() 链表更新 作者对RCU判断是会在 the reader-writer-locking(读写锁), reference-counting(引用技术), and existence-guarantee constructs(存在保证结构)有更多的扩展。 更新 文章中列的API后续又更新到2010,2014,2019版本。 实验 rcu_example 是GitHub一个关于RCU调用的代码。 参考 Linux 2.6内核中新的锁机制–RCU

2019-06-15 · 1 min · 55 words

什么是RCU:用法

这篇文章 What is RCU? Part 2: Usage 作者: Paul E. McKenney, IBM Linux Technology Center , 这篇文章主要通过与几以下几类机制的比较,深入对RCU进行了分析: RCU与读写锁机制; RCU是一种严格引用计数机制 Restricted Reference-Counting Mechanism RCU与GC机制; RCU与Existence guarantees(出自论文Gamsa等。[PDF]) RCU是一种事件等待机制; RCU优势: 性能优势:实验中与读写机制rwlock比较, 随着CPU增加RCU CPU开销没有明显增长; 死锁免疫(Deadlock Immunity):由于读取端没有阻塞, 理论上不会有死锁。 实时性、低延时:同样也是由于RCU读端的不阻塞,使他有更出色的实时性和低延时。 RCUreader与updater同时运行 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开销已经趋于一致。 ...

2019-06-12 · 2 min · 380 words

什么是RCU

这篇文章What is RCU, Fundamentally? 作者: Paul E. McKenney, IBM Linux Technology Center , Jonathan Walpole, Portland State University Department of Computer Science RCU : read-copy-update (RCU) is a synchronization mechanism based on mutual exclusion. 对于RCU机制保护下的数据, 读数据不需要获得任何锁或者很小代价的开销就可以访问, 对于写者需要先拷贝一份副本, 然后修改,最后使用一个回调(callback)机制在适当的时机把指向原来数据的指针重新指向新的被修改的数据。这个时机就是所有引用该数据的CPU都退出对共享数据的操作。 本文主要介绍RCU同步机制的三个部分: 针对插入操作的发布订阅机制; 针对删除操作的等待预先启动读者完成机制; 维护最新更新对象多个版本; 文章中以链表为例介绍了RCU处理过程: 删除情况下保持多版本: 1 struct foo { 2 struct list_head list; 3 int a; 4 int b; 5 int c; 6 }; 7 LIST_HEAD(head); 8 9 /* . . . */ 10 11 p = search(head, key); 12 if (p != NULL) { 13 list_del_rcu(&p->list); 14 synchronize_rcu(); 15 kfree(p); 16 } 找到要删除的节点 ...

2019-06-02 · 1 min · 198 words