Lock rank cleanup, part 2#9728
Conversation
|
The purpose of the changes in |
7b8fa83 to
f652ab7
Compare
|
@andyleiserson I just pushed some doc comments and a minor tweak to the code; could you see if those seem correct? |
|
This commit looks good:
|
andyleiserson
left a comment
There was a problem hiding this comment.
Added comments look good, I just noted a few typos and have minor additional clarifications. I will rebase & incorporate these later.
| /// 3) Call the `PendingSubmission`'s [`submit`] method, passing your mutex | ||
| /// guard on [`Queue::pending_writes`]. |
There was a problem hiding this comment.
I feel like I wrote this in a comment already, so it may exist somewhere else, but it might be worth noting here that the PendingWrites lock should be acquired at some point between (1) and (3) (generally, as late as is possible while supporting the necessary PendingWrites activity).
There was a problem hiding this comment.
The comment I was thinking of is the one on allocate_submission. The doc comments on PendingSubmission and allocate_submission have a fair amount of overlap, but they are presenting things from slightly different perspectives so I didn't try to consolidate them.
I did add a note here (on PendingSubmission) about the timing of acquiring the pending writes lock.
There was a problem hiding this comment.
Oh, right, I was thinking I would trim down the comments on allocate_submission, and refer the reader to PendingSubmission's comments for details. I think I forgot about that.
Improve internal documentation for: - `wgpu_core::device::queue::PendingSubmission` - `wgpu_core::device::Device::is_valid` and `check_is_valid` - `wgpu_core::device::Device::maintain` - `wgpu_hal::vulkan::Queue::submit`
7e83137 to
6082f31
Compare
6082f31 to
eccc1a0
Compare
| rank HUB_DEVICES "Hub::devices" followed by { | ||
| DEVICE_SNATCHABLE_LOCK, | ||
| } |
There was a problem hiding this comment.
I changed my approach in poll_all_devices_of_api (now InstanceDevices::poll_all_devices) a bit. When I originally worked on the lock ranks, there was one registry lock which had a bunch of special locking behavior, and I excluded it from the analysis. But in the current version, the HUB_* locks function like any other.
Previously, I had made poll_all_devices acquire HUB_OTHER, collect all devices, drop the lock, and then poll the collected devices. (Which means that if new devices were created concurrently with polling all devices, the new devices would not be considered.)
Now I've made a dedicated HUB_DEVICES rank, and kept the poll_all_devices code as it was originally: acquire the lock and hold it for the duration of polling.
To actually pass tests with lock validation, HUB_DEVICES needs to be declared as:
rank HUB_DEVICES "Hub::devices" followed by {
DEVICE_SNATCHABLE_LOCK,
QUEUE_PENDING_WRITES,
DEVICE_TRACKERS,
QUEUE_LIFE_TRACKER,
BUFFER_BIND_GROUPS,
DEVICE_TRACE,
TEXTURE_BIND_GROUPS,
TEXTURE_CLEAR_MODE,
TEXTURE_VIEWS,
DEVICE_DEFERRED_DESTROY,
DEVICE_LOST_CLOSURE,
}
This is a mouthful, I'd be happy to restore the "collect devices then unlock" approach if that seems preferable. I don't think it's much of a functional risk to wgpu, it's more of a functional (or confusion) risk to wgpu users to permit poll_all_devices to run concurrently with device creation and itself.
There was a problem hiding this comment.
I don't think keeping "followed by" lists short is very important; am I missing something? It seems to me that the overall ordering is what people will be thinking about.
There was a problem hiding this comment.
So I think having poll_all_devices hold a distinguished HUB_DEVICES for the duration of the polling is fine.
There was a problem hiding this comment.
I don't think keeping "followed by" lists short is very important; am I missing something?
My concern is about maintainability. There are a lot of details of behavior of other parts of wgpu captured in rank.rs. This probably wouldn't happen for you or me because we've worked on this code, but I can see a developer being frustrated upon making a change elsewhere in wgpu that seems reasonable, but throws a hard-to-understand error from the lock rank checker that they're not sure what to do with. How much that happens is a cost/risk to weigh against the structural deadlock prevention that the lock ranking can give us.
The general guidance we can offer to avoid the complexity is "don't acquire more than one lock at a time", which if we wanted to put in practice here, we could do by dropping HUB_DEVICE before acquiring the other locks.
That said, I wrote a comment here because it was a notable change from the earlier version of the PR, and to call out a consequence of choices made now that will show up later. I think the way it is now is fine.
Don't use `Option<Vec<_>>`, just use an empty `Vec`.
Progress towards #5937. Part 1 was in #9524.
This fixes some violations of the lock rank graph:
release_gpu_resourcesinitialize_texture_memorypoll_all_devices_of_apiPendingSubmissionandQueue::write_bufferTesting
No explicit testing in this PR, but at the tip of my branch, the lock validation build can pass our test suite, see #9479.
Squash or Rebase? Rebase
Checklist
wgpumay be affected behaviorally.CHANGELOG.mdentries for the user-facing effects of this change are present.