Skip to content

Core process hangs at 60-98% CPU with rapid memfd_create/mmap/munmap churn (~1000Hz), app becomes unresponsive #408

Description

@leabergero

Preflight checklist

  • I have searched the existing issues and believe this will not be a duplicate of any existing issue. (Closely related to High write volume when action images update frequently #249, but that issue is about disk write volume specifically — this report has strace evidence showing the loop also churns memory-mapped buffers at ~1000Hz, which I don't believe has been documented before, and is severe enough to make the whole application and any attached hardware controller unresponsive rather than just a disk-wear concern.)
  • I understand that if this issue is about support for non-Elgato or non-Tacto hardware, it will be closed without explanation, as per issue Statement regarding device support #38, and that it should be raised in the repository of the plugin that provides support for the hardware. (This is not a hardware-support request — the CPU hang is entirely inside the opendeck core process itself and reproduces with zero device I/O activity, confirmed via plugin-side logging and strace. See below.)
  • I will provide the OpenDeck log file and the log files of plugins involved, where applicable.
  • I will provide my operating system information and method of installation, as well as any steps I have taken to troubleshoot the issue.
  • I certify that I am using the latest available version of OpenDeck, and that I will provide enough information to reproduce the issue.

Summary

opendeck (the core process, not any plugin subprocess) gets stuck in a tight loop that saturates 1 CPU core (60-98% sustained) and grows from ~16-20 threads to 60-70 threads within 1-5 minutes of a fresh launch. Once it starts, the whole application becomes unresponsive: hardware controller buttons/encoders stop firing actions, and any animated action (GIF, live graph, etc.) stops updating. The process does not crash — it stays alive, consuming CPU, until manually killed and restarted, at which point the same thing happens again shortly after.

This also occurred on 2.12.1 before I upgraded to 2.14.0 today, so it is not a 2.14.0 regression specifically — it's been happening consistently for roughly the last 3 weeks after months of trouble-free daily use, on both the old and new version.

Environment

  • OpenDeck version: 2.14.0 (also reproduced on 2.12.1)
  • Installation method: official .deb from GitHub releases (apt install ./opendeck_2.14.0_amd64.deb)
  • OS: Ubuntu 24.04, GNOME/Wayland session
  • Hardware controller: a community-supported HOTSPOTEK/Mirabox Stream Dock K1 Pro (via a third-party plugin) — noted only for context; see below for why this is not a hardware-support issue
  • ~17 plugins installed in total (mix of official/community, e.g. gif player, key macro, menu navigator, weather, Home Assistant, Google Meet, graphs, counters, etc.)

Steps to reproduce (as narrowed down so far)

  1. Launch opendeck --hide (the normal autostart invocation) or without --hide — happens either way.
  2. Within 1-5 minutes, CPU usage of the opendeck process climbs to 60-98% sustained and stays there; thread count grows from the initial ~16-20 to 60-70+.
  3. The controller/UI stops responding to input; any button configured to play an animated GIF (via a community GIF-player plugin) stops advancing frames.

Isolation steps taken

  • Ruled out third-party plugins as the sole cause: moved all non-essential third-party plugins out of ~/.config/opendeck/plugins/, leaving only 5 first-party-authored plugins + the bundled Starter Pack. The hang still reproduced in under 3 minutes.
  • Ruled out --hide vs. windowed mode: reproduces identically either way.
  • Ruled out the controller's own plugin process: while the core opendeck process was pegged at 80-90%+ CPU with 60+ threads, the plugin subprocess that talks to the physical hardware stayed at 0.2-2.3% CPU with a stable ~16 threads the entire time. So whatever is spinning is not in a plugin process.
  • Confirmed it reproduces with zero device I/O: during one hang, the hardware plugin's own log showed no button/encoder events and no image writes to the device for the entire duration — the opendeck core was still climbing in CPU regardless.
  • Ruled out USB power management: power/control for the controller is on (autosuspend disabled), power profile is performance, no relevant power-management package changes in the timeframe this started.
  • Likely trigger: profiles with actions that update their button image frequently. I have ~10 actions across a few profile pages using a community GIF-player plugin (animated loop, so setImage/feedback calls at the GIF's native frame rate, same category of "frequently updating action image" as reported in High write volume when action images update frequently #249, which mentions the Graphs plugin causing the same class of problem). I did not conclusively isolate GIF actions as the sole trigger (didn't get to remove them and retest before capturing the trace below), but the timing and mechanism line up closely with High write volume when action images update frequently #249.

strace -f -c evidence

Attached to the core opendeck process (not any plugin) while it was in the hung state, for ~66 seconds:

% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ------------------
 84.79 1033.568391       49026     21082      6737 futex
  7.88   96.082582        1290     74469           epoll_wait
  4.35   53.064010         176    300076           poll
  0.84   10.238400          48    211717           close
  0.68    8.298120         631     13137           madvise
  0.43    5.300121          79     66589           munmap
  0.21    2.588760           4    598991           statx
  0.15    1.829496          25     72772      1473 recvfrom
  0.08    0.973247           7    133058           getdents64
  0.08    0.936356           5    182477           read
  0.07    0.817626          11     71493           openat
  0.05    0.665954           9     66655     66655 mkdir
  0.04    0.546701           7     69842           write
  0.04    0.446063           6     66529           memfd_create
  0.04    0.435455           6     66588           mmap
  0.02    0.274947           3     68917           fstat
  ... (full table available on request)
------ ----------- ----------- --------- --------- ------------------
100.00 1218.946190         521   2336406     82033 total

Normalized to calls/second over the trace window, the standout pattern is four syscalls moving in lockstep at essentially the same rate:

  • memfd_create: ~1008/s
  • mmap: ~1009/s
  • munmap: ~1009/s
  • ftruncate: ~1008/s

...alongside mkdir at ~1010/s with a 100% error rate (every single call in the trace failed — consistent with something unconditionally trying to (re)create a directory that already exists on every iteration instead of checking first), statx at ~9076/s, poll at ~4547/s, close at ~3208/s, and getdents64 at ~2016/s.

That memfd_createmmapmunmapftruncate group at a near-identical, very high rate looks like a buffer being allocated, mapped, and torn down again on every iteration of some loop that never settles — i.e. broader than just "writes a file to disk too often" (#249): it looks like it may also be re-allocating a shared-memory-backed image/rendering buffer at well over any reasonable frame rate, which would explain why the whole app (not just the affected action) becomes unresponsive rather than just doing excess disk I/O.

Suggested next steps

  • If this is the same root cause as High write volume when action images update frequently #249 (the per-action image/profile write debounce), it seems the fix in 2.11.1 doesn't fully cover this case, or there's a related code path (in-memory buffer handling for frequently-updated action images, maybe via memfd_create for shared image buffers) that has the same "no debounce / no settle" problem.
  • Happy to provide the full strace output, opendeck.log, and plugin logs, and to do further isolation testing (e.g. confirming whether removing the GIF actions specifically stops the hang) if that would help narrow this down further.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions