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.

