-
Notifications
You must be signed in to change notification settings - Fork 193
Mitigation for MSL atomic bounds check. #1703
Conversation
Mostly untested attempt for #1643. This moves the bounds check outside of the atomic expression, but I'm unsure if it is correct to just immediately go to Also not sure about the |
Looks like the CI failure is because I added the atomic tests which aren't implemented for spv. I guess I can remove those before submission, or maybe make a separate group of msl tests. |
@jimblandy please review this |
@glalonde The PR title says "Mitigation", but are you aware of any cases where this doesn't address the problem? |
I'm not aware of situations it doesn't handle, but I wouldn't be surprised if they exist. For example, I'm not sure if there are more complicated access patterns than just array access or struct access ( in the tests) which might break. I just tried this locally as a more convoluted access:
And that looks like it would work... |
Yeah, I think as long as we do the same things that an ordinary load would
do, we should be fine. I'll finish the review in a few minutes.
…On Mon, Jan 31, 2022, 6:48 PM glalonde ***@***.***> wrote:
I'm not aware of situations it doesn't handle, but I wouldn't be surprised
if they exist.
For example, I'm not sure if there are more complicated access patterns
than just array access or struct access ( in the tests) which might break.
I just tried this locally as a more convoluted access:
struct AtomicArray {
a: array<atomic<u32>, 10>;
};
struct Globals {
...
e: array<AtomicArray, 10>;
};
fn fetch_add_atomic_array2(i: i32, j: i32) -> u32 {
return atomicAdd(&globals.e[i].a[j], 1u);
}
metal::uint fetch_add_atomic_array2_(
int i_14,
int j_2,
device Globals& globals,
constant _mslBufferSizes& _buffer_sizes
) {
metal::uint _e8 = metal::uint(j_2) < 10 && metal::uint(i_14) < 10 ? metal::atomic_fetch_add_explicit(&globals.e.inner[i_14].a.inner[j_2], 1u, metal::memory_order_relaxed) : DefaultConstructible();
return _e8;
}
And that looks like it would work...
—
Reply to this email directly, view it on GitHub
<#1703 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAFXNKCHOWISLCSNZ4IXVR3UY5CZBANCNFSM5M42YR2A>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like just the right approach. I have a few small comments, and a suggestion on how to fix the tests.
Thanks for the review, ptal |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great. I wrote the bounds-checking code for Metal, so I humbly thank you for catching my mistake. I have one last change to request, and then I'll merge it.
@@ -0,0 +1,21 @@ | |||
// Tests for `naga::back::BoundsCheckPolicy::ReadZeroSkipWrite`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might want to add:
// for atomic types. These are separate from `bounds-check-zero.wgsl because
// SPIR-V does not yet support `ReadZeroSkipWrite` for atomics. Once it does,
// the test files could be combined.
src/back/msl/writer.rs
Outdated
let put_unchecked_atomic_access = |writer: &mut Writer<W>| -> BackendResult { | ||
write!( | ||
writer.out, | ||
"{}::atomic_fetch_{}_explicit({}", | ||
NAMESPACE, key, ATOMIC_REFERENCE | ||
)?; | ||
writer.put_access_chain(expr_handle, policy, context)?; | ||
write!(writer.out, ", ")?; | ||
writer.put_expression(value, context, true)?; | ||
write!(writer.out, ", {}::memory_order_relaxed)", NAMESPACE)?; | ||
Ok(()) | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I noticed the duplicated code as well. Naga's style is to not use closures in this way, to keep control flow simple. This is certainly subjective, but it's what we've settled on.
Instead, please declare a bool
, and then have two if
statements on either side of the common code.
I sorted out the style points - this is a good fix and I want to get it in right away. Thank you very much! |
awesome, thanks! looking forward to the next release : ) |
[msl-out] Correct output for bounds-checked atomic accesses.
Generalize put_atomic_fetch to handle `exchange` as well, rather than special-cased code which didn't do the bounds check (the check handling as fixed in gfx-rs#1703 but only for the fetch cases, exchange was skipped). Fixes gfx-rs#1848
* Fix incorrect atomic bounds check on metal back-end Generalize put_atomic_fetch to handle `exchange` as well, rather than special-cased code which didn't do the bounds check (the check handling as fixed in #1703 but only for the fetch cases, exchange was skipped). Fixes #1848 * Add tests for atomic exchange
Will CI trigger automatically?