[RFC PATCH 2/3] arm64: cpufeature: constify arm64_ftr_regs array

Ard Biesheuvel ard.biesheuvel at linaro.org
Tue Aug 30 03:50:46 PDT 2016


On 26 August 2016 at 18:15, Ard Biesheuvel <ard.biesheuvel at linaro.org> wrote:
> Constify the arm64_ftr_regs array, by moving the mutable arm64_ftr_reg
> fields out of the array itself. This also streamlines the bsearch, since
> the entire array can be covered by fewer cachelines. Moving the payload
> out of the array also allows us to have special explicitly defined
> struct instance in case other code needs to refer to it directly.
>
> Note that this replaces the runtime sorting of the array with a runtime
> BUG() check whether the array is sorted correctly in the code.
>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
> ---
>  arch/arm64/include/asm/cpufeature.h |  1 -
>  arch/arm64/kernel/cpufeature.c      | 45 +++++++++-----------
>  2 files changed, 19 insertions(+), 27 deletions(-)
>
> diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
> index 7c0b7cff17df..8bb4f1527b26 100644
> --- a/arch/arm64/include/asm/cpufeature.h
> +++ b/arch/arm64/include/asm/cpufeature.h
> @@ -72,7 +72,6 @@ struct arm64_ftr_bits {
>   * @sys_val            Safe value across the CPUs (system view)
>   */
>  struct arm64_ftr_reg {
> -       u32                             sys_id;
>         const char                      *name;
>         u64                             strict_mask;
>         u64                             sys_val;
> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> index eac76cb3a206..35a17487ffb9 100644
> --- a/arch/arm64/kernel/cpufeature.c
> +++ b/arch/arm64/kernel/cpufeature.c
> @@ -265,14 +265,17 @@ static const struct arm64_ftr_bits ftr_aa64raz[] = {
>         ARM64_FTR_END,
>  };
>
> -#define ARM64_FTR_REG(id, table)               \
> -       {                                       \
> -               .sys_id = id,                   \
> +#define ARM64_FTR_REG(id, table) {             \
> +       .sys_id = id,                           \
> +       .reg =  &(struct arm64_ftr_reg){        \
>                 .name = #id,                    \
>                 .ftr_bits = &((table)[0]),      \
> -       }
> +       }}
>
> -static struct arm64_ftr_reg arm64_ftr_regs[] = {
> +static const struct __ftr_reg_entry {
> +       u32                     sys_id;
> +       struct arm64_ftr_reg    *reg;
> +} arm64_ftr_regs[] = {
>
>         /* Op1 = 0, CRn = 0, CRm = 1 */
>         ARM64_FTR_REG(SYS_ID_PFR0_EL1, ftr_id_pfr0),
> @@ -324,7 +327,7 @@ static struct arm64_ftr_reg arm64_ftr_regs[] = {
>
>  static int search_cmp_ftr_reg(const void *id, const void *regp)
>  {
> -       return (int)(unsigned long)id - (int)((const struct arm64_ftr_reg *)regp)->sys_id;
> +       return (int)(unsigned long)id - (int)((const struct __ftr_reg_entry *)regp)->sys_id;
>  }
>
>  /*
> @@ -339,11 +342,14 @@ static int search_cmp_ftr_reg(const void *id, const void *regp)
>   */
>  static struct arm64_ftr_reg *get_arm64_ftr_reg(u32 sys_id)
>  {
> -       return bsearch((const void *)(unsigned long)sys_id,
> +       const struct __ftr_reg_entry *ret;
> +
> +       ret = bsearch((const void *)(unsigned long)sys_id,
>                         arm64_ftr_regs,
>                         ARRAY_SIZE(arm64_ftr_regs),
>                         sizeof(arm64_ftr_regs[0]),
>                         search_cmp_ftr_reg);
> +       return ret->reg;

Actually, this should be

return ret ? ret->reg : NULL;


>  }
>
>  static u64 arm64_ftr_set_value(const struct arm64_ftr_bits *ftrp, s64 reg,
> @@ -378,27 +384,14 @@ static s64 arm64_ftr_safe_value(const struct arm64_ftr_bits *ftrp, s64 new,
>         return ret;
>  }
>
> -static int __init sort_cmp_ftr_regs(const void *a, const void *b)
> -{
> -       return ((const struct arm64_ftr_reg *)a)->sys_id -
> -                ((const struct arm64_ftr_reg *)b)->sys_id;
> -}
> -
> -static void __init swap_ftr_regs(void *a, void *b, int size)
> -{
> -       struct arm64_ftr_reg tmp = *(struct arm64_ftr_reg *)a;
> -       *(struct arm64_ftr_reg *)a = *(struct arm64_ftr_reg *)b;
> -       *(struct arm64_ftr_reg *)b = tmp;
> -}
> -
>  static void __init sort_ftr_regs(void)
>  {
> -       /* Keep the array sorted so that we can do the binary search */
> -       sort(arm64_ftr_regs,
> -               ARRAY_SIZE(arm64_ftr_regs),
> -               sizeof(arm64_ftr_regs[0]),
> -               sort_cmp_ftr_regs,
> -               swap_ftr_regs);
> +       int i;
> +
> +       /* Check that the array is sorted so that we can do the binary search */
> +       for (i = 1; i < ARRAY_SIZE(arm64_ftr_regs); i++)
> +               if (arm64_ftr_regs[i].sys_id < arm64_ftr_regs[i - 1].sys_id)
> +                       BUG();
>  }
>
>  /*
> --
> 2.7.4
>



More information about the linux-arm-kernel mailing list