Skip to content

compositing: Send CompositorDisplayListInfo as bytes to compositor#36484

Merged
mrobinson merged 1 commit intoservo:mainfrom
mrobinson:display-list-info-side-channel
Apr 12, 2025
Merged

compositing: Send CompositorDisplayListInfo as bytes to compositor#36484
mrobinson merged 1 commit intoservo:mainfrom
mrobinson:display-list-info-side-channel

Conversation

@mrobinson
Copy link
Member

CompositorDisplayListInfo is a large data structure that scales with
the size of the display list. Serializing it onto the Compositor's IPC
channel can cause deadlocks. This change serializes it with bincode and
sends it alongside the rest of the serialized display list information
on the IPC bytes_channel. This should prevent deadlocks when the
compositor API is unified.

Testing: This is covered by existing WPT tests.
Signed-off-by: Martin Robinson mrobinson@igalia.com

`CompositorDisplayListInfo` is a large data structure that scales with
the size of the display list. Serializing it onto the Compositor's IPC
channel can cause deadlocks. This change serializes it with bincode and
sends it alongside the rest of the serialized display list information
on the IPC `bytes_channel`. This should prevent deadlocks when the
compositor API is unified.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
@mrobinson mrobinson added the T-linux-wpt Do a try run of the WPT label Apr 12, 2025
@github-actions github-actions bot removed the T-linux-wpt Do a try run of the WPT label Apr 12, 2025
@github-actions
Copy link

