The generic paging core, lifted to atlas-tier (CUDA- and verbs-free).
Re-exported under the atlas_tier names (no historical aliases).
O_DIRECT fixed-stride swap file on NVMe (the peer’s cold tier). record_bytes
MUST be a 4 KiB multiple (O_DIRECT) — the SSM snapshot blob (66,846,720 B =
16,320 × 4 KiB) already is. Records are addressed by disk_slot at
disk_slot * record_bytes; the file grows sparsely as slots are allocated.
The generic paging core, lifted to atlas-tier (CUDA- and verbs-free).
Re-exported under the atlas_tier names (no historical aliases).
Host-RAM SwapStore over a HashMap. Records live in ordinary heap
memory — the “swap” tier when no NVMe directory is configured (unbounded,
still LRU-ordered by the residency).
SlotArena over the peer’s RDMA-registered mmap region (a raw base ptr).
The peer memcpys between an arena slot and the disk swap on spill/fault; the
client one-sided-RDMAs into/out of the same slots. The base VA is stable and
registered ONCE per rail — this NEVER re-registers (no MR churn).
The tier a paging arena serves. Only the RW paging kinds (SSM, KV-as-paging)
ride the CacheServerParams single-base+rkey reply; the read-only tiers
(experts/weights/lora) speak a different manifest+VerbsServerParams dialect
and are NOT accepted on this handshake (rejected in parse_paging_header).
The generic paging core, lifted to atlas-tier (CUDA- and verbs-free).
Re-exported under the atlas_tier names (no historical aliases).
The page table: key → Loc over a bounded SlotArena (hot) backed by an
unbounded SwapStore (cold), with LRU eviction of resident slots to disk.
The generic paging core, lifted to atlas-tier (CUDA- and verbs-free).
Re-exported under the atlas_tier names (no historical aliases).
Host-RAM SlotArena over one flat Vec<u8>. The hot tier for in-process
consumers — e.g. the unified SSM spill store’s RAM cache. Allocates
slot_bytes * num_slots up front.
The ONLY accepted first u64 on the RW paging port (“PAGE” + 2, v2-only
): after the magic comes a [u8 kind] byte so ONE peer serves
a registry of per-(kind, shape) arenas, then [u64 arena_bytes][u64 blob_bytes] — blob_bytes == 0 selects the RAW one-sided mode.
The generic paging core, lifted to atlas-tier (CUDA- and verbs-free).
Re-exported under the atlas_tier names (no historical aliases).
The hot tier: a RAM arena as a set of num_slots fixed-size slots. The
cache peer implements this over its mmap’d MR (page-aligned →
O_DIRECT-safe); in-process consumers use crate::VecSlotArena.
The generic paging core, lifted to atlas-tier (CUDA- and verbs-free).
Re-exported under the atlas_tier names (no historical aliases).
The cold tier: an unbounded fixed-stride record store addressed by a
monotonic disk_slot index. The peer implements this over an O_DIRECT NVMe
file (crate::DirectSwapFile); crate::MemSwapStore is the host-RAM
variant.
Execute one control op against the residency and return the reply. Pure over
the (already unit-tested) Residency, so the protocol is testable
without a socket or RDMA.
Encode the CLIENT half of the v2 paging handshake header — what EVERY
paging client sends first: KV paging, SSM paging (connect_paging), and
both RAW one-sided modes (via blob_bytes == 0):
[u64 PAGING_MAGIC_V2 LE][u8 kind][u64 arena_bytes LE][u64 blob_bytes LE]
— 25 bytes, followed by the unchanged [u8 n_rails] RailSet exchange.
Lives in this ONE shared module (beside parse_paging_header, its peer
half) so writer and reader can never drift; byte-frozen and golden-pinned
in wire_tests.rs.
Parse the paging handshake header after the caller has read the first u64.
v2-only: the first u64 MUST be PAGING_MAGIC_V2, then
[u8 kind][u64 arena_bytes][u64 blob_bytes]. blob_bytes == 0 = the RAW
one-sided mode (per-connection arena, client-owned allocator — the caller
routes it OFF the paging registry). Rejects unsupported kinds (≥2), the
retired v1 magic (dedicated diagnostic so a stale binary fails legibly),
and any other first u64 (e.g. a bare legacy total_bytes).
Shared variant of run_paging_loop: many connection threads drive ONE
process-global residency, locking it per request. This is what makes the
peer a SHARED warm cache — a snapshot PUT by one client is GET-able by
another (same namespace). The lock is held only for the (fast) map op + any
spill/fault byte move, never across a TCP read.
Round-robin stripe a blob_bytes transfer into chunk_bytes chunks across
n_rails, returning per-rail lists of (offset, len). The offset is the
chunk’s position in BOTH the (single, contiguous) staging buffer and the peer
arena slot — so whichever rail fetches chunk j, it lands at its true offset
and one memcpy reassembles the blob (the verified inc-6 reassembly fix). The
tail chunk carries the short remainder, never chunk_bytes.