RFR: 8310656: RISC-V: __builtin___clear_cache can fail silently.
Robbin Ehn
rehn at openjdk.org
Wed Jun 28 08:17:07 UTC 2023
On Wed, 28 Jun 2023 05:33:11 GMT, Thomas Stuefe <stuefe at openjdk.org> wrote:
> Got curious. Looks good.
>
> I was not even aware that __builtin___clear_cache had an errno. Is this documented somewhere? We should probably check arm64 too.
>
> Question, would cacheflush(2) have worked too? Instead of the syscall?
Hi Thomas, thanks for looking, and thanks for being curios!
And sorry in advanced for this long answer, I felt that I needed to add some context.
Cross modifying code/CMODX is not specified on RV.
RV allows both coherent and non-coherent I/D cache.
Right now we have to assume non-coherent I/D cache (I have suggest hwprobe should return this).
But there is two pieces we can use, ifence and full IPI shootdown.
ifence is a local hart instruction read fence.
With non-coherent I/D cache ifence is not sufficient.
And ifence is an extension, not on all RV cpus.
Kernel 4.15 got the syscall riscv_flush_icache added with the IPI shootdown.
There is also a hart local version SYS_RISCV_FLUSH_ICACHE_LOCAL, which can be used instead of ifence.
If we ignore the case of having an UP (as you know we removed UP from the VM),
to make sure all threads/harts have a fresh I-cache our only option, at the moment,
is to emit that syscall => IPI.
There is still some cases in the VM I believe is not entirely correct.
The IPI is very expensive and system-wide intrusive, so if we are running on
I/D cache coherent system we should be able to utilize the ifence instruction and avoid (some?) IPI's.
Regarding the cacheflush wrapper it does not seem to implemented and if I tested it I get undef ref when linking. I only see the syscall in that header.
It looks like glibc/gcc don't consider failing syscalls, maybe this was uncommon, but now when everyone is running in different containers it's certainly more common. E.g. cacheflush do not list EPERM as a return value.
Note that there is a vdso wrapper for this syscall, which just do the ecall (syscall instruction), so I fail to see the point in trying to use that. And since we are doing an a full system IPI the speed of the syscall is not essential.
So I feel more comfortable with the VM explicit emitting this syscall, so everyone can see exactly what we are doing.
> src/hotspot/os_cpu/linux_riscv/riscv_flush_icache.cpp line 44:
>
>> 42:
>> 43: #define assert_with_errno(cond, msg) check_with_errno(assert, cond, msg)
>> 44: #define guarantee_with_errno(cond, msg) check_with_errno(guarantee, cond, msg)
>
> useful; potentially in debug.hpp?
I'll create an jira ticker, I have spread this around to other places which also needs to be cleanup.
-------------
PR Comment: https://git.openjdk.org/jdk/pull/14670#issuecomment-1610966486
PR Review Comment: https://git.openjdk.org/jdk/pull/14670#discussion_r1244854484
More information about the hotspot-dev
mailing list