On Tue, Sep 22, 2026 at 8:25 AM Wilco Dijkstra <[email protected]> wrote:
>
>
> Feedback from the kernel team suggests that it's best to only use HWCAPs
> rather than also use low-level checks as done by has_lse128() and has_rcpc3().
> So change these to just use HWCAPs which simplifies the code and speeds up
> ifunc selection by avoiding expensive system register accesses.
>
> libatomic:
>         * config/linux/aarch64/host-config.h (has_lse2): Mark unused arg.
>         (has_lse128): Change to use HWCAPs and check size of struct.
>         (has_rcpc3): Likewise.

Ok.

>
> ---
>
> diff --git a/libatomic/config/linux/aarch64/host-config.h 
> b/libatomic/config/linux/aarch64/host-config.h
> index 
> 7f91528de5b2d04c4cda0a29622b32cdb1b442aa..78f56bad5aee39afc613836ebaea66fe6cf76790
>  100644
> --- a/libatomic/config/linux/aarch64/host-config.h
> +++ b/libatomic/config/linux/aarch64/host-config.h
> @@ -90,7 +90,7 @@ typedef struct __ifunc_arg_t {
>  #define MIDR_PARTNUM(midr)     (((midr) >> 4) & 0xfff)
>
>  static inline bool
> -has_lse2 (unsigned long hwcap, const __ifunc_arg_t *features)
> +has_lse2 (unsigned long hwcap, const __ifunc_arg_t *features UNUSED)
>  {
>    /* Check for LSE2.  */
>    if (hwcap & HWCAP_USCAT)
> @@ -109,50 +109,23 @@ has_lse2 (unsigned long hwcap, const __ifunc_arg_t 
> *features)
>    return false;
>  }
>
> -/* LSE128 atomic support encoded in ID_AA64ISAR0_EL1.Atomic, bits[23:20].
> -   The minimum value for LSE128 is 0b0011.  */
> -
> -#define AT_FEAT_FIELD(isar0)   (((isar0) >> 20) & 15)
> -
>  static inline bool
>  has_lse128 (unsigned long hwcap, const __ifunc_arg_t *features)
>  {
> -  if (hwcap & _IFUNC_ARG_HWCAP && features->_hwcap2 & HWCAP2_LSE128)
> -    return true;
> -
> -  /* If LSE2 and CPUID are supported, check for LSE128.  */
> -  if (hwcap & HWCAP_CPUID && hwcap & HWCAP_USCAT)
> -    {
> -      unsigned long isar0;
> -      asm volatile ("mrs %0, ID_AA64ISAR0_EL1" : "=r" (isar0));
> -      return AT_FEAT_FIELD (isar0) >= 3;
> -    }
> -
> -  return false;
> +  return (hwcap & _IFUNC_ARG_HWCAP
> +         && features->_size > offsetof (__ifunc_arg_t, _hwcap2)
> +         && features->_hwcap2 & HWCAP2_LSE128);
>  }
>
> -/* LRCPC atomic support encoded in ID_AA64ISAR1_EL1.Atomic, bits[23:20].
> -   The minimum value for LRCPC3 is 0b0011.  */
> -
>  static inline bool
>  has_rcpc3 (unsigned long hwcap, const __ifunc_arg_t *features)
>  {
>    /* LSE2 is a prerequisite for atomic LDIAPP/STILP - check HWCAP_USCAT since
> -     has_lse2 is more expensive and Neoverse N1 does not have LRCPC3. */
> -  if (!(hwcap & HWCAP_USCAT))
> -    return false;
> -
> -  if (hwcap & _IFUNC_ARG_HWCAP && features->_hwcap2 & HWCAP2_LRCPC3)
> -    return true;
> -
> -  if (hwcap & HWCAP_CPUID)
> -    {
> -      unsigned long isar1;
> -      asm volatile ("mrs %0, ID_AA64ISAR1_EL1" : "=r" (isar1));
> -      return AT_FEAT_FIELD (isar1) >= 3;
> -    }
> -
> -  return false;
> +     has_lse2 is more expensive and Neoverse N1 does not have LRCPC3.  */
> +  return (hwcap & _IFUNC_ARG_HWCAP
> +         && features->_size > offsetof (__ifunc_arg_t, _hwcap2)
> +         && features->_hwcap & HWCAP_USCAT
> +         && features->_hwcap2 & HWCAP2_LRCPC3);
>  }
>
>  #endif /* HAVE_IFUNC */
>

Reply via email to