Firefox floods the X server with XkbGetUpdatedMap requests when switching ibus input methods, stops responding to input
Categories
(Core :: Widget: Gtk, defect, P2)
Tracking
()
People
(Reporter: da-wgh, Assigned: da-wgh)
Details
Attachments
(2 files)
330 bytes,
application/octet-stream
|
Details | |
47 bytes,
text/x-phabricator-request
|
RyanVM
:
approval-mozilla-esr78+
|
Details | Review |
I use Firefox 78.4.1esr, X server and ibus (provides input method switching) on Linux.
Every time I change the input method, Firefox bombards the X server with tens of thousands XkbGetUpdatedMap requests (see attached trace_procxkbgetmap_per_second.bt for reference how I obtained this data). This is the result of changing the input method just once:
@total1[uprobe:/usr/bin/X:ProcXkbGetMap]: 26036 # <- how many times the X server called this function
# how many times each process called this function (not all programs use libX11 to communicate with the X server, though)
@total2[uprobe:/usr/lib/libX11.so.6.3.0:XkbGetUpdatedMap, 3914837, alacritty]: 1
@total2[uprobe:/usr/lib/libX11.so.6.3.0:XkbGetUpdatedMap, 3916102, alacritty]: 1
@total2[uprobe:/usr/lib/libX11.so.6.3.0:XkbGetUpdatedMap, 3915717, alacritty]: 1
@total2[uprobe:/usr/lib/libX11.so.6.3.0:XkbGetUpdatedMap, 3862501, alacritty]: 1
@total2[uprobe:/usr/lib/libX11.so.6.3.0:XkbGetUpdatedMap, 3889826, parcellite]: 1
@total2[uprobe:/usr/lib/libX11.so.6.3.0:XkbGetUpdatedMap, 3916118, alacritty]: 1
@total2[uprobe:/usr/lib/libX11.so.6.3.0:XkbGetUpdatedMap, 3915869, alacritty]: 1
@total2[uprobe:/usr/lib/libX11.so.6.3.0:XkbGetUpdatedMap, 3412279, ibus-x11]: 2
@total2[uprobe:/usr/lib/libX11.so.6.3.0:XkbGetUpdatedMap, 3317212, Web Content]: 2
@total2[uprobe:/usr/lib/libX11.so.6.3.0:XkbGetUpdatedMap, 3315983, Web Content]: 2
@total2[uprobe:/usr/lib/libX11.so.6.3.0:XkbGetUpdatedMap, 3317601, Web Content]: 2
@total2[uprobe:/usr/lib/libX11.so.6.3.0:XkbGetUpdatedMap, 3412275, ibus-ui-gtk3]: 2
@total2[uprobe:/usr/lib/libX11.so.6.3.0:XkbGetUpdatedMap, 3318887, Web Content]: 2
@total2[uprobe:/usr/lib/libX11.so.6.3.0:XkbGetUpdatedMap, 3318394, Web Content]: 2
@total2[uprobe:/usr/lib/libX11.so.6.3.0:XkbGetUpdatedMap, 3317317, Privileged Cont]: 2
@total2[uprobe:/usr/lib/libX11.so.6.3.0:XkbGetUpdatedMap, 3315910, WebExtensions]: 2
@total2[uprobe:/usr/lib/libX11.so.6.3.0:XkbGetUpdatedMap, 3320616, Web Content]: 2
@total2[uprobe:/usr/lib/libX11.so.6.3.0:XkbGetUpdatedMap, 3316691, Web Content]: 2
@total2[uprobe:/usr/lib/libX11.so.6.3.0:XkbGetUpdatedMap, 3315863, Web Content]: 2
@total2[uprobe:/usr/lib/libX11.so.6.3.0:XkbGetUpdatedMap, 3315791, firefox]: 25953
When this happens, Firefox doesn't respond to text input. These calls take several seconds to complete, so I have to wait that time every time after input method switching to continue typing, which is pretty bad.
I have captured the Firefox call stack samples with perf, and this is how they look like:
Children Self Command Shared Object Symbol
- 91.12% 0.00% firefox /usr/lib64/firefox/libxul.so 0x7f504c6fb97d l [.] XRE_main ◆
XRE_main libxul.so ▒
XREMain::XRE_main libxul.so ▒
XREMain::XRE_mainRun libxul.so ▒
nsAppStartup::Run libxul.so ▒
nsBaseAppShell::Run libxul.so ▒
MessageLoop::Run libxul.so ▒
-→mozilla::ipc::MessagePump::Run libxul.so ▒
-→91.12% NS_ProcessNextEvent libxul.so ▒
-→nsThread::ProcessNextEvent libxul.so ▒
-→90.85% nsBaseAppShell::OnProcessNextEvent libxul.so ▒
-→90.84% nsBaseAppShell::DoProcessNextNativeEvent libxul.so ▒
-→nsAppShell::ProcessNextNativeEvent libxul.so ▒
- 90.83% g_main_context_iteration libglib-2.0.so.0.6600.2 ▒
-→90.82% g_main_context_iterate.isra.0 libglib-2.0.so.0.6600.2 ▒
-→90.59% g_main_context_dispatch libglib-2.0.so.0.6600.2 ▒
- 90.56% 0x7f5051de72e1 libgdk-3.so.0.2404.18 ▒
- 0x7f5051e19aba libgdk-3.so.0.2404.18 ▒
- 90.56% 0x7f5051de769a libgdk-3.so.0.2404.18 ▒
- _gdk_x11_event_translator_translate libgdk-3.so.0.2404.18 ▒
- 90.55% gdk_x11_display_translate_event libgdk-3.so.0.2404.18 ▒
- 90.55% g_signal_emit_by_name libgobject-2.0.so.0.6600.2 ▒
- 90.55% g_signal_emit_valist libgobject-2.0.so.0.6600.2 ▒
-→90.54% signal_emit_unlocked_R libgobject-2.0.so.0.6600.2 ▒
-→89.83% g_closure_invoke libgobject-2.0.so.0.6600.2 ▒
-→88.93% mozilla::widget::ResetBidiKeyboard libxul.so ▒
-→88.44% nsBidiKeyboard::Reset libxul.so ▒
-→87.53% gdk_x11_keymap_have_bidi_layouts libgdk-3.so.0.2404.18 ▒
+→54.87% XkbGetUpdatedMap libX11.so.6.3.0 ▒
+→29.65% XkbGetControls libX11.so.6.3.0 ▒
+→2.71% get_xkb libgdk-3.so.0.2404.18
It's hard to tell which problem this actually is. i3 window manager also had similar problem with ibus, but it was alleviated with caching in xkbcommon (not yet released). https://github.com/i3/i3/issues/3924
mozilla::widget::ResetBidiKeyboard
itself is being called so many times, but looking at the code it's not immediately obvious why. I'm open to assist with tracing and debugging.
When Firefox is freshly launched, the number of mozilla::widget::ResetBidiKeyboard
is just several hundred per input method switch, and no visible lag occurs. The numbers becomes problematic only after Firefox is running long enough.
InitBySystemSettingsX11
seems to be called after the reset (since mInitialized
is cleared). Could it be that g_signal_connect
is not idempotent, and duplicate signal connections accumulate and cause this slowdown? I'll try to write a patch for that, and see if it helps.
When ibus input method is changed, Firefox reinitializes the KeymapWrapper
object, causing duplicate calls to g_signal_connect. If Firefox is running
long enough, duplicate handlers accumulate, and Firefox starts to barrage the
X server with XkbGetUpdatedMap/XkbGetControls calls, slowing the X server and
itself down.
A symptom of this problem is that after switching the input methods, Firefox
ignores the input for a while (up to several seconds).
Updated•4 years ago
|
Comment 4•4 years ago
|
||
Thanks for the patch, will look at it.
I'm running Firefox with the patch for several days, it certainly helps.
Comment 7•4 years ago
|
||
bugherder |
Hey, any chance of backporting it to ESR? It would be pretty annoying to live with this bug for extra half a year. The lag is severe enough, and ibus is default thing on many desktop environments.
Comment 9•4 years ago
|
||
Comment on attachment 9191506 [details]
Bug 1680909 - Fix slowdown in X keyboard layout handling. r=stransky
ESR Uplift Approval Request
- If this is not a sec:{high,crit} bug, please state case for ESR consideration: When X11 input method is changed (i.e. keyboard layout change) Firefox freezes and it's unusable. It's caused by redundant callbacks processed by Gtk.
- User impact if declined:
- Fix Landed on Version: 85.0
- Risk to taking this patch: Low
- Why is the change risky/not risky? (and alternatives if risky): Avoid to register more than one handler to "keys-changed" and "direction-changed" gtk callbacks. Should be without any risk.
- String or UUID changes made by this patch: none
Comment 10•4 years ago
|
||
Comment on attachment 9191506 [details]
Bug 1680909 - Fix slowdown in X keyboard layout handling. r=stransky
Approved for 78.7esr.
Comment 11•4 years ago
|
||
bugherder uplift |
Assignee | ||
Comment 12•4 years ago
|
||
Thanks!
Description
•