DAMON 采样
kdamond 监控访问
在区域里取随机地址
检查 PTE accessed 位
监控线程
DAMON context
kdamond 内核线程
遍历 target / region
热路径反复采样
采样点
sampling_addr
区域 [start, end)
随机点作探针
估计访问模式
关键
采样地址只是探针
不必安全随机
旧随机 · 带锁熵池
damon_rand(l, r)
get_random_u32_below()
每个采样都调用
取随机要拿锁
local_lock_irqsave
per-CPU 批量熵池
锁保护熵池
批量耗尽再重填
加密级重填
ChaCha20
加密级随机
安全但更重
采样不需要
代价
加密强度用不上
锁却进热路径
热路径 · 区域越多越贵
nr_regions 升高
每次采样都取随机
锁开销被放大
profile 里的主角
lock_acquire
local_lock
__get_random_u32_below
占满 kdamond 采样
2 万+ 区域
kdamond ~72% 单核
锁与熵池主导
不是地址检查本身
采样被随机数拖慢
问题
随机数服务采样
却成了瓶颈
观察 · 不需要加密强度
sampling_addr 不暴露
不做安全决策
只是 PTE 探针
这个地址做什么
选一个地址
看 accessed 位
估计热冷
不传给用户态
随机性要求
无需 ChaCha20
普通 PRNG 足够
lfsr113 线性
绝不用于安全
边界
非加密随机
只用于采样
新 PRNG · per-ctx 状态
struct rnd_state
放在 damon_ctx
kdamond 唯一消费者
初始化
damon_new_ctx()
prandom_seed_state()
get_random_u64()
每 ctx 一份
为什么无锁
无共享状态
热路径无锁
无需原子操作
seed 只做一次
关键
kdamond 单消费者
所以不用同步
取址 · 无锁映射
damon_rand(ctx, l, r)
span = r - l
输出投到区间
32-bit 路径
span <= U32_MAX
prandom_u32_state()
(rnd * span) >> 32
再加到 l
调用点
paddr 采样
vaddr 采样
split regions
都传 ctx
映射
reciprocal multiplication
与旧接口同路
64 位 · 慢路径
span > U32_MAX
只有 64-bit 够得到
拼两个 u32
拼 64 位
u32 << 32 | u32
得到 64 位 rnd
span 也是 64 位
不能用 32 位乘法
宽乘法
mul_u64_u64_shr()
rnd * span >> 64
再加到 l
32-bit 死代码
边界
32-bit 编译期消掉
64-bit 才走
收益与边界
paddr 监控
max_nr_regions=20000
单核 CPU 占用
实测
~72% → ~50%
少约 22 个百分点
约五分之一核
区域多时更便宜
边界
仅 paddr 实测
其他模式未给数据
lfsr113 非加密
采样专用
结论
未给吞吐 / 延迟数字
只报 CPU 占用
空格
播放/暂停
←
→
逐动作
R
重播
⚠
1x