背景
DAMON 的 scheme(DAMOS)可以带 quota:每个计费窗口内 scheme 动作只应用到配额允许的字节量,避免一个窗口就把动作打满全部内存。窗口内按 target、region 的顺序逐个应用并按字节计费;quota 在窗口中途用满时,DAMON 把停下的位置记成一对游标(charge_target_from 与 charge_addr_from),下一个窗口 damos_skip_charged_region() 据此跳过游标之前已计费的 target 与 region,从游标处继续。多个窗口轮转下来,全部 region 都能轮到,quota 既限了速率又不漏覆盖面。
quota 游标让 scheme 跨窗口轮转覆盖
┌───────────────────────────────────────┐
│ 窗口内按 target 与 region 顺序应用动 │
│ 作,按字节计费 │
└───────────────────┬───────────────────┘
▼
┌───────────────────────────────────────┐
│ quota 用满时游标记下停下的 target 与 │
│ 地址 │
└───────────────────┬───────────────────┘
▼
┌───────────────────────────────────────┐
│ 下一窗口跳过游标之前已计费的 region, │
│ 从游标处继续 │
└───────────────────────────────────────┘
跳过与否按 region 与游标的位置关系判定:
- 整个位于游标之前:已计费,跳过
- 跨过游标:按 min_region_sz 对齐 split 出已计费的头部跳过,剩余部分由本轮后续遍历处理
- 落在游标之后:不跳过,正常处理
问题
- 游标有效时遍历到 target 的 last region,会被无条件跳过并重置游标
- last region 可能从未被计费处理,跳过即被 scheme 永久漏掉
- 触发条件苛刻:上一窗口恰好在 last region 之前用满 quota
方案
把到达 last region 时的游标重置与跳过判定解耦。
游标重置集中到遍历末尾一处:到达 last region 只把 charge_target_from 置 NULL、charge_addr_from 清零,不再附带跳过。跳过判定不再含 last region 特例,它与其他 region 走同一条位置关系判定路径,落在游标之后的 last region 照常应用 scheme 动作。
以一个最小场景为例:target 只有 R1、R2 两个 region,quota 每窗口只够处理一个 R1。窗口一处理 R1 后 quota 用满,游标停在 R2 起点;窗口二里 R1 因已计费被跳过,到达 R2 时旧代码无条件跳过并重置游标,R2 从未被处理却就此永久漏掉。修复后到达 R2 只重置游标,R2 整个位于游标之后,照常处理。
到达 last region 时的新旧行为
┌──────────────────────────────────────────┐
│ 游标有效时遍历到达 target 的 last region │
└────────────────────┬─────────────────────┘
┌─────────────────────┴─────────────────────┐
▼ ▼
┌──────────────────────────────────┐ ┌───────────────────────────────────────┐
│ 旧行为:无条件跳过并重置游标,从 │ │ 新行为:只重置游标,跳过与否按 region │
│ 未被处理的 last region 永久漏掉 │ │ 与游标的位置关系判定 │
└──────────────────────────────────┘ └───────────────────────────────────────┘
收益
作者未提供性能数据,从代码逻辑推断的预期收益:
- 设置 quota 的 scheme 不再永久漏掉 last region,跨窗口轮转覆盖完整
- 游标重置集中到遍历末尾一处,与跳过判定解耦,逻辑更直白