-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ThreadSanitizer support for Risc-V #12907
Conversation
Note: what the |
This only shows that the overhead of TSan (at least on this platform) is quite high. |
I would propose adding a If you look for |
Sure, done. |
I forgot to mention that these changes are very similar to the arm64 PR merged some time ago - the logic is completely similar, and so are the minor platform-specific tweaks required. |
I wonder who would be interested in reviewing this. @nojb is the original author of the riscv backend, are there other riscv enthusiasts out there? |
Unfortunately, I know nothing about TSan. If there is a specification or some documentation of what TSam instrumentation is supposed to do, I can take a look, but without any guide it would probably be futile for me to do so :) |
I think we could ask the TSan band (@fabbing and @OlivierNicole) to look at the TSan aspects, and have someone familiar with riscv review the code for readability, consistency of style with the rest of the backend, and verify (should be easy) that this does not change behavior when TSan is not enabled. |
There is some information in |
Makes sense, I'll do the riscv part.
Thanks for the pointers. |
Naive question: do you know when RISC-V will be officially supported by ThreadSanitizer? It’s not yet listed on the LLVM documentation page. |
The documentation is out-of-date, as usual! If you follow the link to the wiki at the end of that page, the "supported platforms" section - which is also out-of-date - points to the latest version of Gcc has enabled support for riscv64 early this year and for s390x 2.5 years ago. |
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.
LGTM
Nit: one could use the existing macros C_ARG_{1,2,3,4}
instead of a0,a1,a2,a3
when calling C functions, but this would only make sense if the same change is made to the arm64
backend in order to maintain symmetry.
As I mentioned in the arm64 PR, these |
327a588
to
f9536c3
Compare
Makes sense, thanks. |
(added to 5.2 milestone for discussion later) |
This looks ready to merge in my opinion. @OlivierNicole: are you intending to take a look? Otherwise I think we can move to merge. |
I believe @fabbing is having a look? |
Yes, I am! |
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.
Apart from the few suggested changes, it looks good to me. Note that I'm new to RISC-V assembly, so I may have missed some things...
I like the addition of the TSAN_C_CALL
macro, we could probably improve amd64.S
with that idea!
I also suggest updating the comment in configure.ac
:
diff --git a/configure.ac b/configure.ac
index 741553a06d..f442a2de60 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1663,8 +1663,8 @@ AS_IF([test "x$enable_instrumented_runtime" != "xno" ],
)]
)
-# ThreadSanitizer support is only for Linux/FreeBSD/macOS on amd64, as well as
-# Linux/macOS on arm64.
+# ThreadSanitizer supported for Linux/FreeBSD/macOS on amd64, Linux/macOS on
+# arm64, and Linux on RISC-V.
# ThreadSanitizer supports more architectures but the OCaml client side is not
# implemented (yet).
AS_IF([test "x$enable_tsan" = "xyes" ],
or fa0:fa1. */ | ||
addi sp, sp, -32 | ||
CFI_ADJUST(32) | ||
sd a0, 0(sp) |
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.
Why save only a0
(and not a1
), but both fa0
and fa1
?
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.
caml_c_call
wraps any kind of C function, and needs to preserve the returned value during the TSan instrumentation.
On RiscV, the ABI requires that integer values are returned into a0
, or a0:a1
if the return value does not fit in one register, and that floating-point values are similarly returned in fa0
or fa0:fa1
.
On 64-bit RiscV, until C grows a 128-bit integer type, all integer types will fit in a single register, so we only need to save a0
. However, a long double
return type would span both fa0
and fa1
, so we save them both.
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.
I was checking with @OlivierNicole our choice not to save xmm1
in amd64.S
: the reasoning was that the compatible returned type of the C function called by OCaml would be only be float
(double
in C) or int32
/int64
/nativeint
(all fitting in 64bits register), so we don't bother saving rdx
and xmm1
. See the table in https://v2.ocaml.org/manual/intfc.html#s:C-cheaper-call for reference.
Do you agree with this, and if so, pehaps we shouldn't save fa1
either to be consistent with amd64.S
.
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.
Given that limited list of supported types, I agree that only one floating-point register needs to be saved here. Since the arm64 code is already in and saves two, I intend to clean this in a later PR once all TSan support PRs are in (since all of them save two floating-point registers here), if that's ok with you.
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.
I'm not sure if it will make a big difference in terms of performance, but I'm glad we agree on this: at least it's not a bug in amd64.S
!
And yes, it's perfectly fine to do this in another PR.
It takes more than 14 minutes to run with tsan on riscv64.
f9536c3
to
bc12d52
Compare
Rebased, updated |
@fabbing can you give a formal approval if you are happy with the current state of the PR? We can then move to merge it. Thanks! |
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.
Apart from the discussion about possibly avoiding saving a register in caml_c_call
, which shouldn't affect correctness (and could could be part of another PR if deemed useful) this looks fine to me.
* Implement Ireturn_addr, needed by TSan instrumentation * TSan riscv bits for runtime * Allow for TSan to be enabled on Linux/riscv64 * Mark this test no-tsan. It takes more than 14 minutes to run with tsan on riscv64. * Document changes (cherry picked from commit 993a7e8)
Cherry-picked to 5.2: dc41ba9 |
This adds TSan support for Linux/riscv64.
Risc-V support in TSan is quite recent - in order to use it, you need to build gcc from sources after 20231218, when TSan support was enabled on this platform.
Support is also enabled for clang in the hope than clang will eventually be able to produce a working OCaml compiler on this platform (this is currently not the case, regardless of whether TSan is enabled or not).
All tests pass but
tests/regression/pr9853/compaction_corner_case.ml
which times out (running the binary manually, it takes a bit more than 14 minutes to complete successfully).