buzz-desktop hardcodes WEBKIT_DISABLE_DMABUF_RENDERER, which #3654 identifies as broken — and it costs ~15% of a CPU core
Summary
buzz-desktop sets WEBKIT_DISABLE_DMABUF_RENDERER=1 for its WebKit child process from inside the binary. #3654 reports that this variable no longer falls back to shared memory on current WebKitGTK and instead leaves the transport mode empty, causing a null-pointer dereference (SIGSEGV) when content needs a compositing layer — and recommends WEBKIT_DMABUF_RENDERER_FORCE_SHM=1 instead.
So Buzz ships with the broken lever enabled by default. On top of the crash exposure described in #3654, I can measure a CPU cost: setting WEBKIT_DMABUF_RENDERER_FORCE_SHM=1 externally reduces the renderer's idle CPU from ~63% to ~48% of a core.
Evidence that Buzz sets it
The string is present in the shipped binaries — both packages:
$ strings -n 8 <appimage-mount>/usr/bin/buzz-desktop.bin | grep -oE 'WEBKIT_[A-Z_]+'
WEBKIT_DISABLE_DMABUF_RENDERER
WEBKIT_DISABLE_COMPOSITING_MODE
$ strings -n 8 /usr/bin/buzz-desktop | grep -oE 'WEBKIT_[A-Z_]+' # .deb build
WEBKIT_DISABLE_DMABUF_RENDERER
WEBKIT_DISABLE_COMPOSITING_MODE
And it appears in the running renderer's environment:
$ tr '\0' '\n' < /proc/<WebKitWebProcess>/environ | grep '^WEBKIT'
WEBKIT_DISABLE_DMABUF_RENDERER=1
It is not set by my shell, by any shell rc file, by ~/.config/environment.d/, or by the AppImage's AppRun / apprun-hooks/linuxdeploy-plugin-gtk.sh — I checked each. The only remaining source is buzz-desktop itself.
Measured cost
Idle, visible window, no user interaction. utime+stime deltas from /proc/<pid>/stat over 60s windows, run from a detached script after a settle period. Phases interleaved A/B/A/B, with Buzz-closed reference phases at both ends to prove the desktop was quiet and did not drift:
| Phase |
kwin_x11 |
Xorg |
WebKitWebProcess |
| 0. closed (reference) |
2.9 % |
4.8 % |
— |
| A1 stock |
93.3 % |
32.8 % |
61.2 % |
B1 + FORCE_SHM |
97.0 % |
34.0 % |
48.5 % |
| A2 stock |
94.4 % |
33.2 % |
65.8 % |
B2 + FORCE_SHM |
92.2 % |
31.2 % |
48.1 % |
| Z. closed (drift check) |
0.7 % |
3.4 % |
— |
The two stock values (61.2, 65.8) and the two FORCE_SHM values (48.5, 48.1) do not overlap, and the FORCE_SHM pair is notably more stable. The compositor and X server are unaffected, as expected — this changes buffer transport, not how much gets composited.
Important limitation: because the variable is set inside the binary, I cannot unset it from outside. So what I measured is adding WEBKIT_DMABUF_RENDERER_FORCE_SHM=1 on top of Buzz's own WEBKIT_DISABLE_DMABUF_RENDERER=1, not replacing it. A build with the flag removed or swapped would likely show the same or better, but I could not test that.
Environment
|
|
| Buzz |
0.5.4 AppImage (md5 66409eb79953315f5a7cb0e10d91af34); same string also in 0.5.2 .deb |
| Toolkit |
WebKitGTK 4.1 + GTK3 |
| OS |
Kubuntu, kernel 7.0.0-28-generic, KDE Plasma 6.6.5 / kwin 6.6.4, X11 |
| Machine |
KVM/QEMU guest, 22 vCPU, 30 GB RAM |
| CPU |
Xeon E5-2680 @ 2.70 GHz — AVX yes, AVX2 no |
| GPU |
virtio-gpu, kernel reports features: -virgl → Mesa 26.0.3 llvmpipe, Accelerated: no |
No GPU acceleration at all here, which is exactly the configuration the dmabuf path cannot help with — and where #3654's recommended FORCE_SHM is the correct transport.
Suggested fix
Related: #3654 (the variable's broken fallback), #3677 (idle renderer/compositor load — a separate and much larger cost on this setup, which this change does not address).
buzz-desktop hardcodes
WEBKIT_DISABLE_DMABUF_RENDERER, which #3654 identifies as broken — and it costs ~15% of a CPU coreSummary
buzz-desktopsetsWEBKIT_DISABLE_DMABUF_RENDERER=1for its WebKit child process from inside the binary. #3654 reports that this variable no longer falls back to shared memory on current WebKitGTK and instead leaves the transport mode empty, causing a null-pointer dereference (SIGSEGV) when content needs a compositing layer — and recommendsWEBKIT_DMABUF_RENDERER_FORCE_SHM=1instead.So Buzz ships with the broken lever enabled by default. On top of the crash exposure described in #3654, I can measure a CPU cost: setting
WEBKIT_DMABUF_RENDERER_FORCE_SHM=1externally reduces the renderer's idle CPU from ~63% to ~48% of a core.Evidence that Buzz sets it
The string is present in the shipped binaries — both packages:
And it appears in the running renderer's environment:
It is not set by my shell, by any shell rc file, by
~/.config/environment.d/, or by the AppImage'sAppRun/apprun-hooks/linuxdeploy-plugin-gtk.sh— I checked each. The only remaining source isbuzz-desktopitself.Measured cost
Idle, visible window, no user interaction.
utime+stimedeltas from/proc/<pid>/statover 60s windows, run from a detached script after a settle period. Phases interleaved A/B/A/B, with Buzz-closed reference phases at both ends to prove the desktop was quiet and did not drift:kwin_x11XorgWebKitWebProcessFORCE_SHMFORCE_SHMThe two stock values (61.2, 65.8) and the two
FORCE_SHMvalues (48.5, 48.1) do not overlap, and theFORCE_SHMpair is notably more stable. The compositor and X server are unaffected, as expected — this changes buffer transport, not how much gets composited.Important limitation: because the variable is set inside the binary, I cannot unset it from outside. So what I measured is adding
WEBKIT_DMABUF_RENDERER_FORCE_SHM=1on top of Buzz's ownWEBKIT_DISABLE_DMABUF_RENDERER=1, not replacing it. A build with the flag removed or swapped would likely show the same or better, but I could not test that.Environment
md5 66409eb79953315f5a7cb0e10d91af34); same string also in 0.5.2.debfeatures: -virgl→ Mesa 26.0.3 llvmpipe,Accelerated: noNo GPU acceleration at all here, which is exactly the configuration the dmabuf path cannot help with — and where #3654's recommended
FORCE_SHMis the correct transport.Suggested fix
WEBKIT_DISABLE_DMABUF_RENDERER=1withWEBKIT_DMABUF_RENDERER_FORCE_SHM=1, per WEBKIT_DISABLE_DMABUF_RENDERER crashes WebKitGTK on NVIDIA instead of falling back to shared memory #3654.FORCE_SHMaddresses that case without the null-transport crash path.Related: #3654 (the variable's broken fallback), #3677 (idle renderer/compositor load — a separate and much larger cost on this setup, which this change does not address).