Skip to content

unscaledcycleclock: use RDTIME instead of RDCYCLE on RISC-V#1631

Closed
aurel32 wants to merge 1 commit intoabseil:masterfrom
aurel32:master
Closed

unscaledcycleclock: use RDTIME instead of RDCYCLE on RISC-V#1631
aurel32 wants to merge 1 commit intoabseil:masterfrom
aurel32:master

Conversation

@aurel32
Copy link
Contributor

@aurel32 aurel32 commented Feb 29, 2024

Starting with Linux 6.6 [1], RDCYCLE is a privileged instruction on RISC-V and can't be used directly from userland. There is a sysctl option to change that as a transition period, but it will eventually disappear.

Use RDTIME instead, which while less accurate has the advantage of being synchronized between CPU (and thus monotonic) and of constant frequency. Therefore this change also fixes another issue caused by wrong time measurement when a process is rescheduled from one CPU to another [2].

Given RDTIME uses a timer independent from the CPU, this patche removes the ABSL_INTERNAL_UNSCALED_CYCLECLOCK_FREQUENCY_IS_CPU_FREQUENCY define accordingly.

This fixes the testsuite on riscv64, tested on a VisionFive 2 board.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=cc4c07c89aada16229084eeb93895c95b7eabaa3
[2] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1025221

Starting with Linux 6.6 [1], RDCYCLE is a privileged instruction on
RISC-V and can't be used directly from userland. There is a sysctl
option to change that as a transition period, but it will eventually
disappear.

Use RDTIME instead, which while less accurate has the advantage of being
synchronized between CPU (and thus monotonic) and of constant frequency.
Therefore this change also fixes another issue caused by wrong time
measurement when a process is rescheduled from one CPU to another [2].

Given RDTIME uses a timer independent from the CPU, this patche removes
the ABSL_INTERNAL_UNSCALED_CYCLECLOCK_FREQUENCY_IS_CPU_FREQUENCY define
accordingly.

This fixes the testsuite on riscv64, tested on a VisionFive 2 board.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=cc4c07c89aada16229084eeb93895c95b7eabaa3
[2] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1025221
#if (defined(__i386__) || defined(__x86_64__) || defined(__riscv) || \
#if (defined(__i386__) || defined(__x86_64__) || \
defined(_M_IX86) || defined(_M_X64))
#define ABSL_INTERNAL_UNSCALED_CYCLECLOCK_FREQUENCY_IS_CPU_FREQUENCY
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need an implementation of UnscaledCycleClock::Frequency() now that these are not the same thing. The code in this repo may not call that method, but code exists that does.

https://riscv.org/wp-content/uploads/2016/06/riscv-spec-v2.1.pdf says

The RDTIME pseudo-instruction reads the low XLEN bits of the time CSR, which counts wall-clock
real time that has passed from an arbitrary start time in the past. RDTIMEH is an RV32I-only instruction that reads bits 63–32 of the same real-time counter. The underlying 64-bit counter should
never overflow in practice. The execution environment should provide a means of determining the
period of the real-time counter (seconds/tick). The period must be constant. The real-time clocks
of all hardware threads in a single user application should be synchronized to within one tick of the
real-time clock. The environment should provide a means to determine the accuracy of the clock.

I have no idea how to get that.

If you are just trying to get something to build, -DABSL_USE_UNSCALED_CYCLECLOCK=0 should work.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The frequency is implementation dependent, and there is no easy way to get it. Could it be measured instead? Basically how it is done for the ABSL_INTERNAL_UNSCALED_CYCLECLOCK_FREQUENCY_IS_CPU_FREQUENCY?

aurel32 added a commit to aurel32/abseil-cpp that referenced this pull request Mar 19, 2024
Starting with Linux 6.6 [1], RDCYCLE is a privileged instruction on
RISC-V and can't be used directly from userland. There is a sysctl
option to change that as a transition period, but it will eventually
disappear.

The RDTIME instruction is another less accurate alternative, however its
frequency varies from board to board, and there is currently now way to
get its frequency from userland [2].

Therefore this patch just removes the code for unscaledcycleclock on
RISC-V. Without processor specific implementation, abseil relies on
std::chrono::steady_clock::now().time_since_epoch() which is basically a
wrapper around clock_gettime (CLOCK_MONOTONIC), which in turns use
__vdso_clock_gettime(). On RISC-V this VDSO is just a wrapper around
RDTIME correctly scaled to use nanoseconds units.

This fixes the testsuite on riscv64, tested on a VisionFive 2 board.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=cc4c07c89aada16229084eeb93895c95b7eabaa3
[2] abseil#1631
@aurel32
Copy link
Contributor Author

aurel32 commented Mar 19, 2024

Closing in favor of #1644

@aurel32 aurel32 closed this Mar 19, 2024
copybara-service bot pushed a commit that referenced this pull request Mar 22, 2024
Imported from GitHub PR #1644

Starting with Linux 6.6 [1], RDCYCLE is a privileged instruction on RISC-V and can't be used directly from userland. There is a sysctl option to change that as a transition period, but it will eventually disappear.

The RDTIME instruction is another less accurate alternative, however its frequency varies from board to board, and there is currently now way to get its frequency from userland [2].

Therefore this patch just removes the code for unscaledcycleclock on RISC-V. Without processor specific implementation, abseil relies on std::chrono::steady_clock::now().time_since_epoch() which is basically a wrapper around clock_gettime (CLOCK_MONOTONIC), which in turns use __vdso_clock_gettime(). On RISC-V this VDSO is just a wrapper around RDTIME correctly scaled to use nanoseconds units.

This fixes the testsuite on riscv64, tested on a VisionFive 2 board.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=cc4c07c89aada16229084eeb93895c95b7eabaa3
[2] #1631
Merge 43356a2 into 76f8011

Merging this change closes #1644

COPYBARA_INTEGRATE_REVIEW=#1644 from aurel32:rv64-no-unscaledcycleclock 43356a2
PiperOrigin-RevId: 618286262
Change-Id: Ie4120a727e7d0bb185df6e06ea145c780ebe6652
netkex pushed a commit to netkex/abseil-cpp that referenced this pull request Apr 3, 2024
Imported from GitHub PR abseil#1644

Starting with Linux 6.6 [1], RDCYCLE is a privileged instruction on RISC-V and can't be used directly from userland. There is a sysctl option to change that as a transition period, but it will eventually disappear.

The RDTIME instruction is another less accurate alternative, however its frequency varies from board to board, and there is currently now way to get its frequency from userland [2].

Therefore this patch just removes the code for unscaledcycleclock on RISC-V. Without processor specific implementation, abseil relies on std::chrono::steady_clock::now().time_since_epoch() which is basically a wrapper around clock_gettime (CLOCK_MONOTONIC), which in turns use __vdso_clock_gettime(). On RISC-V this VDSO is just a wrapper around RDTIME correctly scaled to use nanoseconds units.

This fixes the testsuite on riscv64, tested on a VisionFive 2 board.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=cc4c07c89aada16229084eeb93895c95b7eabaa3
[2] abseil#1631
Merge 43356a2 into 76f8011

Merging this change closes abseil#1644

COPYBARA_INTEGRATE_REVIEW=abseil#1644 from aurel32:rv64-no-unscaledcycleclock 43356a2
PiperOrigin-RevId: 618286262
Change-Id: Ie4120a727e7d0bb185df6e06ea145c780ebe6652
MingcongBai pushed a commit to AOSC-Tracking/qt-6 that referenced this pull request Feb 12, 2025
Imported from GitHub PR abseil/abseil-cpp#1644

Starting with Linux 6.6 [1], RDCYCLE is a privileged instruction on RISC-V and can't be used directly from userland. There is a sysctl option to change that as a transition period, but it will eventually disappear.

The RDTIME instruction is another less accurate alternative, however its frequency varies from board to board, and there is currently now way to get its frequency from userland [2].

