# Userspace RCU ###### tags: `rcu` - [Userspace RCU - liburcu](https://liburcu.org/) - [User-space RCU - LWN 2013](https://lwn.net/Articles/573424/) - [User-space RCU: Atomic-operation and utility API](https://lwn.net/Articles/573435/) - [User-space RCU: Memory-barrier menagerie](https://lwn.net/Articles/573436/) - [The user-space RCU API](https://lwn.net/Articles/573439/) - [The RCU-protected list API](https://lwn.net/Articles/573441/) - [urcu/userspace-rcu - github](https://github.com/urcu/userspace-rcu) - [tests/benchmark/](https://github.com/urcu/userspace-rcu/tree/master/tests/benchmark) - [doc/rcu-api.md](https://github.com/urcu/userspace-rcu/blob/master/doc/rcu-api.md) - [What Linear Multiprocessor Scalability Means for Your Application](https://blog.linuxplumbersconf.org/2009/slides/Mathieu-Desnoyers-talk-lpc2009.pdf) Linux Plumbers Conference 2009, slide - [Userspace RCU library: new APIs and data structures - Mathieu Desnoyers, EfficiOS Inc.](https://youtu.be/yOoWvdBFFRs) Linux Plumbers Conference 2013, video - [Mentorship Session: Unraveling RCU-Usage Mysteries (Fundamentals)](https://youtu.be/K-4TI5gFsig) - [liburcu,一个用户态的RCU实现](https://airekans.github.io/c/2016/05/10/dive-into-liburcu) - [Userspace RCU原理](https://blog.csdn.net/chenmo187J3X1/article/details/80992945) --- ## URCU overview When is URCU useful? ![](https://i.imgur.com/nikvjfU.png) TODO 筆記補完整 ## RCU Flavors - QSBR - RCU_MEMBARRIER - RCU_MB - RCU_SIGNAL - Bullet-proof ### QSBR - #include <urcu-qsbr.h> - Link with -lurcu-qsbr QSBR flavor of RCU 每個 reader thread 都要週期性的呼叫 `rcu_quiescent_state()` 確保程式的 progress。 可以用 rcu_thread_online() and rcu_thread_offline() 使該 reader thread 進入較長時間的 inactive,暫時脫離 grace period 的偵測 由於需要呼叫 `rcu_quiescent_state()`,此 flavor 對於程式的 intrusiveness 較大,但可以得到最快的 read-side speed (zero cost) ---- ### RCU_MEMBARRIER - #include <urcu.h> - Link the application with -lurcu > This is the preferred version of the library, in terms of grace-period detection speed, read-side speed and flexibility. Dynamically detects kernel support for sys_membarrier(). Falls back on urcu-mb scheme if support is not present, which has slower read-side. 最推薦的版本,在偵測 grace period, read-side 的速度跟 flexibility 都很好。 會動態偵測是否支援 `sys_membarrier()`,不支援的話會自動退到 RCU_MB 的版本, ,降低 read-side 速度 ---- ### RCU_MB - #include <urcu.h> - Compile any _LGPL_SOURCE code using this library with -DRCU_MB - Link with -lurcu-mb 在 reader 跟 writer 都會使用 memory barriers,所以在偵測 grace period 的速度較快,但犧牲 reader-side speed ---- ### RCU_SIGNAL - #include <urcu.h> - Compile any _LGPL_SOURCE code using this library with -DRCU_SIGNAL - Link the application with -lurcu-signal > Version of the library that requires a signal, typically SIGUSR1. Can be overridden with -DSIGRCU by modifying Makefile.build.inc. 此 flavor 的 read-side speed 只略輸 QSBR,並且不需要呼叫 quiescent states,但是會需要佔用掉一個 signal,預設是會佔用掉 `SIGUSR1` ---- ### Bullet-proof - #include <urcu-bp.h> - Link with -lurcu-bp > It is specifically designed to help tracing library to hook on applications without requiring to modify these applications. 此 flavor 被設計來 hook 在 application 上,並且不用改動這些 applications 前面所有的 flavor 都需要 rcu_init(), rcu_register_thread() and rcu_unregister_thread() 才能夠運作,但這個卻不用。(會轉變成 nops) 可是會犧牲 read-side and write-side 的速度 --- ## URCU Test https://github.com/ccs100203/kernel-module-rcu-test 將此測試移植到 userspace rcu 來做 已經做好了,尚未放到 github 上 TODO, 增加測試的強度 (stress) ### 執行結果: #### kernel module ``` [348771.405662] id : 0, name : book1, author : jb, borrow : 0, addr : ffff94e2d0490e40 [348771.405667] id : 1, name : book2, author : jb, borrow : 0, addr : ffff94e2d0490240 [348771.405669] book1 borrow : 0 [348771.405669] book2 borrow : 0 [348771.426178] borrow success 0, preempt_count : 0 [348771.453980] borrow success 1, preempt_count : 0 [348771.453985] id : 0, name : book1, author : jb, borrow : 1, addr : ffff94e2d0490900 [348771.453988] id : 1, name : book2, author : jb, borrow : 1, addr : ffff94e49d2adc00 [348771.470186] return success 0, preempt_count : 0 [348771.494184] return success 1, preempt_count : 0 [348771.494189] id : 0, name : book1, author : jb, borrow : 0, addr : ffff94e49d2ad180 [348771.494192] id : 1, name : book2, author : jb, borrow : 0, addr : ffff94e2d0490900 ``` #### userspace rcu 目前這裡的 `preempt_count` 目前是直接回傳 0,而不是像 kernel module 使用 [preempt_count() function](https://elixir.bootlin.com/linux/v5.8.9/source/include/asm-generic/preempt.h#L9) 使用到 [urcu/rculist.h](https://github.com/urcu/userspace-rcu/blob/master/include/urcu/rculist.h) 以及 [urcu/list.h](https://github.com/urcu/userspace-rcu/blob/master/include/urcu/list.h) ``` id : 0, name : book1, author : jb, borrow : 0, addr : 55fc4d1cb2a0 id : 1, name : book2, author : jb, borrow : 0, addr : 55fc4d1cb340 book1 borrow : 0 book2 borrow : 0 borrow success 0, preempt_count : 0 borrow success 1, preempt_count : 0 id : 0, name : book1, author : jb, borrow : 1, addr : 55fc4d1cb7f0 id : 1, name : book2, author : jb, borrow : 1, addr : 55fc4d1cb2a0 return success 0, preempt_count : 0 return success 1, preempt_count : 0 id : 0, name : book1, author : jb, borrow : 0, addr : 55fc4d1cb340 id : 1, name : book2, author : jb, borrow : 0, addr : 55fc4d1cb7f0 ``` --- ## APIs & Docs - [Userspace RCU API](https://github.com/urcu/userspace-rcu/blob/master/doc/rcu-api.md) 完整 API 連結 - [Userspace RCU Concurrent Data Structures (CDS) API](https://github.com/urcu/userspace-rcu/blob/master/doc/cds-api.md) This document describes briefly the data structures contained with the userspace RCU library. ### liburcu-defer ### urcu-call-rcu --- ## 已提交 patch [[lttng-dev] [PATCH] Fix: revise obsolete command in README.md](https://lists.lttng.org/pipermail/lttng-dev/2022-August/030245.html) 測試的時候發現 make bench 早在 2015 被改掉了,被分成 short_bench, long_bench 兩種 但 readme 跟 doc 都沒改 [Refactor tests](https://github.com/urcu/userspace-rcu/commit/ad46005890368f9c306f0c510b3d4b08c47b66f8) 然後 benchmark 沒有紀錄 log 要自己存