Up front
I do not think this is your bug, and I want to be clear about that before
describing it. The extension's own memory behaviour is fine and its cleanup is
correct — I checked. But it appears to be the trigger for a kernel-level leak in
the NVIDIA driver, and you may want to know, and may be able to mitigate.
Environment
- Live Lock Screen 3.2.0 (version 8)
- GNOME Shell 50.3, Wayland
- Fedora 44, kernel 7.1.4-200.fc44.x86_64
- NVIDIA RTX 3090, driver 610.43.03 (open kernel module)
- GStreamer 1.28.5,
gstreamer1-plugin-gtk4-0.15.2
- 32 GB RAM
- Also enabled:
unblank@sun.wxg@gmail.com (prevents screen blanking — likely
relevant, see below)
What happened
Two system-wide OOM events, 19 processes killed by the kernel, including the
audio server, input method, file manager, and terminal.
The memory was not held by the extension or its player process. At the
moment of the second OOM, the player process (gjs, PID 15373) held 374 kB of
anonymous memory. Every process on the system combined held 213 MB, on a 32 GB
machine. ~30 GB was held by kernel-side allocations, and the OOM killer was
invoked from the NVIDIA driver's own KMS thread:
KMS thread invoked oom-killer: gfp_mask=0x40dc0(GFP_KERNEL|__GFP_ZERO|__GFP_COMP), order=3
slab_unreclaimable:4409875 (16.8 GB)
sec_pagetables:2841472kB (2.8 GB, with no VM running)
all_unreclaimable? yes
Your code is not at fault
I read through core/player_process.js and extension.js before filing, so
you do not have to defend against the obvious guesses:
PlayerProcess.destroy() closes stdin and sends SIGKILL to the subprocess.
disable() calls this._player?.destroy() and nulls it.
metadata.json declares "session-modes": ["unlock-dialog"], so the player
only exists while locked.
I confirmed this empirically. Six lock/unlock cycles happened in five minutes
(PIDs 10455, 14454, 14772, 14988, 15167, 15373). The kernel's OOM task dump at
23:42:43 shows only PID 15373 alive — every earlier player was correctly
reaped. No process leak, no fd leak that I could see.
The two patterns that seem to provoke it
1. Pipeline churn. Six create/destroy cycles of a GPU video pipeline in five
minutes. First OOM followed twelve minutes later.
2. Sustained looped playback. The second OOM came after PID 15373 had been
decoding and compositing continuously for 12.8 hours — screen locked
overnight, background-video-looped on. This is where unblank matters:
without it the display would blank and presumably reduce the work; with it, the
pipeline runs flat out all night.
Concretely, that run was:
- A 75-second 3840x2160 60 fps H.264 file
- Looped via
seek_simple on EOS, so roughly 613 flushing seeks
- Roughly 2.76 million frames decoded and presented
Worth knowing, and possibly worth a line in your README: during both crashes
playbin was autoplugging a software decoder (openh264dec, rank
marginal), so 4K60 was being chewed by the CPU and then uploaded per-frame to
the GPU.
The cause turned out to be a stale GStreamer plugin registry
(~/.cache/gstreamer-1.0/registry.x86_64.bin). It had been generated at the
exact minute the NVIDIA driver was installed, before libcuda.so.1 existed, so
nvcodec was cached as having 0 features with the warning CUDA library "libcuda.so.1" was not found. It never re-probed. Deleting the cache fixed it —
nvh264dec now registers at rank primary + 1 (257).
This is not your bug either, but it will silently hit any user who installs your
extension around the same time as a GPU driver, and the symptom is just "the
lock screen is heavy". A troubleshooting line suggesting
rm ~/.cache/gstreamer-1.0/registry.*.bin might save people some confusion.
Possible mitigations on your side
Offered as suggestions, not demands — the real fix belongs in the driver.
-
Idle timeout. After N minutes locked with no input, pause the pipeline
(you already have _player.pause() wired up for prepare-for-sleep) or tear
it down and show a static frame. Nobody is watching an animated background at
4 a.m., and it would cap the exposure for everyone on NVIDIA.
-
Pause on blank. Hook the screen-blank signal the same way you hook
prepare-for-sleep. Users running unblank won't benefit, but most will.
-
README note. A line about NVIDIA proprietary/open driver + long lock
sessions, until the driver is fixed. Would save the next person the two days
I spent reading OOM dumps.
-
Cycle debounce. Rapid lock/unlock currently spawns a fresh GStreamer
pipeline each time. A short grace period before teardown would collapse the
churn case.
Happy to test
I have a reliable-ish reproduction environment and I am glad to test patches,
try settings combinations, or collect more kernel data. Just say what would
help.
oom-evidence-trimmed.txt
system-info.txt
Up front
I do not think this is your bug, and I want to be clear about that before
describing it. The extension's own memory behaviour is fine and its cleanup is
correct — I checked. But it appears to be the trigger for a kernel-level leak in
the NVIDIA driver, and you may want to know, and may be able to mitigate.
Environment
gstreamer1-plugin-gtk4-0.15.2unblank@sun.wxg@gmail.com(prevents screen blanking — likelyrelevant, see below)
What happened
Two system-wide OOM events, 19 processes killed by the kernel, including the
audio server, input method, file manager, and terminal.
The memory was not held by the extension or its player process. At the
moment of the second OOM, the player process (
gjs, PID 15373) held 374 kB ofanonymous memory. Every process on the system combined held 213 MB, on a 32 GB
machine. ~30 GB was held by kernel-side allocations, and the OOM killer was
invoked from the NVIDIA driver's own
KMS thread:Your code is not at fault
I read through
core/player_process.jsandextension.jsbefore filing, soyou do not have to defend against the obvious guesses:
PlayerProcess.destroy()closes stdin and sendsSIGKILLto the subprocess.disable()callsthis._player?.destroy()and nulls it.metadata.jsondeclares"session-modes": ["unlock-dialog"], so the playeronly exists while locked.
I confirmed this empirically. Six lock/unlock cycles happened in five minutes
(PIDs 10455, 14454, 14772, 14988, 15167, 15373). The kernel's OOM task dump at
23:42:43 shows only PID 15373 alive — every earlier player was correctly
reaped. No process leak, no fd leak that I could see.
The two patterns that seem to provoke it
1. Pipeline churn. Six create/destroy cycles of a GPU video pipeline in five
minutes. First OOM followed twelve minutes later.
2. Sustained looped playback. The second OOM came after PID 15373 had been
decoding and compositing continuously for 12.8 hours — screen locked
overnight,
background-video-loopedon. This is whereunblankmatters:without it the display would blank and presumably reduce the work; with it, the
pipeline runs flat out all night.
Concretely, that run was:
seek_simpleon EOS, so roughly 613 flushing seeksWorth knowing, and possibly worth a line in your README: during both crashes
playbinwas autoplugging a software decoder (openh264dec, rankmarginal), so 4K60 was being chewed by the CPU and then uploaded per-frame tothe GPU.
The cause turned out to be a stale GStreamer plugin registry
(
~/.cache/gstreamer-1.0/registry.x86_64.bin). It had been generated at theexact minute the NVIDIA driver was installed, before
libcuda.so.1existed, sonvcodecwas cached as having 0 features with the warningCUDA library "libcuda.so.1" was not found. It never re-probed. Deleting the cache fixed it —nvh264decnow registers at rankprimary + 1 (257).This is not your bug either, but it will silently hit any user who installs your
extension around the same time as a GPU driver, and the symptom is just "the
lock screen is heavy". A troubleshooting line suggesting
rm ~/.cache/gstreamer-1.0/registry.*.binmight save people some confusion.Possible mitigations on your side
Offered as suggestions, not demands — the real fix belongs in the driver.
Idle timeout. After N minutes locked with no input, pause the pipeline
(you already have
_player.pause()wired up forprepare-for-sleep) or tearit down and show a static frame. Nobody is watching an animated background at
4 a.m., and it would cap the exposure for everyone on NVIDIA.
Pause on blank. Hook the screen-blank signal the same way you hook
prepare-for-sleep. Users runningunblankwon't benefit, but most will.README note. A line about NVIDIA proprietary/open driver + long lock
sessions, until the driver is fixed. Would save the next person the two days
I spent reading OOM dumps.
Cycle debounce. Rapid lock/unlock currently spawns a fresh GStreamer
pipeline each time. A short grace period before teardown would collapse the
churn case.
Happy to test
I have a reliable-ish reproduction environment and I am glad to test patches,
try settings combinations, or collect more kernel data. Just say what would
help.
oom-evidence-trimmed.txt
system-info.txt