[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>
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.h version that Dawn implements.webgpu.h.Helpful links:
Developer documentation:
User documentation: (TODO, figure out what overlaps with the webgpu.h docs)
BSD 3-Clause License, please see LICENSE.
This is not an officially supported Google product.