[wire] Fix some other lock-inversions with client Buffers.

- This fixes two more lock-inversion cases that weren't
  caught in:
  https://dawn-review.git.corp.google.com/c/dawn/+/321995.
  Specifically:
  1) One lock inversion was a result of calling MapAsyncEvent's
     ReadyHook while also holding the EventManager's mTrackedEvents
     lock. The inversion happens when a user's MapAsync callback
     calls MapAsync inside itself which, while holding the Buffer
     lock, now tries to acquire mTrackedEvent's lock. This change
     ensures that ReadyHook is called while we are not holding the
     mTrackedEvent's lock so that those two locks are always
     acquired with the Buffer lock first.
  2) Another lock inversion happens in our end2end tests because
     we synchronously mock the wire with the TerribleCommandBuffer
     in those tests. This case shouldn't cause an issue in
     production because it is a result of the TerribleCommandBuffer
     blocking synchronously and calling Flush as a part of
     GetCmdSpace. In Chromium, the Flush wouldn't be blocking since
     it would be an IPC back to the server, but in our tests, it
     happens while holding any locks on the client side,
     specifically, this inversion can happen when:
     Let M0 be the buffer->mState lock,
         M1 be the server-wide lock from server->GetGuard()
         M2 be a native lock, in this case the call_once in
	    native::Buffer::MapAsyncBufferEvent::Complete.
     The inversion proposed by TSAN assumes the following happens:
     - Thread 1 calls something like Client::Buffer::Unmap which
       takes M0, then flushes to the server trying to take M1.
     - Thread 2 calls a server-side callback handler, i.e.
       OnBufferMapAsync which starts with M1 taken, then in the
       native code tries to takes M2.
     - Thread 3 calls native::MapAsyncEvent::Complete which takes
       M2, then triggers server->client response which calls the
       client::Buffer::MapAsyncEvent::ReadyHook which tries to
       take M0.
     With those three things happening, then we could have a
     deadlock. To address this, we made sure that the
     client->SerializeCommand calls are called without holding
     buffer->mState lock. This also required making the
     memoryHandle a shared_ptr for now so that we could
     properly serialize the memoryHandle data while being sure
     that the handle was still valid.

Bug: 529413629
Change-Id: I561190c76bd26607193e9f847e5cb89744a0a3c4
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/323497
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Commit-Queue: Loko Kung <lokokung@google.com>
4 files changed
tree: 154813cc9b7ef4f7d972af47a3cd620bad4af6d5
  1. .github/
  2. .vscode/
  3. agents/
  4. build_overrides/
  5. docs/
  6. generator/
  7. include/
  8. infra/
  9. scripts/
  10. src/
  11. test/
  12. third_party/
  13. tools/
  14. webgpu-cts/
  15. .bazelrc
  16. .bazelversion
  17. .clang-format
  18. .clang-format-ignore
  19. .clang-tidy
  20. .git-blame-ignore-revs
  21. .gitattributes
  22. .gitignore
  23. .gitmodules
  24. .gn
  25. .style.yapf
  26. .vpython3
  27. AUTHORS
  28. BUILD.bazel
  29. BUILD.gn
  30. CMakeLists.txt
  31. CMakeSettings.json
  32. CODE_OF_CONDUCT.md
  33. codereview.settings
  34. CONTRIBUTING.md
  35. CPPLINT.cfg
  36. DEPS
  37. DIR_METADATA
  38. go.mod
  39. go.sum
  40. go_presubmit_support.py
  41. LICENSE
  42. MODULE.bazel
  43. MODULE.bazel.lock
  44. OWNERS
  45. PRESUBMIT.py
  46. PRESUBMIT_test.py
  47. README.chromium
  48. README.md
  49. unsafe_buffers_paths.txt
  50. WATCHLISTS
  51. WORKSPACE.bazel
README.md

Build Status Matrix Space

Dawn, a WebGPU implementation

Dawn is an open-source and cross-platform implementation of the WebGPU standard. More precisely it implements webgpu.h that is a one-to-one mapping with the WebGPU IDL. Dawn is meant to be integrated as part of a larger system and is the underlying implementation of WebGPU in Chromium.

Dawn provides several WebGPU building blocks:

  • WebGPU C/C++ headers that applications and other building blocks use.
    • The webgpu.h version that Dawn implements.
    • A C++ wrapper for the webgpu.h.
  • A “native” implementation of WebGPU using platforms' GPU APIs: D3D12, Metal, Vulkan and OpenGL. See per API support for more details.
  • A client-server implementation of WebGPU for applications that are in a sandbox without access to native drivers
  • Tint is a compiler for the WebGPU Shader Language (WGSL) that can be used in standalone to convert shaders from and to WGSL.

Helpful links:

Documentation table of content

Developer documentation:

User documentation: (TODO, figure out what overlaps with the webgpu.h docs)

License

BSD 3-Clause License, please see LICENSE.

Disclaimer

This is not an officially supported Google product.