Skip to the content.

CONFIG_TASKS_RCU

function tracer 为什么会打开 CONFIG_TASKS_RUDE_RCU

config FUNCTION_TRACER
	bool "Kernel Function Tracer"
	depends on HAVE_FUNCTION_TRACER
	select KALLSYMS
	select GENERIC_TRACER
	select CONTEXT_SWITCH_TRACER
	select GLOB
	select TASKS_RCU if PREEMPTION
	select TASKS_RUDE_RCU
	help
	  Enable the kernel to trace every kernel function. This is done
	  by using a compiler feature to insert a small, 5-byte No-Operation
	  instruction at the beginning of every kernel function, which NOP
	  sequence is then dynamically patched into a tracer call when
	  tracing is enabled by the administrator. If it's runtime disabled
	  (the bootup default), then the overhead of the instructions is very
	  small and not measurable even in micro-benchmarks (at least on
	  x86, but may have impact on other architectures).

不能说是简单易懂,也算是真的牛逼

https://docs.kernel.org/RCU/Design/Requirements/Requirements.html#tasks-rcu

居然考虑到 trace 机制和 preemption 通知打开的时候,tracepoint 里面的 trampolines 的内存的释放。

所以,我们观察到,这一组函数的调用者都是 call_rcu_tasks() 之类的

task rcu 做什么的

它也是一种 RCU,但它等待的不是普通 RCU 的 quiescent state,而是“task 级别”的执行点”。

最常见的普通 RCU 里,你关心的是:

但有些场景里,这个定义不够用。因为你想等的并不是“CPU 上的 RCU read-side critical section 结束”,而是:

也就是说,RCU Tasks 不太关心你有没有 rcu_read_lock(),而更关心:

所以它常用于这类需求:

为什么叫 Tasks

因为 grace period 的完成条件,和 task 的状态转换强相关,而不是单纯 CPU 是否经历一次 quiescent state。

普通 RCU 的 reader:

RCU Tasks:

codex 关于 rcu 变体的两个问题

  1. RCU Tasks、RCU Tasks Trace、RCU Tasks Rude 三者分别是什么
  2. 为什么 eBPF/tracing/text patching 更适合用它们而不是普通 RCU

可以先按“读侧临界区是怎么定义的”来记:

一句话压缩:

为什么普通 RCU 不够

普通 synchronize_rcu() 适合“数据结构 reader 在普通 RCU read-side critical section 里”的模型。 但 eBPF、ftrace、text patching 这类问题常常不是“某个指针还被读着”,而是:

这时你要等的是“没有 task 还在执行旧代码”,不是“没有 CPU 还在普通 RCU 读侧”。

文档在 Documentation/RCU/Design/Requirements/Requirements.rst:2730 对 Tasks RCU 的动机讲得很准:trampoline 可能在真正执行很久之前就布置好了,普通 RCU 的 CPU 视角不 够表达“task 还在那段旧代码里”。

为什么 eBPF / tracing / text patching 分别会选它们

怎么选

工程上可以这样判断:

一个容易记错的点

RCU Tasks 和 RCU Tasks Rude 都没有显式 rcu_read_lock*() reader 标记。 RCU Tasks Trace 则有,而且这是它和前两者最本质的 API 区别。这个对照表在 Documentation/RCU/whatisRCU.rst:1170 很清楚。

如果你愿意,我下一条可以继续讲一个更细的问题: “为什么 Tasks Trace 不直接用 SRCU,而是单独搞一个 flavor?”

ps -elf | grep rcu 里这些线程都是什么

这些线程可以粗分成四类:

在一台开启 PREEMPT_RCUTASKS_RCUTASKS_TRACE_RCU 之类配置的机器上,常见线程名可以这样理解:

可以用名字快速猜它的职责:

一个容易混淆的点:

ps 里看到“很多 rcu 线程”,并不意味着每个线程都在做同一件事。它们分别服务不同的 RCU flavor 和不同的推进策略。真正最常见、最基础的仍然是普通 Tree RCU 的 rcu_preempt;而 rcu_exp_*rcu_tasks_* 更多是为了加急路径或特殊 reader 模型存在。

本站所有文章转发 CSDN 将按侵权追究法律责任,其它情况随意。