Skip to content

klipper: keep klippy resident in RAM - #320

Closed
kyleinoregon wants to merge 1 commit into
OpenCentauri:mainfrom
kyleinoregon:klippy-mlock
Closed

klipper: keep klippy resident in RAM#320
kyleinoregon wants to merge 1 commit into
OpenCentauri:mainfrom
kyleinoregon:klippy-mlock

Conversation

@kyleinoregon

Copy link
Copy Markdown

This is the "Timer too close" that several of us have hit at print start (see the comments on #312). I chased one on a Centauri Carbon with CANVAS today and it is not CPU load, it is swap latency.

What happened. Orca uploaded a 7.5 MB G-code file and started the print three seconds later. Moonraker was still parsing the file for metadata. Five seconds in, the first G28 Y failed with Unable to obtain 'trsync_state' response and the main MCU shut down with Timer too close. Host load was 0.2, nothing was printing yet.

Why. The board has 117 MB of RAM and the zram init sets vm.swappiness to 150, so the kernel prefers to page program memory out over dropping file cache. Sampling /proc once a second on an idle printer: klippy had 35 MB of its 48 MB in swap and was taking a handful of major page faults every second. During an upload it took about 150 faults in one second, its resident size fell to 10 MB and free memory to 7 MB. That is the state klippy was in when the MCU needed its trsync reply within a few milliseconds.

All processes together use only 40 MB resident, so this is not a shortage of RAM, it is the swap policy applied to the one process with hard deadlines.

Fix. A small Kalico module, [mlock], that at startup raises RLIMIT_MEMLOCK (the default is 8 MB) and calls mlockall(MCL_CURRENT | MCL_FUTURE | MCL_ONFAULT), falling back to a plain mlockall on kernels without MCL_ONFAULT. It logs what it locked once klippy is ready. Shipped as one more patch in the Kalico recipe, enabled with [mlock] in machine.cfg next to [danger_options].

Measured with it. klippy 46 MB resident, 6 MB of never-touched pages left in swap. Through the same upload and metadata parse: zero page faults, resident size unchanged. Moonraker took the paging instead, which it does not mind. Upload-and-print from Orca then homed and started normally, and the printer went on through a three-hour, 85-change CANVAS print with a pause, a file swap and a cancel in the middle, no Timer too close, no page faults on klippy.

Trade-off: about 48 MB of the 117 MB is now pinned. Free memory sits around 8 to 13 MB with the camera streamer running, and Moonraker lives a bit more in swap. Nothing else changed: swappiness stays at 150, since that was benchmarked for a reason, and this only takes klippy out of that decision.

swappiness alone would only shift the odds; locking the process makes the timing independent of what Moonraker, the camera or a file upload are doing.

The board has 117 MB of RAM and the zram init sets swappiness to 150,
so the kernel prefers to page program memory out over dropping file
cache. Measured on a Centauri Carbon: klippy sat with 35 MB of its
48 MB in swap while idle, taking major page faults every second, and
a G-code upload pushed it further out (about 150 faults in one second,
free memory down to 7 MB). Starting a print right after the upload, as
Orca does, then hit "Unable to obtain 'trsync_state' response" on the
first homing move and "Timer too close" on the main MCU.

Add a small Kalico module, [mlock], that raises RLIMIT_MEMLOCK and calls
mlockall(MCL_CURRENT|MCL_FUTURE) at startup, and enable it in
machine.cfg. With it klippy stays at 46 MB resident and took zero page
faults through the same upload; Moonraker takes the paging instead,
which it does not mind.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@kyleinoregon

Copy link
Copy Markdown
Author

Correction to the write-up above, in fairness to anyone reading it: the memory lock did not fix the print-start shutdown on this printer. The same file failed the same way again with klippy fully locked and zero page faults, so I have taken the lock back out of the printer for now.

What the shutdown dump showed instead: the main MCU was mid-homing, being fed step batches every 50 ms, and the host stopped sending for about 220 ms starting at the exact moment AFC's print-start timer ran. That timer fires 5 s into every print and fetched the file's metadata from Moonraker with a blocking urlopen() on klippy's main thread, no timeout; measured at 360 to 410 ms on this board. With the fetch moved to a helper thread the timer's time on the main thread drops to 7 ms, and the same file now starts cleanly. That fix is going to the AFC fork as its own PR.

What stands from this PR is the measurement: klippy on this board sits 35 of 48 MB in swap and page-faults during uploads, and the lock removes that. It is latency hardening, not the fix for this shutdown, and with only about 10 MB left free after locking it may cost as much as it buys. I'll leave it to you whether it is worth keeping open in that light; happy to reword the description or close it.

@jamesturton

Copy link
Copy Markdown
Collaborator

the memory lock did not fix the print-start shutdown on this printer. The same file failed the same way again with klippy fully locked and zero page faults, so I have taken the lock back out of the printer for now.

If this fix didn't help then I see no reason to keep the PR open

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants