Re: [PATCH v4 1/2] xen/console: correct leaky-bucket rate limiter

Roger Pau Monné <[email protected]>
Newsgroups org.xenproject.lists.xen-devel
Message-ID <[email protected]>
You mention "correct" in the subject, but there's no fixes tag, and
it's not clear exactly what this patch corrects.

On Wed, Jul 29, 2026 at 12:25:19AM -0700, [email protected] wrote:
> From: Denis Mukhin <[email protected]> 
> 
> Use existing 'ratelimit_ms' and 'ratelimit_burst' variables in
> do_printk_ratelimit() instead of hardcoded values 5000 and 10 respectively.
> 
> Ensure rate limiter is disabled if either 'ratelimit_ms' or 'ratelimit_burst'
> is 0.
> 
> Account for integer overflow in the rate-limiter logic.
> 
> Signed-off-by: Denis Mukhin <[email protected]>
> ---
> Changes since v3:
> - fixed types
> - fixed integer division logic - I used DIM_MUL2() from xvmalloc.h
>   I hope this is fine given another pending patch which will include xvmalloc.h
>   for heap allocations
> - fixed potential problem w/ overflow of toks (introduced elapsed)
> - fixed potential problem with toks == 0 which is also "uninitialized"
>   state.
> ---
>  xen/drivers/char/console.c | 37 ++++++++++++++++++++++++++++++-------
>  1 file changed, 30 insertions(+), 7 deletions(-)
> 
> diff --git a/xen/drivers/char/console.c b/xen/drivers/char/console.c
> index ea4e3ff34178..76a1681670c1 100644
> --- a/xen/drivers/char/console.c
> +++ b/xen/drivers/char/console.c
> @@ -33,6 +33,7 @@
>  #include <asm/setup.h>
>  #include <xen/sections.h>
>  #include <xen/consoled.h>
> +#include <xen/xvmalloc.h>
>  
>  #ifdef CONFIG_X86
>  #include <asm/guest.h>
> @@ -1286,21 +1287,43 @@ bool __printk_ratelimit(unsigned int ratelimit_ms,
>                          unsigned int ratelimit_burst)
>  {
>      static DEFINE_SPINLOCK(ratelimit_lock);
> -    static unsigned long toks = 10 * 5 * 1000;
> +    static unsigned long toks;
>      static unsigned long last_msg;
>      static unsigned int missed;
> +    static bool initialized;
> +    unsigned long limit;
>      unsigned long flags;
> -    unsigned long long now = NOW(); /* ns */
>      unsigned long ms;
> +    s_time_t now;
>  
> -    do_div(now, 1000000);
> -    ms = (unsigned long)now;
> +    if ( !ratelimit_ms || !ratelimit_burst )
> +        return true;
> +
> +    limit = DIM_MUL2(ratelimit_burst, ratelimit_ms);
> +
> +    now = NOW(); /* ns */
> +    do_div(now, MILLISECS(1));
> +    ms = now;
>  
>      spin_lock_irqsave(&ratelimit_lock, flags);
> -    toks += ms - last_msg;
> +
> +    if ( initialized )
> +    {
> +        unsigned long elapsed = ms - last_msg;
> +
> +        if ( toks >= limit || elapsed >= limit - toks )
> +            toks = limit;
> +        else
> +            toks += elapsed;
> +    }
> +    else
> +    {
> +        toks = limit;
> +        initialized = true;
> +    }

I'm not sure you need the `initialized` static variable.  You could
set the initial value of toks = ~0, and then if the limit is set to a
lower value it would already get adjusted as part of the toks >= limit
check?

Thanks, Roger.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.