[PATCH v3] lib: sbi: Ensure SBI extension is available

Anup Patel anup at brainfault.org
Thu May 11 00:51:00 PDT 2023


On Mon, May 1, 2023 at 5:38 PM Andrew Jones <ajones at ventanamicro.com> wrote:
>
> Ensure attempts to invoke SBI extension functions fail with
> SBI_ERR_NOT_SUPPORTED when the extension's probe function has
> reported that the extension is not available. To avoid invoking
> probe too frequently, we check single extension ID extensions at
> init time and even drop them from the extension list when their
> probe fails. If the probe succeeds, we keep it, and then later
> seeing that it's a single extension ID extension is enough to know
> it's available. Extensions which have multiple IDs must have its probe
> called for each, so we don't try to reduce calls to those. It's
> expected that these multi-ID extension probe functions implement
> their own optimizations in order to ensure extension lookups are
> fast.
>
> Signed-off-by: Andrew Jones <ajones at ventanamicro.com>
> ---
> v3:
>  - Only apply optimization to single extension ID extensions [Xiang]
>  - Drop extensions from extension list when they can be probed
>    at init time (and drop the, now unnecessary, status) [Anup]
>
>  lib/sbi/sbi_ecall.c | 32 +++++++++++++++++++++++---------
>  1 file changed, 23 insertions(+), 9 deletions(-)
>
> diff --git a/lib/sbi/sbi_ecall.c b/lib/sbi/sbi_ecall.c
> index 76a1ae9ab733..cb73105d7aa8 100644
> --- a/lib/sbi/sbi_ecall.c
> +++ b/lib/sbi/sbi_ecall.c
> @@ -42,16 +42,19 @@ static SBI_LIST_HEAD(ecall_exts_list);
>
>  struct sbi_ecall_extension *sbi_ecall_find_extension(unsigned long extid)
>  {
> -       struct sbi_ecall_extension *t, *ret = NULL;
> +       struct sbi_ecall_extension *t;
> +       unsigned long out_val;
>
>         sbi_list_for_each_entry(t, &ecall_exts_list, head) {
>                 if (t->extid_start <= extid && extid <= t->extid_end) {
> -                       ret = t;
> -                       break;
> +                       if (t->extid_start != t->extid_end && t->probe &&
> +                           (t->probe(extid, &out_val) || !out_val))

I disagree with this approach of penalizing extension spread over
a range of extension IDs. Particularly this adds overhead for
vendor extension.

I suggest, we should change the prototype of probe callback to:
"int (* probe)(struct sbi_ecall_extension *extl);"

And update existing probe functions to directly register extension
by calling sbi_ecall_register_extension().

The sbi_ecall_init() should call sbi_ecall_register_extension()
only for extensions which don't have a probe callback.

Based on this suggestion, no changes are required in
sbi_ecall_find_extension().

Regards,
Anup

> +                               return NULL;
> +                       return t;
>                 }
>         }
>
> -       return ret;
> +       return NULL;
>  }
>
>  int sbi_ecall_register_extension(struct sbi_ecall_extension *ext)
> @@ -148,15 +151,26 @@ int sbi_ecall_handler(struct sbi_trap_regs *regs)
>
>  int sbi_ecall_init(void)
>  {
> -       int ret;
>         struct sbi_ecall_extension *ext;
> -       unsigned long i;
> +       unsigned long out_val, i;
> +       int ret;
>
>         for (i = 0; i < sbi_ecall_exts_size; i++) {
>                 ext = sbi_ecall_exts[i];
> -               ret = sbi_ecall_register_extension(ext);
> -               if (ret)
> -                       return ret;
> +               /*
> +                * Don't bother adding extensions which have a single extension
> +                * ID and its probe fails. Extensions with multiple IDs need to
> +                * have their probe called on specific IDs, so we need to add
> +                * them here and probe on each use. And, of course, if there
> +                * isn't a probe function, then the extension is always
> +                * available, so we add it here.
> +                */
> +               if (ext->extid_start != ext->extid_end || !ext->probe ||
> +                   (!ext->probe(ext->extid_start, &out_val) && out_val)) {
> +                       ret = sbi_ecall_register_extension(ext);
> +                       if (ret)
> +                               return ret;
> +               }
>         }
>
>         return 0;
> --
> 2.40.0
>



More information about the opensbi mailing list