Add Gecko Profiler support for RISCV64 and LoongArch64
Categories
(Core :: Gecko Profiler, task, P3)
Tracking
()
| Tracking | Status | |
|---|---|---|
| firefox160 | --- | fixed |
People
(Reporter: csmantle, Assigned: csmantle)
References
Details
(Whiteboard: [fp])
Attachments
(10 files, 7 obsolete files)
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
154.91 KB,
image/jpeg
|
Details | |
|
107.15 KB,
image/jpeg
|
Details | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
326.97 KB,
image/png
|
Details | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
Details | Review |
Starting from Bug 1403421, we've already enjoyed Gecko Profiler support on MIPS64. This bug tracks my efforts to implement the same for RV64 and LA64, two Tier-3 platforms. These architectures are gaining adoption recently, and having a working in-browser profiler for them would greatly boost user experience.
| Assignee | ||
Updated•7 months ago
|
| Assignee | ||
Comment 1•7 months ago
|
||
| Assignee | ||
Comment 2•7 months ago
|
||
| Assignee | ||
Comment 3•7 months ago
•
|
||
Part 1 and Part 2 are tested by kf <kf@aosc.io> on Loongson XA61200 (3A6000) by capturing a trace using F12 - Performance on a Speedometer Main run, after working around Bug 2023180.
Captured profile: https://share.firefox.dev/4sEvD2J
| Assignee | ||
Comment 4•7 months ago
|
||
| Assignee | ||
Comment 5•7 months ago
|
||
Comment on attachment 9552985 [details]
LoongArch64 demo screenshot 1
Courtesy of kf <kf@aosc.io>.
| Assignee | ||
Comment 6•7 months ago
|
||
Courtesy of kf <kf@aosc.io>.
| Assignee | ||
Comment 7•7 months ago
|
||
| Assignee | ||
Comment 8•7 months ago
|
||
Updated•7 months ago
|
Updated•7 months ago
|
| Assignee | ||
Comment 9•7 months ago
|
||
| Assignee | ||
Comment 10•7 months ago
|
||
Taken by myself on Milk-V Jupiter (SpacemiT M1).
Profile: https://share.firefox.dev/40AJ73P
Updated•7 months ago
|
Updated•7 months ago
|
Updated•7 months ago
|
Updated•7 months ago
|
Updated•7 months ago
|
| Assignee | ||
Comment 11•6 months ago
|
||
t0on RV and$t0on LA are used by glibc.a1on RV and$a1on LA are used by libffi.
Link:
https://elixir.bootlin.com/glibc/glibc-2.43/source/sysdeps/unix/sysv/linux/loongarch/setcontext.S#L49
Link:
https://elixir.bootlin.com/glibc/glibc-2.43/source/sysdeps/unix/sysv/linux/riscv/setcontext.S#L46
Link:
https://github.com/libffi/libffi/blob/10056e7e6a0d40d2a21af63484b99f08898dde9e/src/loongarch64/sysv.S#L92
Link:
https://github.com/libffi/libffi/blob/10056e7e6a0d40d2a21af63484b99f08898dde9e/src/riscv/sysv.S#L90
| Assignee | ||
Comment 12•6 months ago
|
||
| Assignee | ||
Comment 13•6 months ago
|
||
This change is learned from Breakpad.
| Assignee | ||
Comment 14•6 months ago
|
||
It seems that this stack has become too large. I'll split it into other bugs that allow fine-grained review.
Comment 15•6 months ago
|
||
Comment on attachment 9570956 [details]
Bug 2023167 - Part 8: Accept def_cfa_register as the first CFI opcode. r=#profiler-reviewers!
Revision D294884 was moved to bug 2033272. Setting attachment 9570956 [details] to obsolete.
Comment 16•6 months ago
|
||
Comment on attachment 9552683 [details]
Bug 2023167 - Part 1: Move field initializers of {Base}Profiler's Registers class to declaration. r=#profiler-reviewers!
Revision D287578 was moved to bug 2033273. Setting attachment 9552683 [details] to obsolete.
Comment 17•6 months ago
|
||
Comment on attachment 9552992 [details]
Bug 2023167 - Part 4: (Drive-by) Fix typo: "rEDZONE" -> "REDZONE". r=#profiler-reviewers!
Revision D287781 was moved to bug 2033273. Setting attachment 9552992 [details] to obsolete.
Comment 18•6 months ago
|
||
Comment on attachment 9553655 [details]
Bug 2023167 - Part 5: (Drive-by) Lower constant MOZ_ASSERTs to static_asserts. r=#profiler-reviewers!
Revision D288164 was moved to bug 2033273. Setting attachment 9553655 [details] to obsolete.
Updated•6 months ago
|
Updated•6 months ago
|
Updated•6 months ago
|
Updated•6 months ago
|
Comment 19•6 months ago
|
||
Hi :csmantle!
We couldn't review your patches yet, sorry! I have a few questions before I get into the reviewing the important parts of the code changes:
- Are all of the patches ready for review? Does the native stack walking as well as the rest of the profiler work in RISCV64 and LoongArch64?
- How can we test these changes locally? As I'm not really familiar with the architecture, I kind of feel like I'm in the dark while reviewing the patches. It would be great if you can provide a manual testing STR. Since we don't have machines for these platforms, it's pretty difficult to gauge. For example, I assume I can download QEMU and then install a linux distro that distributes RISCV64 and LoongArch64 binaries. And then I can try to compile it to see if it works locally. Could you provide us more concrete testing steps?
| Assignee | ||
Comment 20•6 months ago
•
|
||
Hi :canova,
(In reply to Nazım Can Altınova [:canova][:canaltinova on phabricator] from comment #19)
- Are all of the patches ready for review? Does the native stack walking as well as the rest of the profiler work in RISCV64 and LoongArch64?
The current state is that the code compiles, can capture and upload profiles, and the basic browsing works. I'm still debugging the missing frames (as mentioned in the Matrix thread), and it seems that symbol files for these archs are lacking.
The primary goal of this bug is to make Gecko Profiler at least as usable as on MIPS64 (tier-3, same as RISC-V and LoongArch), where it already has some support.
- How can we test these changes locally?
For example, I assume I can download QEMU and then install a linux distro that distributes RISCV64 and LoongArch64 binaries. And then I can try to compile it to see if it works locally.
This is plausible but would be very slow. I'll ask my friends at Anthon OS Community to see if they could help. They have significant support efforts into and user groups of these archs. I actually have a version of Fx with this stack landed [^0] there, and the profiles posted in the comments above were collected on that version.
Could you provide us more concrete testing steps?
Honestly my current testing steps are quite casual:
- Go to https://browserben.ch/speedometer/v3.1/.
- Launch the profiler, start capturing with "Firefox" preset.
- Start Speedometer, and let it run for a couple of seconds.
- Stop the capture and observe.
So I'd be delighted to know a more systematic approach :)
Comment 21•6 months ago
|
||
(In reply to Nazım Can Altınova [:canova][:canaltinova on phabricator] from comment #19)
Hi :csmantle!
We couldn't review your patches yet, sorry! I have a few questions before I get into the reviewing the important parts of the code changes:
- Are all of the patches ready for review? Does the native stack walking as well as the rest of the profiler work in RISCV64 and LoongArch64?
- How can we test these changes locally? As I'm not really familiar with the architecture, I kind of feel like I'm in the dark while reviewing the patches. It would be great if you can provide a manual testing STR. Since we don't have machines for these platforms, it's pretty difficult to gauge. For example, I assume I can download QEMU and then install a linux distro that distributes RISCV64 and LoongArch64 binaries. And then I can try to compile it to see if it works locally. Could you provide us more concrete testing steps?
Hi Nazım,
Rong notified me about your question about potential hardware access. While I can't help with RISC-V, I could potentially help you connect with SSH access or a physical device (depending on where you are located). Happy to help if you can email me via the contact below:
Comment 22•5 months ago
|
||
(In reply to Rong Bao [:csmantle] from comment #20)
Honestly my current testing steps are quite casual:
- Go to https://browserben.ch/speedometer/v3.1/.
- Launch the profiler, start capturing with "Firefox" preset.
- Start Speedometer, and let it run for a couple of seconds.
- Stop the capture and observe.
So I'd be delighted to know a more systematic approach :)
That sounds good. Another thing worth checking is to run all the profiler tests in these archs to see they all pass. For example, our tests mostly live in tools/profiler/tests and devtools/client/performance-new/test. So running the tests in these directories will most likely show you if there is something broken. We have some native stack collection tests there as well, but they don't check exactly if "all" of the frames look correct. Still it's something worth checking.
(In reply to jeffbai from comment #21)
Hi Nazım,
Rong notified me about your question about potential hardware access. While I can't help with RISC-V, I could potentially help you connect with SSH access or a physical device (depending on where you are located). Happy to help if you can email me via the contact below:
Hi, thanks for the offer! It would be great to have an SSH access for me to check at least. Just reached out to you via email.
| Assignee | ||
Comment 23•5 months ago
|
||
- WasmTailCallFPScratchReg:
t3on RV and$t3on LA. - WasmTailCallRAScratchReg:
raon RV and$raon LA.
Updated•5 months ago
|
Updated•5 months ago
|
| Assignee | ||
Comment 24•5 months ago
|
||
(In reply to Nazım Can Altınova [:canova][:canaltinova on phabricator] from comment #22)
(In reply to Rong Bao [:csmantle] from comment #20)
Another thing worth checking is to run all the profiler tests in these archs to see they all pass. For example, our tests mostly live intools/profiler/testsanddevtools/client/performance-new/test. So running the tests in these directories will most likely show you if there is something broken.
These tests are super helpful!
I think we're almost there now. I ironed out some glitches in frame chasing code. And it seems that both LoongArch and RISC-V have stacks larger than 160KB [^0], which is probably why the libc frames are not captured.
I'll update the diffs once more testing is done, but here's a profile for LA64 I captured yesterday: https://share.firefox.dev/4cUc8gj. Once done, I'll re-request review for the updated diffs.
CC-ing Markus here :)
Updated•5 months ago
|
Updated•5 months ago
|
| Assignee | ||
Comment 25•5 months ago
|
||
This adds support for undefining calculation rule for a given (address,
reg) pair.
| Assignee | ||
Comment 26•5 months ago
|
||
The stack size needed on these platforms are much larger than that on
x64, so allocating more space for it.
| Assignee | ||
Comment 27•5 months ago
|
||
The purpose of this patch is to work around huge frames on these
platforms. Clang has little support for -fstack-clash-protection on
LoongArch, while on RV64 this flag is not enabled in build config by
default.
For async sampling, we store the UniquePtr to a heap-allocated
lul::StackImage in SamplerThread, and pass the pointer around when doing
LUL backtraces.
For sync sampling, we allocate space for lul::StackImage in the thread
local storage, and pass the pointer into LUL backtracer.
This patch is organized so that only {loongarch64,riscv64}-linux are
affected, while other architectures should not be impacted.
| Assignee | ||
Comment 28•5 months ago
|
||
This profile is captured with this new stack applied on LoongArch64: https://share.firefox.dev/4cJXSYR
| Assignee | ||
Comment 29•5 months ago
|
||
(In reply to Rong Bao [:csmantle] from comment #27)
Created attachment 9575795 [details]
Bug 2023167 - Part 8: Move lul::StackImage out of stack on {loongarch64,riscv64}-linux. r=#profiler-reviewers!The purpose of this patch is to work around huge frames on these
platforms. Clang has little support for-fstack-clash-protectionon
LoongArch, while on RV64 this flag is not enabled in build config by
default. [...]
I filed https://github.com/llvm/llvm-project/pull/195595 for LLVM, but I guess this workaround would have to stay for a while...
Updated•5 months ago
|
Updated•5 months ago
|
| Assignee | ||
Comment 30•4 months ago
|
||
FYI: https://github.com/llvm/llvm-project/pull/195595 has been merged for Clang 23.
| Assignee | ||
Comment 31•3 months ago
|
||
Gentle ping.
| Assignee | ||
Comment 32•3 months ago
|
||
This moves the saved $fp to $fp+0 and saved $ra to $fp+8, which looks
the same as the JS ABI frame layout. This can aid LUL frame chasing that
has just walked the JS frames. The risk should be minimal since
EnterJITRegs's layout should be opaque to deeper frames after all.
| Assignee | ||
Comment 33•3 months ago
|
||
Ditto for riscv64; see Part 1.
Updated•3 months ago
|
Updated•3 months ago
|
Updated•3 months ago
|
Updated•3 months ago
|
Updated•3 months ago
|
Updated•3 months ago
|
Updated•3 months ago
|
Updated•3 months ago
|
| Assignee | ||
Comment 34•3 months ago
|
||
Profile https://share.firefox.dev/4vIssbx is captured with a build containing the latest stack. I think the majority of stacks are reasonable (apart from missing symbols), both JS and native ones.
| Assignee | ||
Comment 35•1 month ago
|
||
Good news! LLVM 23.1.0 is now released. This version contains my implementation of -fstack-clash-protection on LoongArch and my fix for this feature on RISC-V.
This means that, with an up-to-date toolchain, the Part 9 workaround would no longer be required.
I would do more testing on these platforms and drop Part 9 once confirmed.
| Assignee | ||
Comment 36•1 month ago
|
||
So, after some experimentation:
-
The increase in stack snapshot size in Part 8 has no observable effect on the Speedometer 3.1 profile.
- Without Part 8 (160 KiB): https://share.firefox.dev/3Sz4HFe
- With Part 8 (256 KiB): https://share.firefox.dev/4zHoHpT
Both profiles show a similar stack shape with no missing frames.
- The originally observed SIGSEGV on loongarch64 and riscv64 was caused by overflowing the 256 KiB per-thread stack size limit [^0]. So, while SCP helps, since sampling happens on a non-main thread, it couldn't prevent the crash.
In fact, for Speedometer 3.1, abandoning both Part 8 and 9 can also produce a successful and complete capture: https://share.firefox.dev/4qHJ56b
Updated•1 month ago
|
Updated•1 month ago
|
| Assignee | ||
Comment 37•1 month ago
|
||
(In reply to Rong Bao [:csmantle] from comment #36)
Both profiles show a similar stack shape with no missing frames.
Oh, it seems that I missed something near the bottom of the samples display.
There is a tiny number of samples that have truncated frames:
- 1 with Part 8 reverted and Part 9 present.
- 5 with both Part 8 and Part 9 reverted.
All of these have this stack shape:
[...]
Run [/home/csmantle/workspace/mozilla-firefox-dev/obj-full/ipc/chromium/./../../../ipc/chromium/src/base/message_loop.cc]
XRE_InitChildProcess [/home/csmantle/workspace/mozilla-firefox-dev/toolkit/xre/nsEmbedFunctions.cpp]
XRE_InitChildProcess
main [/home/csmantle/workspace/mozilla-firefox-dev/browser/app/nsBrowserApp.cpp]
(root)
So I guess snapshot size does play some part here, but not very significantly.
As shown by (currently abandoned) Part 9, accommodating this would require working around the per-thread stack size limit, and thus introduce extra complexity and overhead.
Markus, would you like to share some thoughts? I'm curious about why this isn't biting on Tier-1 platforms like x64. And just like you mentioned in [^0], if stack truncation could really happen on such platforms, it would be better to improve Part 9 to be used on all platforms with less per-thread memory overhead.
| Assignee | ||
Comment 38•11 days ago
|
||
Thanks for your review comments! I've replied in Phabricator.
Comment 39•11 days ago
|
||
Comment 40•10 days ago
|
||
| bugherder | ||
https://hg.mozilla.org/mozilla-central/rev/cd275d1d76a2
https://hg.mozilla.org/mozilla-central/rev/9cdf0d732b31
https://hg.mozilla.org/mozilla-central/rev/9078e0704d50
https://hg.mozilla.org/mozilla-central/rev/42b7f67542d2
https://hg.mozilla.org/mozilla-central/rev/144527eaa51b
https://hg.mozilla.org/mozilla-central/rev/6c2cca3ee59e
https://hg.mozilla.org/mozilla-central/rev/79c0376ef206
Description
•