You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Narrowed from #31, which closed when gate 1 ran. This is the residue that
survived it, and the residue is smaller and better defined than the original
question.
Two K3 opens on a 64 GB machine cannot be fixed by any budget policy. docs/LEARNED.md §64: K3's floor is 29.19 GB, almost entirely the resident
trunk, so two floors are 58.38 GB against a 51.54 GB ceiling. A ledger would
drive the second process to its floor and the pair would still oversubscribe.
Gate 1 confirmed the failure mode empirically — neither process reached
decode, and the machine needed a power cycle.
Bounding the ceiling by an instantaneous sample stays refused, for the
reason in src/memory.c.
Explicit budgets stay authoritative. Warn, never clamp.
Capacity is solved.waste_usable_ram() is min(physical, cgroup limit).
Where the case actually exists
A ledger only has something to divide when the floors fit and the caches do
not. That is not a corner — it is what a larger machine running K3 looks
like, and it is the opposite of where #31 was written:
host
ceiling 3/4
one open picks
two opens
two at the floor
64 GB
51.54 GB
46.39 GB
92.78 GB — 135%
58.38 GB — 85%, over the ceiling for one
128 GB
96.00 GB
80.77 GB (floor + 3x)
161.54 GB — 126%
58.38 GB — 46%, comfortable
On 64 GB there is nothing to engineer: the floors alone bust the budget. On
128 GB the second process has 37 GB of headroom above its floor that a ledger
could hand it deliberately instead of leaving it to be discovered by paging.
This is the row #31's table called "K3 + Kimi-Linear, different containers" —
generalised. The predicate is not container identity and never was; it is
resident bytes against a ceiling somebody else has already spent, which is
arithmetic waste_open is one input short of doing.
kill(pid, 0) is the wrong liveness primitive. Pid reuse leaves a dead
reservation unprunable, and every future budget on that machine is
permanently smaller — a symptom nobody attributes to a stale file. Closing it
with process start times costs three platform paths.
flock per reservation is the right one, and is already in the tree. One
file per reservation held under LOCK_EX for the life of the process; the
kernel releases it on any exit. A reader takes LOCK_SH | LOCK_NB and a file
it can lock is dead. The refcounted, atfork-safe, CLOEXEC implementation
is at src/waste.c:117, landed as exclusive_open in Add opt-in exclusive model-container ownership #29 — same technique,
different key.
Placement has no answer that is both safe and complete. World-writable
means any local user can publish a 10 TB reservation and starve the machine;
per-user is safe and blind exactly where the harm is real, on a shared box.
This is a choice, not a cost, and it comes before a file format.
Namespaces are worse. Two containers on one host each see one process,
believe they are alone, and share one kernel's RAM. Silent under-counting in
a safety mechanism is worse than no mechanism, because the printed budget
line then looks like it was checked against something.
waste.h says no global state. A cross-process ledger is the first thing
this project would write outside a container directory. That is a decision
about what the library is.
The "capacity, not pressure" defence is weaker than Two auto-budget opens on one machine each size against the whole machine #31 stated. The sum
of live reservations is not fixed for the life of the process. What survives
is that its volatility is declared and attributable: a smaller budget is
always matched by a real, still-live claim, rather than by a transient that
has already gone. That is enough to admit the input; it is not determinism,
and the cost has to be accepted openly.
Gates, and the first one must not be run the way #31's was
#31's gate 1 cost a reboot because the unmanaged arm is the dangerous one.
That is unavoidable here too, so it has to be bounded by the host rather than
by hope.
Does the floors-fit case degrade at all? Two auto-budget K3 opens on a
64 GB host, against a single-process baseline. Run under a memory cap
that bounds the damage — Linux with memory.max on a cgroup, where the
OOM killer ends the arm instead of the machine. If the OS degrades
gracefully when the floors fit, this closes with a dated entry and nothing
is built.
Would the ledger's outcome have been better? Same pair, both pinned by
hand to the budget a ledger would have picked — the cap split between them.
Unlike Two auto-budget opens on one machine each size against the whole machine #31's gate 2 this is a safe arm by construction, since two floors are
46% of a 128 GB host. If two processes sharing the ceiling are meaningfully
faster than two contending for all of it, there is something to engineer.
Only then, pick the shape, against the constraints above.
@Lrrr908 has the machine this needs — 128 GB, Linux, and a K3 container, from #37 — and gate 1 is the arm a 64 GB host can never select. No obligation
attached; noting it because it is the only host in this project's reach where
the question is answerable safely.
Non-goals
Any change to explicit --budget.
Anything that refuses an open that would otherwise have succeeded. Refusal
is what exclusive_open already does, opt-in, and Two auto-budget opens on one machine each size against the whole machine #31's criticism of its key
stands — it just turns out the right predicate has no non-refusing answer in
the 64 GB case.
The 64 GB two-K3 case. §64 closed it; the only things that would cover it are
refusing, or not duplicating the trunk, which is a different engine shape.
Done when
docs/LEARNED.md has a dated entry with the gate-1 numbers, and either a
mechanism behind them or the reason there is none — the second outcome being as
good as the first.
Narrowed from #31, which closed when gate 1 ran. This is the residue that
survived it, and the residue is smaller and better defined than the original
question.
What #31 settled, and is not up for re-litigation
docs/LEARNED.md§64: K3's floor is 29.19 GB, almost entirely the residenttrunk, so two floors are 58.38 GB against a 51.54 GB ceiling. A ledger would
drive the second process to its floor and the pair would still oversubscribe.
Gate 1 confirmed the failure mode empirically — neither process reached
decode, and the machine needed a power cycle.
reason in
src/memory.c.waste_usable_ram()ismin(physical, cgroup limit).Where the case actually exists
A ledger only has something to divide when the floors fit and the caches do
not. That is not a corner — it is what a larger machine running K3 looks
like, and it is the opposite of where #31 was written:
floor + 3x)On 64 GB there is nothing to engineer: the floors alone bust the budget. On
128 GB the second process has 37 GB of headroom above its floor that a ledger
could hand it deliberately instead of leaving it to be discovered by paging.
This is the row #31's table called "K3 + Kimi-Linear, different containers" —
generalised. The predicate is not container identity and never was; it is
resident bytes against a ceiling somebody else has already spent, which is
arithmetic
waste_openis one input short of doing.What is already argued about the shape
From #31's thread, so it is not re-derived:
kill(pid, 0)is the wrong liveness primitive. Pid reuse leaves a deadreservation unprunable, and every future budget on that machine is
permanently smaller — a symptom nobody attributes to a stale file. Closing it
with process start times costs three platform paths.
flockper reservation is the right one, and is already in the tree. Onefile per reservation held under
LOCK_EXfor the life of the process; thekernel releases it on any exit. A reader takes
LOCK_SH | LOCK_NBand a fileit can lock is dead. The refcounted,
atfork-safe,CLOEXECimplementationis at
src/waste.c:117, landed asexclusive_openin Add opt-in exclusive model-container ownership #29 — same technique,different key.
means any local user can publish a 10 TB reservation and starve the machine;
per-user is safe and blind exactly where the harm is real, on a shared box.
This is a choice, not a cost, and it comes before a file format.
believe they are alone, and share one kernel's RAM. Silent under-counting in
a safety mechanism is worse than no mechanism, because the printed budget
line then looks like it was checked against something.
waste.hsays no global state. A cross-process ledger is the first thingthis project would write outside a container directory. That is a decision
about what the library is.
of live reservations is not fixed for the life of the process. What survives
is that its volatility is declared and attributable: a smaller budget is
always matched by a real, still-live claim, rather than by a transient that
has already gone. That is enough to admit the input; it is not determinism,
and the cost has to be accepted openly.
Gates, and the first one must not be run the way #31's was
#31's gate 1 cost a reboot because the unmanaged arm is the dangerous one.
That is unavoidable here too, so it has to be bounded by the host rather than
by hope.
hand to the budget a ledger would have picked — the cap split between them.
Unlike Two auto-budget opens on one machine each size against the whole machine #31's gate 2 this is a safe arm by construction, since two floors are
46% of a 128 GB host. If two processes sharing the ceiling are meaningfully
faster than two contending for all of it, there is something to engineer.
@Lrrr908 has the machine this needs — 128 GB, Linux, and a K3 container, from
#37 — and gate 1 is the arm a 64 GB host can never select. No obligation
attached; noting it because it is the only host in this project's reach where
the question is answerable safely.
Non-goals
--budget.is what
exclusive_openalready does, opt-in, and Two auto-budget opens on one machine each size against the whole machine #31's criticism of its keystands — it just turns out the right predicate has no non-refusing answer in
the 64 GB case.
refusing, or not duplicating the trunk, which is a different engine shape.
Done when
docs/LEARNED.mdhas a dated entry with the gate-1 numbers, and either amechanism behind them or the reason there is none — the second outcome being as
good as the first.