On Tue, Aug 18, 2026 at 11:30 AM Breno Leitao <[email protected]> wrote:
>
> Keep the number of messages dropped since the last report on the target
> and send it to the receiver as soon as a message gets through again:
>
>   netconsole: 45 messages dropped by rate limit
>
> netconsole formats that record itself rather than calling printk(),
> which would feed the console it is currently servicing. Nothing here has
> a printk sequence number, so the extended header carries a zero.
>
> The timestamp comes from local_clock(), the same clock printk stamps its
> records with, but it is taken when the notice goes out rather than when
> the message was logged. It can therefore read a few microseconds later
> than the message it precedes.
>
> The notice rides on the next message the bucket lets through, so a
> target that goes quiet right after a burst of drops only reports them
> once the host logs again, and a target with ratelimit_burst set to zero
> never reports at all.
>
> Signed-off-by: Breno Leitao <[email protected]>
> ---
>  drivers/net/netconsole.c | 53 
> +++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 52 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
> index 6d60a5188bf13..0af2e5b4335c0 100644
> --- a/drivers/net/netconsole.c
> +++ b/drivers/net/netconsole.c
> @@ -50,6 +50,7 @@
>  #include <linux/workqueue.h>
>  #include <linux/delay.h>
>  #include <linux/ratelimit.h>
> +#include <linux/sched/clock.h>
>
>  MODULE_AUTHOR("Matt Mackall <[email protected]>");
>  MODULE_DESCRIPTION("Console driver for network interfaces");
> @@ -177,6 +178,7 @@ struct netcons_userdata {
>   * @sysdata_fields:    Sysdata features enabled.
>   * @msgcounter:        Message sent counter.
>   * @ratelimit: Opaque structure to ratelimit messages
> + * @pending_drops: Messages dropped since the last notice was sent.
>   * @stats:     Packet send stats for the target. Used for debugging.
>   * @state:     State of the target.
>   *             Visible from userspace (read-write).
> @@ -221,6 +223,7 @@ struct netconsole_target {
>         u32                     sysdata_fields;
>         /* protected by target_list_lock */
>         u32                     msgcounter;
> +       u32                     pending_drops;
>         struct ratelimit_state  ratelimit;
>  #endif
>         struct netconsole_target_stats stats;
> @@ -297,7 +300,20 @@ static bool netconsole_ratelimited(struct 
> netconsole_target *nt)
>         if (oops_in_progress)
>                 return false;
>
> -       return !__ratelimit(&nt->ratelimit);
> +       if (__ratelimit(&nt->ratelimit))
> +               return false;
> +
> +       nt->pending_drops++;
> +
> +       return true;
> +}
> +
> +static u32 netconsole_take_drops(struct netconsole_target *nt)
> +{
> +       u32 drops = nt->pending_drops;
> +
> +       nt->pending_drops = 0;
> +       return drops;
>  }
>
>  #else  /* !CONFIG_NETCONSOLE_DYNAMIC */
> @@ -345,6 +361,11 @@ static bool netconsole_ratelimited(struct 
> netconsole_target *nt)
>         return false;
>  }
>
> +static u32 netconsole_take_drops(struct netconsole_target *nt)
> +{
> +       return 0;
> +}
> +
>  #endif /* CONFIG_NETCONSOLE_DYNAMIC */
>
>  /* Check if the target was bound by mac address. */
> @@ -2554,6 +2575,34 @@ static void send_msg_udp(struct netconsole_target *nt, 
> const char *msg,
>         }
>  }
>
> +static void send_ratelimit_notice(struct netconsole_target *nt, bool 
> extended)
> +{
> +       int len = 0;
> +       u64 ts_usec;
> +       u32 drops;
> +
> +       drops = netconsole_take_drops(nt);
> +       if (!drops)
> +               return;
> +
> +       if (extended) {
> +               /* append the extended headers */
> +               if (nt->release)
> +                       len = scnprintf(nt->buf, sizeof(nt->buf), "%s,",
> +                                       init_utsname()->release);
> +
> +               ts_usec = div_u64(local_clock(), NSEC_PER_USEC);
> +               len += scnprintf(nt->buf + len, sizeof(nt->buf) - len,
> +                                "%u,0,%llu,-;", LOGLEVEL_WARNING, ts_usec);
> +       }

This additional message with sequence number zero in the middle of a
stream looks awkward.
I don't think we need to send a notice about dropped messages to
extended console targets. Those targets can detect dropped messages by
tracking the sequence number in the message header.

Reply via email to