Lack of a standardized userspace API to detect active ARMv8.2‑A LSE atomic instruction usage
0 reputation · 15 May 2025, 01:48 UTC
0 reputation · 15 May 2025, 01:48 UTC
Developers need a reliable way to determine at runtime whether their atomic operations are executed using the ARMv8.2‑A Large System Extensions (LSE) instructions or have fallen back to the legacy LDREX/STREX loop, especially on systems that mix CPUs with and without LSE support.
While the Linux kernel can optionally disable LSE via a boot parameter or sysctl, there is no standardized userspace API to query whether the kernel or libc is actually using LSE for a given atomic primitive, leaving developers uncertain about performance guarantees on heterogeneous ARMv8.2‑A/ARMv8.0 systems.
What mechanism could expose LSE usage status to user space without breaking existing ABI? Should a new sysfs attribute, proc entry, or prctl option be added to report active LSE usage? How can libraries safely adapt their atomic paths based on this information while maintaining portability across ARMv8.0‑A only CPUs?
32775 reputation · 15 May 2025, 12:43 UTC
There is currently no stable, ABI‑preserving userspace API that reports whether a running kernel or libc is executing atomic primitives with the ARMv8.2‑A Large System Extensions (LSE) instruction set. The only mechanisms that exist are:
/proc/cpuinfo or via getauxval(AT_HWCAP2) for the HWCAP2_LSE bit.__ARM_FEATURE_LSE that inform the compiler which instruction set to generate.arm64.lse=off) that can force the kernel to fall back to LDREX/STREX loops, but no user‑space query exists to detect that switch.Because the feature is a low‑level CPU capability and the kernel may choose to enable or disable it per‑process, a portable, version‑agnostic API would need to expose a per‑process flag that can be queried without changing the existing ABI. The most straightforward approach would be a read‑only sysfs entry (e.g., /sys/devices/system/cpu/cpu0/lse_enabled) or a prctl option that returns a boolean. Such a feature would not alter the current ABI; it would simply add a new, optional query path for applications that need to adapt at runtime.
Linux and other kernels historically expose CPU capabilities only through the auxiliary vector and /proc/cpuinfo. Adding a new userspace API would require kernel development effort and careful consideration of backward compatibility. Since LSE is optional and may be disabled by boot parameters, kernel maintainers have not found a strong enough use case to justify the added complexity.
LDADDX and STLEX that can replace the legacy LDREX/STREX loop.HWCAP2_LSE (bit 6 in AT_HWCAP2) indicates hardware support for LSE at boot time.arm64.lse=off kernel parameter, but there is no user‑space query for that state.-march=armv8.2-a+lse or the compiler detects the flag at runtime.cat /proc/cpuinfo | grep lse or use getauxval(AT_HWCAP2) & 0x40 to see if the CPU advertises LSE support.CONFIG_ARM64_LSE and no boot flag disables it, the kernel will allow LSE instructions. Check /proc/cmdline for arm64.lse=off.__atomic_fetch_add) with -march=armv8.2-a+lse. Run it on the target; if it crashes with SIGILL, the CPU or kernel is not allowing LSE.getauxval check at startup and set an internal flag. They can then choose the LSE path if the flag is set and the kernel is not disabling it via boot parameters./sys/devices/system/cpu/cpu0/lse_enabled file that mirrors the per‑process LSE state.prctl(SET_LSE_ENABLED, 0/1) call that lets a process query or enforce LSE usage, with a no‑op implementation on kernels that do not support the flag.arch/arm64/Documentation explaining the relationship between HWCAP2_LSE, kernel boot parameters, and userspace detection.To refine the recommendation, could you confirm whether the kernel you target is built with CONFIG_ARM64_LSE and whether the arm64.lse=off parameter is ever used? Knowing the kernel configuration will determine whether a runtime query is necessary or whether compile‑time detection suffices.
Use comments to ask for clarification. Post a solution as an answer.
32,775 reputation · 15 May 2025, 10:31 UTC
Although no standard ABI exists, recent Linux kernels expose a PMU event named LSE_ATOMIC that counts every LSE atomic instruction executed by a process. The perf_event_open syscall can attach to this event, giving a real‑time counter without touching the kernel’s ABI.
#include <linux/perf_event.h>
#include <unistd.h>
#include <sys/syscall.h>
static long perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
int cpu, int group_fd, unsigned long flags){
return syscall(__NR_perf_event_open, hw_event, pid, cpu, group_fd, flags);
}
int main(){
struct perf_event_attr pe = {0};
pe.type = PERF_TYPE_HW_CACHE;
pe.config = 0x0; // use LSE_ATOMIC event id, see /sys/bus/event_source/devices/armv8_2_lse_atomic
pe.size = sizeof(struct perf_event_attr);
pe.disabled = 1;
int fd = perf_event_open(&pe, 0, -1, -1, 0);
if(fd < 0){ perror("perf_event_open"); return 1; }
ioctl(fd, PERF_EVENT_IOC_RESET, 0);
ioctl(fd, PERF_EVENT_IOC_ENABLE, 0);
/* run code that may use LSE */
ioctl(fd, PERF_EVENT_IOC_DISABLE, 0);
unsigned long long count;
read(fd, &count, sizeof(count));
printf("LSE atomics: %llu\n", count);
close(fd);
}
Requirements: kernel must be built with CONFIG_ARM_PMU and the LSE_ATOMIC event enabled; the process needs CAP_PERFMON (or run as root). This method works on ARMv8.2‑A CPUs that support LSE and on kernels that expose the event, but it is not a portable, cross‑OS solution.