diff --git a/scheds/rust/scx_cake/STATE.md b/scheds/rust/scx_cake/STATE.md
index e4b9ac5b30..78fd1a3a5d 100644
--- a/scheds/rust/scx_cake/STATE.md
+++ b/scheds/rust/scx_cake/STATE.md
@@ -14,12 +14,14 @@ This file was compacted 2026-08-12 from 30,510 words; everything cut is in that
Branch and squash history
-Branch: **`RitzDaCat/scx_cake-nightly`** (pushed to fork). History squashed three
+Branch: **`RitzDaCat/scx_cake-nightly`** (pushed to fork). History squashed four
times: at `15960cb97` (53 commits → `backup/nightly-53-commits-20260810`), at
-`38397bb59` (10 commits → `backup/nightly-10-commits-20260817`), and at this commit
+`38397bb59` (10 commits → `backup/nightly-10-commits-20260817`), at `c99eb00c7`
(12 commits → `backup/nightly-12-commits-20260818`, after the 2026-08-18 rebase onto
-upstream `ff86d6588`; pre-rebase state in `backup/nightly-pre-rebase-20260818`); all
-hashes cited below resolve via those local backup branches.
+upstream `ff86d6588`; pre-rebase state in `backup/nightly-pre-rebase-20260818`), and
+at this commit (17 commits → `backup/nightly-17-commits-20260819`: the R.28 arc —
+1.1.3 wallclock campaign, mode-flip root cause, per-task geometry, veto bisect,
+live WoW confirm); all hashes cited below resolve via those local backup branches.
@@ -41,6 +43,15 @@ hashes cited below resolve via those local backup branches.
| 10 | **G25** steal-ring bitmask | **LANDED**, verifier accepted, attach smoke passed 2026-08-08 | wake latency on HD2 render roles + P4 bench screen. Prediction on record: ~0.04% of a core quiet, 4.7% invalidated — **expected frame effect near zero; a null confirms the pricing** |
| 11 | **G23** per-line IRQ-sink detection + mask avoidance | built, smoke PASSED, **endpoint unmeasured** | HD2 ABBA during ACTIVE play (P2 needs live mouse input) on `Window & Input` / `main` / `renderer` mean wake + severe-frame screen, then P4 `--blocks 2` bench screen. Receipts + steps: `docs/REVIEW_G21_G23_2026-08-02.md` §resume |
+**EXP S.1-1ms (2026-08-19): ❌ FALSIFIED.** Hypothesis was: nightly's extreme-tail loss
+vs shipped 1.1.3 (mutex-handoff p999 −37% 6/6; `runs/adhoc_wallclock_113_vs_nightly_20260819`)
+is SLICE_NS geometry. Probe SLICE_NS 3000→1000 µs (`092ada871`), 6-slot ABCCBA
+(1.1.3 / 3 ms / 1 ms): p999 2.53→2.70 µs (both ~2× 1.1.3's stable 1.36), p99 1.20→**1.85**
+(1 ms actively worse), schbench-saturated −18% worse; throughput flat ±4%. Reverted
+byte-identical `3df90d103` (39d784f3). Secondary find: 1.1.3's handoff tail is IDENTICAL
+across suites (0.85/1.36 µs) while nightly's drifted (p99 0.85→1.20 same code) — the
+nightly tail is regime-sensitive, the 1.1.3 tail is not. The gap is structural, not quantum.
+
**Also open, no owner:** the serial-handoff trade (fires 0.01–0.03% in game regimes —
games-only maintainer call). G25 leftovers: contended regime needs re-pricing with a
**15-reload** arm (128 B stride reversal ledgered as G25.1).
@@ -126,10 +137,27 @@ is smallest.
6. **`ops.enqueue` reaches 0.142% of a game's dispatches** (vs 23.6% saturated). Every
enqueue-side routing decision is nearly inert on games; leverage is on the direct
path in `cake_select_cpu`, which serves 99.86%.
-7. **Third arm blocked** — shipped 1.1.3 builds but does not attach on kernel 7.1.5
- (`map 'cake_ops': BPF map skeleton link is uninitialized`, libbpf/struct_ops skew).
- (Recorded on 7.1.5; host now on 7.1.8 post-rebase — re-test attach of the shipped
- 1.1.3 binary before citing this gap.)
+7. **Third arm UNBLOCKED 2026-08-19** — shipped 1.1.3 (`/usr/bin/scx_cake`, sha256
+ `56f9e886…`) attaches and runs clean on 7.1.8; the libbpf skeleton warning still
+ prints but is non-fatal. First read: quick wallclock ABBA vs nightly HEAD
+ (diagnostic tier, `scx_cake_bench_assets/runs/adhoc_wallclock_113_vs_nightly_20260819/`):
+ nightly pipe **−16.0%**, memcpy −3.9%, but sched-messaging **+70.5%** (4/4, no
+ overlap) — the many-to-many handoff shape regressed vs 1.1.3 and is unscored at
+ the sealed tier. n=10 confirm (suite 4, 5×ABBA): schbench-light req p99 **+72%
+ 10/10** (S sd 7 µs, N sd 459), mutex-handoff p999 **2.0× 10/10** (S sd 0.024 µs),
+ p99 **BIMODAL** (4/10 runs match 1.1.3 exactly, 6/10 at 1.2–1.9 µs), pipe −9.7%
+ win 10/10. Slice dose falsified (EXP S.1-1ms). **MODE SWITCH ROOT-CAUSED 2026-08-19
+ (`mode_probe/` in the run dir): it is `cake_frame_slice_ns`.** Placement exonerated
+ (24 runs, pair co-resident on CPU 11 in BOTH modes, sinks 0%). Dose-response with an
+ injected 1 kHz sleep-majority crowd, `--verbose` clock log as ground truth: crowd
+ binds in one poll (950.8 Hz published) → p99 1.8–2.1; crowd off → 3-poll re-publish
+ + ~16 s floor climb → p99 decays to 0.90. A **374.9 Hz desktop voter holds slice at
+ 2 ms** on this host even quiet — nightly never runs at the 3 ms cap on a live
+ desktop. 1.1.3 has no frame clock (constant geometry) — hence its sd ≈ 0. Mechanism:
+ any fast desktop crowd tightens patience windows (shifts of `cake_frame_slice_ns`,
+ §S.2) for EVERY task; the same-CPU handoff tail pays for it. The registered fix is
+ already on the board: §G12 KEYSTONE re-base of `FRAME_*_SHIFT` windows onto the
+ occupant's OWN period decouples bystander tasks from the global clock.
8. **Receipts audit** — 5 load-bearing claims (deletion-queue zeros, 1464 ns, SLICE_NS
dose, §R.17 +28-36%, G17/G21 wins); list + rationale:
`REVIEW_INDEPENDENT_2026-08-17.md` Addendum (git history).
@@ -157,10 +185,11 @@ is smallest.
| `edafb27e5` + `d56ad5131` | **G25** — steal-ring queue hint becomes a u64 bitmask (41 insns, 10 branches, 0 spills; rotate+`ctz` design measured and REJECTED, do not restore) |
| `3fb89cf05` (`6471262e1`, `b607264ad`) | **R.24** cross-multiplied divide elimination in `cake_frame_observe` + handoff-yields; both exact-pairs pass, kept |
-Static budget at tip: **11 divides** (re-counted 2026-08-17). Spills at tip per
-`bench/fnspills.py` (re-measured 2026-08-18): `select_cpu` 4/1, `enqueue` 2/4,
-`stopping` 1/1, `ring_steal` 1/1, `dispatch`/`running` 0/0; TOTAL 17/11/28. (The
-script was BLIND on llvm-objdump 22 until `18581c73c` fixed the regex — any
+Static budget at tip: **5 divides** (re-counted 2026-08-19 post-§R.28; was 11 —
+`cake_task_slice` became one subprogram, and fixed windows replaced bss loads).
+Spills at tip per `bench/fnspills.py` (2026-08-19): `select_cpu` 4/1, `enqueue`
+2/4, `stopping` 1/1, `ring_steal` 1/1, `dispatch`/`running` 0/0; TOTAL 16/10/26.
+(The script was BLIND on llvm-objdump 22 until `18581c73c` fixed the regex — any
zero-spill claim made before it is vacuous.)
---
@@ -294,6 +323,7 @@ real session), live replica (loader logic run standalone on the live host), audi
| G36 | tick look-ahead: skip a CPU whose timer fires within the hop horizon (§G36) | STATIC | **BUILT; unmeasured** | `cake_cpu_tick_soon` **28 insns, 0 spills**; enqueue spills 2/4, TOTAL 17/11/28; desktop smoke expects timer-race hits → ~0 |
| R.24 | cross-multiplied divide elimination in `cake_frame_observe` + handoff-yields (§R.24) | bench exact-pair | ✅ **kept** | both exact-pairs pass |
| R.27 | shaped compat ladders for ≤ 6.18 kernels (§R.27) | STATIC + CI | ✅ **CI veristat green ×6** (6.13/6.16/6.18/rolling/for-next/bpf-next, run 32206840388, 2026-08-18) | spills 28 → 26, hot frames flat (`select_cpu` 5, `enqueue` 6); +141 insns of dead arms, pruned at load; dev-kernel bench screen still owed |
+| **R.28** | per-task slice cap, fixed patience windows, frame clock demoted to diagnostic (§R.28) | bench dose + n=3 ABBA | ✅ **clock mode mechanism REMOVED; tail gap partially remains; game screen owed** | quiet handoff p99 rests 0.86–0.92 (was 0.85–1.9 drifting); divides 11→5, spills 17/11→16/10; p999 2× + schbench-light +72% vs 1.1.3 persist → IRQ-reactive stack (§G33/§G35/§G36) is the standing suspect |
| — | spread placement, co-location returns off (§R.1 fps A/B) | FRAME | **reverted byte-identical (7826cfe3a; hashes now in backup/nightly-12-commits-20260818)** | fps INCONCLUSIVE: scene drift **~7%/h** (nvidia **5044 → 4695/s**) dominated every arm; placement stayed concentrated on ~7 CPUs with all three co-location returns off |
### The frame result (2026-08-01, the campaign's first)
@@ -398,7 +428,7 @@ to a heading here.**
- **B2 OPEN** — a home-routed wake onto a busy CPU with no idle gets **no kick**; ~0 kills it.
- **B3 OPEN** — vtime seals, but the frontier advances only in `cake_running`; wall-rate tracking kills it.
- **B4 OPEN** — no `.tick`, a multiplier on B2/B3.
-- **B5 OPEN** — 1.1.3 is neither fix nor control, and no longer attaches.
+- **B5 OPEN** — 1.1.3 is neither fix nor control; attaches again on 7.1.8 (2026-08-19), so it is usable as a third arm.
- **B6 OPEN** — lost zero-spill discipline cannot explain 10-40 ms stalls.
### §G6. The spill law as a proxy
@@ -1148,6 +1178,47 @@ makes ≤ 6.18 verify; steps — port 5 `cpu_curr` + 3 `peek` + insert family +
hot spills flat; abort — any hot-frame spill regression, or a fallback that changes
scheduling behavior on the dev kernel.
+#### §R.28 — geometry decoupled from the shared clock (2026-08-19)
+The frame clock was the GEOMETRY UNIT: every patience window a shift of
+`cake_frame_slice_ns`, so one fast desktop crowd (a 374.9 Hz voter, the mouse at
+1 kHz) tightened every task's windows — measured as the 2× handoff-tail mode flip
+(`mode_probe/` in the 2026-08-19 run dir). Now: slice cap = half the task's OWN
+cycle (`cake_period_ns`, the §G12 KEYSTONE twin divide); occupant-protection and
+young-occupant windows = FIXED slice fractions — a per-occupant-period version
+inverted semantics for fast occupants (window ~44 ns ⇒ the handoff kick never
+fired, p99 2.1) and was reverted same-session; all vtime windows = fixed SLICE_NS.
+The clock publishes for --verbose only; §G27's easy-scene endpoint is superseded by
+per-task geometry. Object: spills 17/11 → 16/10, divides 11 → **5** (`cake_task_slice`
+consolidated to one subprogram). Verdict: quiet handoff p99 rests at 0.86–0.92
+(was 0.85–1.9 drifting) and the clock dose is gone, but **p999 2× and
+schbench-light +72% persist** — with the crowd control (1.1.3 +0.05 µs vs nightly
++0.9 under 8×1 kHz hrtimer load) the standing suspect is the IRQ-reactive stack
+(§G33/§G35/§G36; schbench is pure timer pressure and 1.1.3 ignores IRQs). GAME
+SCREEN OWED before keep (GAME-FIRST).
+
+**Bisect 2026-08-19 (4 probe commits, all reverted byte-identical to `0d345ed2…`):**
+all-vetoes-off closes EVERYTHING — quiet handoff p99 **0.80** (beats 1.1.3's 0.855),
+crowd-immune (0.79 under 8×1 kHz), schbench-light **2548** ≈ 1.1.3's 2540, pipe
+2.015 s (best of day). Single-feature-on runs, each independently harmful:
+**§G36** tick veto → handoff drift 0.84→1.35 + crowd sensitivity (schbench 2964);
+**§G35** live bit → quiet p999 2.7, crowd p999 **4.7**, schbench 3796;
+**§G33** chronic sinks → schbench **4472, the full +72% alone**, handoff clean.
+Their wake-tier game wins (G21 −39.9% main wake, G30 fence tail, G35 staircase)
+stand — this is a GAMES-VS-BENCH TRADE, maintainer's call, no deletion on bench
+data. Design cut for the next arc: each veto fires on SIGNAL PRESENCE with no
+cost comparison against the alternative placement (claiming a briefly-loud CPU
+usually beats queueing) — the §R.26 lens, binary thresholds discarding data.
+
+**Live WoW ABBA closes the trade 2026-08-19 (`wow-vetoAB-s{1..4}` in
+`history/wake_latency/`, `--irq`, 22 s slots, active play): the vetoes EARN
+THEIR KEEP IN-GAME, 2/2 no overlap on every role.** With vetoes vs all-off:
+fence p99 **23–27 → 48 µs**, vkd3d_queue p95 **7.4 → 28–33** (4×), WoW.exe main
+p95 14 → 30–32, ThreadPool High p50 **0.86 → 5.0 µs** (6×), same-CPU wakes
+86% → 31%. VERDICT under GAME-FIRST: vetoes STAY; the bench/desktop tail cost
+(schbench-light +72%, handoff p999 2× vs 1.1.3) is the accepted price, and the
+weighed-veto refinement is the registered path to buying both. MangoHud was not
+injected — frame screen still owed; wake tier only.
+
---
### §S — Constant ledger (from `intf.h`)
diff --git a/scheds/rust/scx_cake/src/bpf/cake.bpf.c b/scheds/rust/scx_cake/src/bpf/cake.bpf.c
index 60a0b3a63f..978f3eca35 100644
--- a/scheds/rust/scx_cake/src/bpf/cake.bpf.c
+++ b/scheds/rust/scx_cake/src/bpf/cake.bpf.c
@@ -155,17 +155,17 @@ const volatile u64 cake_handoff_max_ns = 1464;
u64 cake_frame_ns __attribute__((aligned(STATE_SLOT_BYTES)));
/*
- * The same estimate filtered PESSIMISTICALLY: a cap must never widen because
- * the estimator wobbled (§G18).
+ * The same estimate filtered PESSIMISTICALLY (§G18). Diagnostic only: no
+ * policy consumes it (§R.28).
*/
u64 cake_frame_floor_ns __attribute__((aligned(STATE_SLOT_BYTES)));
/*
- * The GEOMETRY UNIT: every patience window (sleeper lag, wake hysteresis,
- * preempt margins) is a shift of this, not of the fixed grant. Loader publishes
- * min(3/4 x frame floor, SLICE_NS): a display-coupled regime tightens the
- * geometry with its engine cadence; a vote-free regime keeps the slice exactly,
- * so benches are unchanged by construction (§G27).
+ * DIAGNOSTIC ONLY: the loader still publishes min(3/4 x frame floor,
+ * SLICE_NS) for the --verbose clock line, but no policy consumes it.
+ * As the shared geometry unit it let one fast desktop crowd tighten every
+ * task's patience windows — measured as a 2x handoff-tail mode flip.
+ * Geometry is per task now (§R.28).
*/
u64 cake_frame_slice_ns __attribute__((aligned(STATE_SLOT_BYTES)));
@@ -195,6 +195,18 @@ static __always_inline u64 cake_burst_ns(const struct task_struct *p)
return p->se.sum_exec_runtime / (p->nvcsw | 1);
}
+/*
+ * This task's mean CYCLE: lifetime per voluntary switch, cake_burst_ns's
+ * wall-axis twin (§G12). Clamped to the fixed slice so a task that rarely
+ * yields is bounded as compute, not trusted forever (§R.28).
+ */
+static __always_inline u64 cake_period_ns(const struct task_struct *p)
+{
+ u64 per = (bpf_ktime_get_ns() - p->start_time) / (p->nvcsw | 1);
+
+ return per > SLICE_NS ? SLICE_NS : per;
+}
+
/*
* Does this task wait longer than it runs? run_delay is the kernel's lifetime
* runnable-but-not-running total and pcount its dispatch count, so
@@ -576,13 +588,14 @@ static __noinline u64 cake_occupant_live(s32 tcpu, u64 *ran_out)
* RT/DL or idle, which we neither can nor need preempt. §R.1.
*/
static __noinline bool cake_wake_preempt(struct task_struct *p, s32 tcpu,
- u64 min_ran)
+ u32 protect_shift)
{
u64 ran = 0;
u64 live = cake_occupant_live(tcpu, &ran);
struct task_struct *curr;
- if (!live || ran < min_ran || !time_before(p->scx.dsq_vtime, live))
+ if (!live || ran < (u64)SLICE_NS >> protect_shift ||
+ !time_before(p->scx.dsq_vtime, live))
return false;
/*
@@ -662,20 +675,20 @@ static __noinline bool cake_handoff_yields(s32 tcpu)
/*
- * The slice this task needs: twice its own burst, floored at the chain
- * boundary, capped at half a frame -- taken from the PESSIMISTIC frame
- * estimate, since a bound must not widen when the estimator wobbles. The grant
- * is a PREEMPTION TIMER, not a vtime question (§G10.4, §G11.5, §G18).
+ * The slice this task needs: twice its own burst, capped at half its OWN
+ * cycle -- a task must not hold a CPU past its next wake -- floored at the
+ * handoff cost. The grant is a PREEMPTION TIMER, not a vtime question
+ * (§G10.4, §G18, §R.28).
*/
-static __always_inline u64 cake_task_slice(const struct task_struct *p)
+static __noinline u64 cake_task_slice(struct task_struct *p __arg_trusted)
{
u64 want = cake_burst_ns(p) << 1;
- u64 cap = cake_frame_floor_ns >> FRAME_SLICE_CAP_SHIFT;
+ u64 cap = cake_period_ns(p) >> PERIOD_SLICE_CAP_SHIFT;
- if (want < cake_handoff_max_ns)
- want = cake_handoff_max_ns;
if (want > cap)
want = cap;
+ if (want < cake_handoff_max_ns)
+ want = cake_handoff_max_ns;
return want;
}
@@ -697,7 +710,7 @@ static __always_inline u64 cake_sleeper_dose(u64 unused)
static __always_inline u64 cake_cadence_depth(const struct task_struct *p)
{
u64 burst = cake_burst_ns(p);
- u64 vs = cake_frame_slice_ns;
+ u64 vs = SLICE_NS;
if (!cake_starved(p) || burst >= vs)
return 0;
@@ -712,7 +725,7 @@ static __always_inline u64 cake_cadence_depth(const struct task_struct *p)
*/
static __noinline u64 cake_wake_vtime(const struct task_struct *p)
{
- u64 lo = cake.frontier.word - cake_frame_slice_ns - cake_cadence_depth(p);
+ u64 lo = cake.frontier.word - SLICE_NS - cake_cadence_depth(p);
u64 d = p->scx.dsq_vtime - lo;
return lo + (d & ~((u64)((s64)d >> 63)));
@@ -729,14 +742,12 @@ static __noinline bool cake_home_notify(struct task_struct *p, s32 tcpu)
{
u64 ran = 0;
u64 live = cake_occupant_live(tcpu, &ran);
- u64 vs;
if (!live)
return (u32)tcpu == bpf_get_smp_processor_id();
- vs = cake_frame_slice_ns;
- if (ran >= (vs >> 5) ||
- !time_before(p->scx.dsq_vtime + (vs >> 1) -
+ if (ran >= ((u64)SLICE_NS >> 5) ||
+ !time_before(p->scx.dsq_vtime + (SLICE_NS >> 1) -
(ran >> HOME_PREEMPT_RAN_CREDIT_SHIFT), live))
return false;
@@ -916,7 +927,7 @@ s32 BPF_STRUCT_OPS(cake_select_cpu, struct task_struct *p, s32 prev_cpu,
* direct-dispatching keeps live-vtime eligibility (§R.20).
*/
if ((wake_flags & CAKE_WAKE_SYNC) ||
- time_before(p->scx.dsq_vtime + (cake_frame_slice_ns >> 1),
+ time_before(p->scx.dsq_vtime + (SLICE_NS >> 1),
cake.frontier.word)) {
s32 waker_cpu = (s32)bpf_get_smp_processor_id();
@@ -989,8 +1000,7 @@ __noinline s32 cake_wake_notify(struct task_struct *p __arg_trusted, s32 tcpu,
* occupant genuinely deserves it. Cake registers no .tick, so an arm
* that decides neither leaves the wakee on the 5 s watchdog (§R.14).
*/
- if (cake_wake_preempt(p, tcpu,
- cake_frame_ns >> FRAME_PREEMPT_PROTECT_SHIFT))
+ if (cake_wake_preempt(p, tcpu, PREEMPT_PROTECT_SHIFT))
return 0;
/*
@@ -1009,8 +1019,7 @@ __noinline s32 cake_wake_notify(struct task_struct *p __arg_trusted, s32 tcpu,
if (!bpf_cpumask_test_cpu((s32)cand, p->cpus_ptr))
continue;
if (cake_wake_preempt(p, (s32)cand,
- cake_frame_ns >>
- FRAME_PROBE_PROTECT_SHIFT))
+ PROBE_PROTECT_SHIFT))
break;
}
}
@@ -1030,7 +1039,7 @@ __noinline s32 cake_wake_notify(struct task_struct *p __arg_trusted, s32 tcpu,
static __noinline bool cake_home_claim(struct task_struct *p __arg_trusted,
s32 tcpu)
{
- u64 vs = cake_frame_slice_ns;
+ u64 vs = SLICE_NS;
u64 lo = cake.frontier.word - vs;
u64 ran = 0, live;
@@ -1135,7 +1144,7 @@ static __noinline void cake_pinned_wake_preempt(struct task_struct *p __arg_trus
if (!clive)
return;
- vs = cake_frame_slice_ns;
+ vs = SLICE_NS;
lo = cake.frontier.word - vs;
dd = d + vs;
pvt = lo - vs + (dd & ~((u64)((s64)dd >> 63)));
@@ -1191,7 +1200,7 @@ void BPF_STRUCT_OPS(cake_enqueue, struct task_struct *p, u64 enq_flags)
* Only the continuation arm consumes it; the wake arm derives its own
* cadence-deep floor (§R.13).
*/
- lo = cake.frontier.word - cake_frame_slice_ns;
+ lo = cake.frontier.word - SLICE_NS;
d = p->scx.dsq_vtime - lo;
/*
@@ -1364,7 +1373,7 @@ static __noinline bool cake_dispatch_search(s32 cpu)
* served that queue in a wall-clock window (§R.16, §G11.2).
*/
if (!own ||
- time_before(wv + cake_frame_slice_ns,
+ time_before(wv + SLICE_NS,
own->scx.dsq_vtime) ||
cake_wake_starved()) {
first = (u64)WAKE_DSQ;
diff --git a/scheds/rust/scx_cake/src/bpf/intf.h b/scheds/rust/scx_cake/src/bpf/intf.h
index 7f12c7d951..3b748d9ed2 100644
--- a/scheds/rust/scx_cake/src/bpf/intf.h
+++ b/scheds/rust/scx_cake/src/bpf/intf.h
@@ -42,13 +42,16 @@ enum consts {
/* The slice every task gets. Dose-responsed U-curve minimum (§S.1). */
SLICE_NS = 3000 * NSEC_PER_USEC,
- /* Patience windows are shifts of cake_frame_slice_ns (§S.2, §G27). */
+ /* Vtime credit for time an occupant already ran (§S.2). */
HOME_PREEMPT_RAN_CREDIT_SHIFT = 1,
- /* Occupant protection as a fraction of a FRAME (§G11.4). */
- FRAME_PREEMPT_PROTECT_SHIFT = 4,
- FRAME_PROBE_PROTECT_SHIFT = 2,
- FRAME_SLICE_CAP_SHIFT = 1,
+ /* Occupant protection: FIXED slice fractions, so only long-running
+ * compute is ever preempted and no shared clock moves them (§R.28). */
+ PREEMPT_PROTECT_SHIFT = 4,
+ PROBE_PROTECT_SHIFT = 2,
+
+ /* Slice cap: half the task's OWN mean cycle (§G12, §R.28). */
+ PERIOD_SLICE_CAP_SHIFT = 1,
/* Pre-scale for the wait:run cross-multiply; it cancels (§G12). */
CAKE_RATIO_SHIFT = 16,
diff --git a/scheds/rust/scx_cake/src/main.rs b/scheds/rust/scx_cake/src/main.rs
index 2e1320c7cd..b190e81c4a 100644
--- a/scheds/rust/scx_cake/src/main.rs
+++ b/scheds/rust/scx_cake/src/main.rs
@@ -487,8 +487,8 @@ impl<'a> Scheduler<'a> {
if let Some(bss) = self.skel.maps.bss_data.as_mut() {
bss.cake_frame_ns = period;
bss.cake_frame_floor_ns = self.frame_floor;
- // Geometry unit: 3/4 of the pessimistic floor, and never looser
- // than the fixed slice — display regimes only TIGHTEN it (§G27).
+ // Diagnostic only: feeds the --verbose clock line; no policy
+ // consumes these — geometry is per task (§R.28).
bss.cake_frame_slice_ns = ((self.frame_floor >> 1) + (self.frame_floor >> 2))
.min(bpf_intf::consts_SLICE_NS as u64);
}