🔨 Triggering try run (#14419634449) for Linux (WPT)

@github-actions
Copy link

Test results for linux-wpt from try job (#14419634449):

Flaky unexpected result (26)
  • TIMEOUT /FileAPI/url/url-in-tags-revoke.window.html (#19978)
    • TIMEOUT [expected PASS] subtest: Fetching a blob URL immediately before revoking it works in &lt;script&gt; tags.

      Test timed out
      

  • FAIL [expected PASS] /css/css-conditional/container-queries/container-for-cue.html (#34528)
  • FAIL [expected PASS] /css/css-fonts/font-palette-2.html
  • OK /css/css-fonts/variations/at-font-face-font-matching.html (#20684)
    • FAIL [expected PASS] subtest: Matching font-weight: '400' should prefer '501 550' over '502 560'

      assert_equals: Unexpected font on test element expected 487 but got 532
      

  • FAIL [expected PASS] /css/css-overflow/line-clamp/line-clamp-021.tentative.html (#35008)
  • FAIL [expected PASS] /css/css-overflow/overflow-video.html (#34720)
  • OK /custom-elements/form-associated/ElementInternals-setFormValue.html (#29174)
    • PASS [expected FAIL] subtest: Newline normalization - \r\n in name (urlencoded)
  • OK /encoding/legacy-mb-japanese/euc-jp/eucjp-encode-form-cseucpkdfmtjapanese.html?1-1000
    • FAIL [expected PASS] subtest: U+30AE ギ %A5%AE

      assert_equals: expected "%A5%AE" but got ""
      

    • FAIL [expected PASS] subtest: U+30AF ク %A5%AF

      str is undefined
      

    • FAIL [expected PASS] subtest: U+30B0 グ %A5%B0

      str is undefined
      

    • FAIL [expected PASS] subtest: U+30B1 ケ %A5%B1

      str is undefined
      

    • FAIL [expected PASS] subtest: U+30B2 ゲ %A5%B2

      str is undefined
      

    • FAIL [expected PASS] subtest: U+30B3 コ %A5%B3

      str is undefined
      

    • FAIL [expected PASS] subtest: U+30B4 ゴ %A5%B4

      str is undefined
      

    • FAIL [expected PASS] subtest: U+30B5 サ %A5%B5

      str is undefined
      

    • FAIL [expected PASS] subtest: U+30B6 ザ %A5%B6

      str is undefined
      

    • FAIL [expected PASS] subtest: U+30B7 シ %A5%B7

      str is undefined
      

    • And 390 more unexpected results...
  • OK /encoding/legacy-mb-japanese/shift_jis/sjis-encode-form-x-sjis.html?1-1000
    • FAIL [expected PASS] subtest: U+80 � %80

      assert_equals: expected "%80" but got ""
      

    • FAIL [expected PASS] subtest: U+A5 ¥ %5C

      str is undefined
      

    • FAIL [expected PASS] subtest: U+A7 § %81%98

      str is undefined
      

    • FAIL [expected PASS] subtest: U+A8 ¨ %81%4E

      str is undefined
      

    • FAIL [expected PASS] subtest: U+B0 ° %81%8B

      str is undefined
      

    • FAIL [expected PASS] subtest: U+B1 ± %81%7D

      str is undefined
      

    • FAIL [expected PASS] subtest: U+B4 ´ %81%4C

      str is undefined
      

    • FAIL [expected PASS] subtest: U+B6 ¶ %81%F7

      str is undefined
      

    • FAIL [expected PASS] subtest: U+D7 × %81%7E

      str is undefined
      

    • FAIL [expected PASS] subtest: U+F7 ÷ %81%80

      str is undefined
      

    • And 390 more unexpected results...
  • OK /encoding/legacy-mb-japanese/shift_jis/sjis-encode-href-errors-han.html?1-1000 (#35697)
    • FAIL [expected PASS] subtest: cjk U+4E02 丂 %26%2319970%3B

      assert_equals: expected "%26%2319970%3B" but got ""
      

    • FAIL [expected PASS] subtest: cjk U+4E04 丄 %26%2319972%3B

      assert_equals: expected (string) "%26%2319972%3B" but got (undefined) undefined
      

    • FAIL [expected PASS] subtest: cjk U+4E05 丅 %26%2319973%3B

      assert_equals: expected (string) "%26%2319973%3B" but got (undefined) undefined
      

    • FAIL [expected PASS] subtest: cjk U+4E06 丆 %26%2319974%3B

      assert_equals: expected (string) "%26%2319974%3B" but got (undefined) undefined
      

    • FAIL [expected PASS] subtest: cjk U+4E0C 丌 %26%2319980%3B

      assert_equals: expected (string) "%26%2319980%3B" but got (undefined) undefined
      

    • FAIL [expected PASS] subtest: cjk U+4E0F 丏 %26%2319983%3B

      assert_equals: expected (string) "%26%2319983%3B" but got (undefined) undefined
      

    • FAIL [expected PASS] subtest: cjk U+4E12 丒 %26%2319986%3B

      assert_equals: expected (string) "%26%2319986%3B" but got (undefined) undefined
      

    • FAIL [expected PASS] subtest: cjk U+4E13 专 %26%2319987%3B

      assert_equals: expected (string) "%26%2319987%3B" but got (undefined) undefined
      

    • FAIL [expected PASS] subtest: cjk U+4E1A 业 %26%2319994%3B

      assert_equals: expected (string) "%26%2319994%3B" but got (undefined) undefined
      

    • FAIL [expected PASS] subtest: cjk U+4E1B 丛 %26%2319995%3B

      assert_equals: expected (string) "%26%2319995%3B" but got (undefined) undefined
      

    • And 390 more unexpected results...
  • OK /encoding/legacy-mb-tchinese/big5/big5-encode-form-errors-extBb.html?1-1000
    • FAIL [expected PASS] subtest: extB (pt 2) U+2536B 𥍫 %26%23152427%3B

      assert_equals: expected "%26%23%31%35%32%34%32%37%3B" but got ""
      

    • FAIL [expected PASS] subtest: extB (pt 2) U+2536C 𥍬 %26%23152428%3B

      str is undefined
      

    • FAIL [expected PASS] subtest: extB (pt 2) U+2536D 𥍭 %26%23152429%3B

      str is undefined
      

    • FAIL [expected PASS] subtest: extB (pt 2) U+2536E 𥍮 %26%23152430%3B

      str is undefined
      

    • FAIL [expected PASS] subtest: extB (pt 2) U+2536F 𥍯 %26%23152431%3B

      str is undefined
      

    • FAIL [expected PASS] subtest: extB (pt 2) U+25370 𥍰 %26%23152432%3B

      str is undefined
      

    • FAIL [expected PASS] subtest: extB (pt 2) U+25371 𥍱 %26%23152433%3B

      str is undefined
      

    • FAIL [expected PASS] subtest: extB (pt 2) U+25372 𥍲 %26%23152434%3B

      str is undefined
      

    • FAIL [expected PASS] subtest: extB (pt 2) U+25373 𥍳 %26%23152435%3B

      str is undefined
      

    • FAIL [expected PASS] subtest: extB (pt 2) U+25374 𥍴 %26%23152436%3B

      str is undefined
      

    • And 390 more unexpected results...
  • ERROR /fetch/metadata/generated/serviceworker.https.sub.html (#36247)
    • FAIL [expected PASS] subtest: sec-fetch-site - Same origin, no options - registration

      promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
      

  • OK /fetch/private-network-access/worker-blob-fetch.tentative.window.html (#30064)
    • PASS [expected FAIL] subtest: treat-as-public to public: success.
  • OK /html/browsers/browsing-the-web/navigating-across-documents/008.html (#24456)
    • PASS [expected FAIL] subtest: Link with onclick form submit to javascript url and href navigation
  • OK /html/browsers/browsing-the-web/navigating-across-documents/009.html (#24456)
    • PASS [expected FAIL] subtest: Link with onclick form submit to javascript url with document.write and href navigation
  • OK /html/browsers/browsing-the-web/navigating-across-documents/navigation-unload-cross-origin.sub.window.html (#29056)
    • FAIL [expected PASS] subtest: Cross-origin navigation started from unload handler must be ignored

      promise_test: Unhandled rejection with value: object "SecurityError: The operation is insecure."
      

  • OK /html/browsers/windows/embedded-opener-remove-frame.html (#23867)
    • PASS [expected FAIL] subtest: opener of discarded auxiliary browsing context
  • PASS [expected FAIL] /html/canvas/element/manual/drawing-text-to-the-canvas/canvas.2d.disconnected-font-size-math.html (#30063)
  • OK [expected CRASH] /html/canvas/offscreen/canvas-host/2d.canvas.host.size.large.worker.html (#30164)
  • TIMEOUT [expected OK] /html/infrastructure/urls/base-url/document-base-url-window-initiator-is-not-opener.https.window.html (#30970)
  • OK /html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-into-iframe.html
    • FAIL [expected PASS] subtest: NOT invoking resource selection by inserting into other document with src set

      assert_equals: expected 3 but got 1
      

  • CRASH [expected TIMEOUT] /html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-2.html (#22154)
  • OK /html/semantics/forms/form-submission-0/form-data-set-usv.html (#34934)
    • FAIL [expected PASS] subtest: Strings from form controls should be converted to Unicode scalar values in form submission

      assert_equals: expected "69 6e 70 75 74 31 ef bf bd 3d 69 6e 70 75 74 31 ef bf bd 0d 0a 69 6e 70 75 74 32 ef bf bd 3d 69 6e 70 75 74 32 ef bf bd 0d 0a 69 6e 70 75 74 33 ef bf bd 3d 69 6e 70 75 74 33 ef bf bd 0d 0a 69 6e 70 75 74 34 ef bf bd 3d 69 6e 70 75 74 34 ef bf bd 0d 0a" but got "\n  \n  \n    option\n  \n  \n  \n\n\n\n\"use strict\";\n\nconst form = document.querySelector(\"form\");\n\nfor (let el of Array.from(form.querySelectorAll(\"input\"))) { // Firefox/Edge support\n  el.name = el.id + \"\\uDC01\";\n  el.value = el.id + \"\\uDC01\";\n}\n\nconst select = document.querySelector(\"select\");\nselect.name = select.id + \"\\uDC01\";\nselect.firstElementChild.value = select.id + \"\\uDC01\";\n\n"
      

  • OK /html/semantics/forms/form-submission-0/form-submit-iframe-then-location-navigate.html (#29634)
    • FAIL [expected PASS] subtest: Verifies that location navigations take precedence when following form submissions.

      assert_equals: expected "/html/semantics/forms/form-submission-0/resources/location.html" but got "/html/semantics/forms/form-submission-0/resources/form.html"
      

  • OK [expected TIMEOUT] /html/semantics/forms/form-submission-0/reparent-form-during-planned-navigation-task.html (#29724)
    • PASS [expected TIMEOUT] subtest: reparent-form-during-planned-navigation-task
  • OK /html/semantics/scripting-1/the-script-element/execution-timing/077.html (#22139)
    • FAIL [expected PASS] subtest: adding several types of scripts through the DOM and removing some of them confuses scheduler

      assert_array_equals: expected property 1 to be "Script #1 ran" but got "Script #3 ran" (expected array ["Script #2 ran", "Script #1 ran", "Script #3 ran", "Script #4 ran"] got ["Script #2 ran", "Script #3 ran", "Script #4 ran", "Script #1 ran"])
      

Stable unexpected results that are known to be intermittent (19)
  • OK /_webgl/conformance/textures/misc/texture-upload-size.html (#21770)
    • FAIL [expected PASS] subtest: WebGL test #44

      assert_true: could not create image (SVG) expected true got false
      

  • OK /content-security-policy/frame-ancestors/frame-ancestors-path-ignored.window.html (#36468)
    • PASS [expected FAIL] subtest: A 'frame-ancestors' CSP directive with a URL that includes a path should be ignored.
  • OK /fetch/metadata/generated/css-font-face.https.sub.tentative.html (#32732)
    • PASS [expected FAIL] subtest: sec-fetch-dest
  • OK /html/browsers/browsing-the-web/navigating-across-documents/initial-empty-document/iframe-nosrc.html (#34819)
    • FAIL [expected PASS] subtest: form submission

      assert_equals: expected "http://web-platform.test:8000/common/blank.html?1=" but got "about:blank"
      

  • OK /html/browsers/browsing-the-web/navigating-across-documents/initial-empty-document/iframe-src-aboutblank-navigate-immediately.html (#29048)
    • FAIL [expected PASS] subtest: Navigating to a different document with form submission

      assert_equals: expected "http://web-platform.test:8000/common/blank.html?1=" but got "about:blank"
      

  • OK /html/browsers/browsing-the-web/navigating-across-documents/refresh/same-document-refresh.html (#34597)
    • FAIL [expected PASS] subtest: Same-Document Referrer from Refresh

      assert_equals: original page loads expected "http://web-platform.test:8000/html/browsers/browsing-the-web/navigating-across-documents/refresh/resources/refresh-with-section.sub.html?url=%23section" but got "http://web-platform.test:8000/html/browsers/browsing-the-web/navigating-across-documents/refresh/resources/refresh-with-section.sub.html?url=%23section#section"
      

  • OK /html/browsers/history/the-history-interface/traverse_the_history_5.html (#21383)
    • FAIL [expected PASS] subtest: Multiple history traversals, last would be aborted

      assert_array_equals: Pages opened during history navigation expected property 1 to be 5 but got 3 (expected array [6, 5] got [6, 3])
      

  • ERROR [expected TIMEOUT] /html/canvas/element/manual/imagebitmap/createImageBitmap-serializable.html (#34120)
  • OK [expected CRASH] /html/canvas/offscreen/canvas-host/2d.canvas.host.size.large.html (#34117)
  • OK [expected TIMEOUT] /html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-1.html (#22647)
  • OK [expected CRASH] /html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-3.html (#24057)
  • OK [expected TIMEOUT] /html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-1.html (#24066)
    • FAIL [expected NOTRUN] subtest: Check that popups from a sandboxed iframe do not escape the sandbox

      assert_equals: It came from a sandboxed iframe expected "null" but got "http://web-platform.test:8000"
      

  • OK /html/semantics/forms/form-submission-0/multipart-formdata.window.html (#28725)
    • PASS [expected FAIL] subtest: multipart/form-data: 0x00 in name (normal form)
  • OK /html/semantics/forms/form-submission-0/text-plain.window.html (#28687)
    • PASS [expected FAIL] subtest: text/plain: 0x00 in filename (formdata event)
  • OK /navigation-timing/test-navigation-type-reload.html (#33334)
    • FAIL [expected PASS] subtest: Reload domComplete &gt; Original domComplete

      assert_true: Reload domComplete &gt; Original domComplete expected true got false
      

    • FAIL [expected PASS] subtest: Reload loadEventEnd &gt; Original loadEventEnd

      assert_true: Reload loadEventEnd &gt; Original loadEventEnd expected true got false
      

    • FAIL [expected PASS] subtest: Reload loadEventStart &gt; Original loadEventStart

      assert_true: Reload loadEventStart &gt; Original loadEventStart expected true got false
      

  • OK /resize-observer/eventloop.html (#33599)
    • PASS [expected FAIL] subtest: test0: multiple notifications inside same event loop
  • ERROR /service-workers/idlharness.https.any.html (#36250)
    • TIMEOUT [expected PASS] subtest: ServiceWorkerContainer interface: operation register((TrustedScriptURL or USVString), optional RegistrationOptions)

      Test timed out
      

    • TIMEOUT [expected PASS] subtest: NavigationPreloadManager interface: operation enable()

      Test timed out
      

    • TIMEOUT [expected PASS] subtest: NavigationPreloadManager interface: operation disable()

      Test timed out
      

    • TIMEOUT [expected PASS] subtest: NavigationPreloadManager interface: operation setHeaderValue(ByteString)

      Test timed out
      

    • TIMEOUT [expected PASS] subtest: NavigationPreloadManager interface: operation getState()

      Test timed out
      

  • OK /webaudio/the-audio-api/the-audiobuffersourcenode-interface/sub-sample-buffer-stitching.html (#22849)
    • FAIL [expected PASS] subtest: X Stitched sine-wave buffers at sample rate 43800 does not equal [0,0.06264832615852356,0.12505052983760834,0.18696144223213196,0.24813786149024963,0.308339387178421,0.36732959747314453,0.4248766601085663,0.480754554271698,0.5347436666488647,0.5866320133209229,0.6362156271934509,0.6832997798919678,0.7276994585990906,0.7692402601242065,0.8077589869499207...] with an element-wise tolerance of {"absoluteThreshold":0.0038986,"relativeThreshold":0}. Index Actual Expected AbsError RelError Test threshold [14680] -2.5707264081920000e+12 2.0512369275093079e-1 2.5707264081922051e+12 1.2532566929329230e+13 3.8985999999999999e-3 [14681] 1.1480505578219891e-2 1.4340442419052124e-1 1.3192391861230135e-1 9.1994315626575540e-1 3.8985999999999999e-3 Max AbsError of 2.5707264081922051e+12 at index of 14680. Max RelError of 1.2532566929329230e+13 at index of 14680.

      assert_true: expected true got false
      

    • FAIL [expected PASS] subtest: X SNR (-204.7670312345937 dB) is not greater than or equal to 65.737. Got -204.7670312345937.

      assert_true: expected true got false
      

  • OK [expected ERROR] /workers/constructors/Worker/Worker-constructor.html (#22991)

@github-actions
Copy link

✨ Try run (#14419634449) succeeded.

@jdm
Copy link
Member

jdm commented Apr 12, 2025

Can you explain the source of the deadlock? I'm having trouble following.

@mrobinson
Copy link
Member Author

Here's what I think is happening, and I believe that there are three threads involved:

Thread 1 (Thread 0x7ffff3fc3cc0 (LWP 1913691) "servo"):
#0  syscall () at ../sysdeps/unix/sysv/linux/x86_64/syscall.S:38
#1  0x000055555a081466 in std::thread::park ()
#2  0x0000555558f29612 in crossbeam_channel::flavors::array::Channel<T>::recv::{{closure}} ()
#3  0x0000555558f27f74 in crossbeam_channel::flavors::array::Channel<T>::recv ()
#4  0x0000555558fad312 in crossbeam_channel::channel::Receiver<T>::recv ()
#5  0x000055555903eb2e in webrender::render_api::RenderApi::hit_test ()
#6  0x00005555588753fe in compositing::compositor::ServoRenderer::hit_test_at_point ()
#7  0x0000555558878b09 in compositing::compositor::IOCompositor::handle_browser_message ()
#8  0x000055555887fef1 in compositing::compositor::IOCompositor::receive_messages ()
#9  0x000055555605457a in servo::Servo::spin_event_loop ()
#10 0x0000555555bf36a0 in servoshell::desktop::app_state::RunningAppState::pump_event_loop ()
#11 0x0000555555c2d048 in servoshell::desktop::app::App::handle_events_with_winit ()
#12 0x0000555555c2e83c in <servoshell::desktop::app::App as winit::application::ApplicationHandler<servoshell::desktop::events_loop::WakerEvent>>::user_event ()
#13 0x0000555555c92046 in winit::platform_impl::linux::wayland::event_loop::EventLoop<T>::pump_events ()
#14 0x0000555555c95f8b in winit::platform_impl::linux::wayland::event_loop::EventLoop<T>::run_on_demand ()
#15 0x0000555555c99999 in servoshell::desktop::events_loop::EventsLoop::run_app ()
#16 0x0000555555c6e00b in servoshell::desktop::cli::main ()
#17 0x0000555555be04f3 in std::sys::backtrace::__rust_begin_short_backtrace ()
#18 0x0000555555be04e9 in std::rt::lang_start::{{closure}} ()
#19 0x000055555a080547 in std::rt::lang_start_internal ()
#20 0x0000555555be0545 in main ()

Thread 23 (Thread 0x7fffcbfff6c0 (LWP 1913726) "WRRenderBackend"):
#0  0x00007ffff6f2c03b in __libc_sendmsg (flags=0, msg=0x7fffcbff3890, fd=24) at ../sysdeps/unix/sysv/linux/sendmsg.c:28
#1  __libc_sendmsg (fd=24, msg=0x7fffcbff3890, flags=0) at ../sysdeps/unix/sysv/linux/sendmsg.c:25
#2  0x0000555559fd2dab in ipc_channel::platform::unix::OsIpcSender::send::send_first_fragment ()
#3  0x0000555559fd28c9 in ipc_channel::platform::unix::OsIpcSender::send ()
#4  0x00005555595e561a in ipc_channel::ipc::IpcSender<T>::send ()
#5  0x00005555595d9910 in compositing_traits::CompositorProxy::send ()
#6  0x000055555605057d in <servo::RenderNotifier as webrender_api::RenderNotifier>::new_frame_ready ()
#7  0x0000555558f7c6b7 in webrender::render_backend::RenderBackend::update_document ()
#8  0x0000555558f7a182 in webrender::render_backend::RenderBackend::process_transaction ()
#9  0x0000555558f7245a in webrender::render_backend::RenderBackend::run ()
#10 0x0000555558f4e5f8 in std::sys::backtrace::__rust_begin_short_backtrace ()
#11 0x0000555559076cb6 in core::ops::function::FnOnce::call_once{{vtable.shim}} ()
#12 0x000055555a0976cb in std::sys::pal::unix::thread::Thread::new::thread_start ()
#13 0x00007ffff6e9caa4 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:447
#14 0x00007ffff6f29c3c in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78

Thread 46 (Thread 0x7fffa67ff6c0 (LWP 1913749) "Script(1,1)"):
#0  0x00007ffff6f2c03b in __libc_sendmsg (flags=0, msg=0x7fffa67f9770, fd=24) at ../sysdeps/unix/sysv/linux/sendmsg.c:28
#1  __libc_sendmsg (fd=24, msg=0x7fffa67f9770, flags=0) at ../sysdeps/unix/sysv/linux/sendmsg.c:25
#2  0x0000555559fd2dab in ipc_channel::platform::unix::OsIpcSender::send::send_first_fragment ()
#3  0x0000555559fd28c9 in ipc_channel::platform::unix::OsIpcSender::send ()
#4  0x00005555595e561a in ipc_channel::ipc::IpcSender<T>::send ()
#5  0x00005555595d9e9e in compositing_traits::CrossProcessCompositorApi::send_display_list ()
#6  0x000055555640cc33 in layout_thread_2020::LayoutThread::handle_reflow ()
#7  0x0000555556424ec4 in profile_traits::time::profile ()
#8  0x000055555640a0b2 in <layout_thread_2020::LayoutThread as script_layout_interface::Layout>::reflow ()
#9  0x0000555556802c5a in script::dom::window::Window::reflow ()
#10 0x0000555557161b8c in script::script_thread::ScriptThread::update_the_rendering ()
#11 0x0000555557166c06 in script::script_thread::ScriptThread::handle_msgs ()
#12 0x0000555557160e18 in script::script_thread::ScriptThread::start ()
#13 0x000055555650a7a0 in profile_traits::mem::ProfilerChan::run_with_memory_reporting ()
#14 0x00005555570c07fb in std::sys::backtrace::__rust_begin_short_backtrace ()
#15 0x00005555570c813a in core::ops::function::FnOnce::call_once{{vtable.shim}} ()
#16 0x000055555a0976cb in std::sys::pal::unix::thread::Thread::new::thread_start ()
#17 0x00007ffff6e9caa4 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:447
#18 0x00007ffff6f29c3c in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78
  1. The Compositor synchronously asks WebRender for a hit test, WebRender asks the WRRenderBackend thread to complete the hit test.
  2. The WRRenderBackend thread is busy telling the Compositor about a new frame, but is blocking on sending the IPC message to the Compositor because the OS socket buffer is full.
  3. The OS socket buffer is full, because Script(1, 1) has filled it up with a giant CompositorDisplayListInfo data structure (which is particularly big because of the large page from the failing test from compositor: Unify the cross process and in-process API #36443). Script(1, 1) is also blocked because the Compositor cannot consume any bytes from the OS socket buffer as it is waiting on the hit test from number 1.

I think the main issue here is that CompositorDisplayListInfo is just too chonky to be serialized and sent over the Compositor's main IPC channel. Probably all these display list bits should be sent via shared memory as they are so large, but for now this PR is the workaround.

@mrobinson
Copy link
Member Author

Apologies for not including the details earlier. Let me know if you need more information. I'm happy to keep digging if something is missing!

@mrobinson
Copy link
Member Author

Ah, I forgot to mention that this is an issue because before, I believe that the router thread was buffering and blocking before, rather than the scene builder thread. #36443 removes the router thread from the mix and removes the extra buffering and copying.

@jdm
Copy link
Member

jdm commented Apr 12, 2025

Oof!

@mrobinson mrobinson added this pull request to the merge queue Apr 12, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Apr 12, 2025
@mrobinson mrobinson added this pull request to the merge queue Apr 12, 2025
Merged via the queue into servo:main with commit 5f0f457 Apr 12, 2025
53 checks passed
@mrobinson mrobinson deleted the display-list-info-side-channel branch April 12, 2025 20:36
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.

2 participants