Therefore this patch just removes the code for unscaledcycleclock on RISC-V. Without processor specific implementation, abseil relies on std::chrono::steady_clock::now().time_since_epoch() which is basically a wrapper around clock_gettime (CLOCK_MONOTONIC), which in turns use __vdso_clock_gettime(). On RISC-V this VDSO is just a wrapper around RDTIME correctly scaled to use nanoseconds units.

This fixes the testsuite on riscv64, tested on a VisionFive 2 board.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=cc4c07c89aada16229084eeb93895c95b7eabaa3
[2] abseil/abseil-cpp#1631
Merge 43356a2548cfde76e164d446cb69004b488c6a71 into 76f8011beabdaee872b5fde7546e02407b220cb1

Merging this change closes #1644

COPYBARA_INTEGRATE_REVIEW=abseil/abseil-cpp#1644 from aurel32:rv64-no-unscaledcycleclock 43356a2548cfde76e164d446cb69004b488c6a71
PiperOrigin-RevId: 618286262
Change-Id: Ie4120a727e7d0bb185df6e06ea145c780ebe6652

Link: https://github.com/riscv-forks/electron/raw/4eff53436a1a86ac548a107e21ca5078518833c0/patches/chromium/unscaledcycleclock-remove-riscv-support.patch
Signed-off-by: Mingcong Bai <[email protected]>
IgnotaYun pushed a commit to IgnotaYun/abseil-cpp that referenced this pull request Sep 28, 2025
Imported from GitHub PR abseil#1644

Starting with Linux 6.6 [1], RDCYCLE is a privileged instruction on RISC-V and can't be used directly from userland. There is a sysctl option to change that as a transition period, but it will eventually disappear.

The RDTIME instruction is another less accurate alternative, however its frequency varies from board to board, and there is currently now way to get its frequency from userland [2].

Therefore this patch just removes the code for unscaledcycleclock on RISC-V. Without processor specific implementation, abseil relies on std::chrono::steady_clock::now().time_since_epoch() which is basically a wrapper around clock_gettime (CLOCK_MONOTONIC), which in turns use __vdso_clock_gettime(). On RISC-V this VDSO is just a wrapper around RDTIME correctly scaled to use nanoseconds units.

This fixes the testsuite on riscv64, tested on a VisionFive 2 board.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=cc4c07c89aada16229084eeb93895c95b7eabaa3
[2] abseil#1631
Merge 43356a2 into 76f8011

Merging this change closes abseil#1644

COPYBARA_INTEGRATE_REVIEW=abseil#1644 from aurel32:rv64-no-unscaledcycleclock 43356a2
PiperOrigin-RevId: 618286262
Change-Id: Ie4120a727e7d0bb185df6e06ea145c780ebe6652
IgnotaYun pushed a commit to IgnotaYun/abseil-cpp that referenced this pull request Sep 28, 2025
Imported from GitHub PR abseil#1644

Starting with Linux 6.6 [1], RDCYCLE is a privileged instruction on RISC-V and can't be used directly from userland. There is a sysctl option to change that as a transition period, but it will eventually disappear.

The RDTIME instruction is another less accurate alternative, however its frequency varies from board to board, and there is currently now way to get its frequency from userland [2].

Therefore this patch just removes the code for unscaledcycleclock on RISC-V. Without processor specific implementation, abseil relies on std::chrono::steady_clock::now().time_since_epoch() which is basically a wrapper around clock_gettime (CLOCK_MONOTONIC), which in turns use __vdso_clock_gettime(). On RISC-V this VDSO is just a wrapper around RDTIME correctly scaled to use nanoseconds units.

This fixes the testsuite on riscv64, tested on a VisionFive 2 board.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=cc4c07c89aada16229084eeb93895c95b7eabaa3
[2] abseil#1631
Merge 43356a2 into 76f8011

Merging this change closes abseil#1644

COPYBARA_INTEGRATE_REVIEW=abseil#1644 from aurel32:rv64-no-unscaledcycleclock 43356a2
PiperOrigin-RevId: 618286262
Change-Id: Ie4120a727e7d0bb185df6e06ea145c780ebe6652
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants