Re: [PATCH net-next RFC 4/6] netconsole: tell the target when the rate limit drops messages

From: Gustavo Luiz Duarte

Date: Thu Aug 20 2026 - 16:50:11 EST


On Tue, Aug 18, 2026 at 11:30 AM Breno Leitao <leitao@xxxxxxxxxx> 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 <leitao@xxxxxxxxxx>
> ---
> 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 <mpm@xxxxxxxxxxx>");
> 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.