Lack of a standardized userspace API to detect active ARMv8.2‑A LSE atomic instruction usage
29.1K 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?
1 answer
1 question comment
Use comments to ask for clarification. Post a solution as an answer.
29,110 reputation · 15 May 2025, 10:31 UTC
Practical PMU Work‑Around
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.