On 3/4/25 16:24, Jerome Forissier wrote:
> Introduce a uthread scheduling loop into udelay() when CONFIG_UTHREAD
> is enabled. This means that any uthread calling into udelay() may yield
> to uthread and be scheduled again later. The granunlarity of the
> scheduling loop is defined by CONFIG_UTHREAD_GRANULARITY. The lower the
> value, the tighter the loop. The default value of 10 ms was chosen by
> testing the concurrent initialization of the two USB busses of an
> i.MX93 board (introduced in a later commit). The total time is as
> follows:
> 
>   UTHREAD_GRANULARITY (us) |  "usb start" time (s)
>   -------------------------+----------------------
>                          0 |                2.426
>                       1000 |                2.448
>                      10000 |                2.512
>                     100000 |                2.992
>                     300000 |                3.407
> 
> For reference, if uthread_schedule() is not called at all in udelay()
> except once via schedule(), the "usb start" time is 4.377s and without
> UTHREAD it is 4.591 s.

Replying to myself... but I have done some more tests on the i.MX93 and
this UTHREAD_GRANULARITY delay is not good. The console drops characters
as soon as it is greater than 5 microseconds. That's after running
"spawn sleep 10" -- the console becomes buggy during 10 seconds then back
to normal. With UTHREAD_GRANULARITY=0 all is fine.

Therefore I consider dropping UTHREAD_GRANULARITY in v4 and using a tight
loop like in v2 [1].

[1] https://lists.denx.de/pipermail/u-boot/2025-February/581634.html

-- 
Jerome
> 
> Signed-off-by: Jerome Forissier <jerome.foriss...@linaro.org>
> ---
>  lib/Kconfig |  8 ++++++++
>  lib/time.c  | 21 ++++++++++++++++++++-
>  2 files changed, 28 insertions(+), 1 deletion(-)
> 
> diff --git a/lib/Kconfig b/lib/Kconfig
> index 8321f20e154..40964f5bb4a 100644
> --- a/lib/Kconfig
> +++ b/lib/Kconfig
> @@ -1276,6 +1276,14 @@ config UTHREAD_STACK_SIZE
>         When the stack_sz argument to uthread_create() is zero then this
>         value is used.
>  
> +config UTHREAD_GRANULARITY
> +     int "Scheduling period for uthreads inside udelay()"
> +     depends on UTHREAD
> +     default 10000
> +     help
> +       The delay in microseconds between calls to uthread_schedule() inside
> +       the udelay() function.
> +
>  endmenu
>  
>  source "lib/fwu_updates/Kconfig"
> diff --git a/lib/time.c b/lib/time.c
> index d88edafb196..7c34424bf64 100644
> --- a/lib/time.c
> +++ b/lib/time.c
> @@ -17,6 +17,7 @@
>  #include <asm/global_data.h>
>  #include <asm/io.h>
>  #include <linux/delay.h>
> +#include <uthread.h>
>  
>  #ifndef CFG_WD_PERIOD
>  # define CFG_WD_PERIOD       (10 * 1000 * 1000)      /* 10 seconds default */
> @@ -190,6 +191,23 @@ void __weak __udelay(unsigned long usec)
>  
>  /* ------------------------------------------------------------------------- 
> */
>  
> +static void do_delay(unsigned long kv)
> +{
> +#if CONFIG_IS_ENABLED(UTHREAD)
> +     ulong t0 = timer_get_us();
> +     ulong gr = CONFIG_UTHREAD_GRANULARITY;
> +
> +     if (kv < CONFIG_UTHREAD_GRANULARITY)
> +             gr = kv;
> +     while (timer_get_us() - t0 < kv) {
> +             uthread_schedule();
> +             __udelay(gr);
> +     }
> +#else
> +     __udelay(kv);
> +#endif
> +}
> +
>  void udelay(unsigned long usec)
>  {
>       ulong kv;
> @@ -197,7 +215,8 @@ void udelay(unsigned long usec)
>       do {
>               schedule();
>               kv = usec > CFG_WD_PERIOD ? CFG_WD_PERIOD : usec;
> -             __udelay(kv);
> +             do_delay(kv);
>               usec -= kv;
>       } while(usec);
> +
>  }

Reply via email to