[PATCH net-next RFC 4/6] netconsole: tell the target when the rate limit drops messages
From: Breno Leitao <leitao@debian.org>
Date: 2026-08-18 10:30:04
Also in:
linux-doc, linux-kselftest, lkml
Subsystem:
netconsole, networking drivers, the rest · Maintainers:
Breno Leitao, Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
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@debian.org> --- 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@selenic.com>"); 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); + } + + len += scnprintf(nt->buf + len, sizeof(nt->buf) - len, + "netconsole: %u messages dropped by rate limit\n", + drops); + + send_udp(nt, nt->buf, len); +} + /** * netconsole_write - Generic function to send a msg to all targets * @wctxt: nbcon write context
@@ -2583,6 +2632,8 @@ static void netconsole_write(struct nbcon_write_context *wctxt, bool extended) if (!nbcon_enter_unsafe(wctxt)) return; + send_ratelimit_notice(nt, extended); + if (extended) send_ext_msg_udp(nt, wctxt); else
--
2.53.0-Meta