From: Breno Leitao <leitao@debian.org>
To: Andrew Lunn <andrew+netdev@lunn.ch>,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>,
Paolo Abeni <pabeni@redhat.com>, Simon Horman <horms@kernel.org>,
Jonathan Corbet <corbet@lwn.net>,
Shuah Khan <skhan@linuxfoundation.org>,
Shuah Khan <shuah@kernel.org>
Cc: Randy Dunlap <rdunlap@infradead.org>,
paulmck@kernel.org, gustavold@gmail.com, asantostc@gmail.com,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org,
Breno Leitao <leitao@debian.org>,
kernel-team@meta.com
Subject: [PATCH net-next v2 1/4] netconsole: add a per-target message rate limit
Date: Thu, 10 Sep 2026 06:46:10 -0700 [thread overview]
Message-ID: <20260910-netcons_ratelimit-v2-1-ebf0dd91e26e@debian.org> (raw)
In-Reply-To: <20260910-netcons_ratelimit-v2-0-ebf0dd91e26e@debian.org>
Give each target a token bucket and consult it once per message in
netconsole_write().
The bucket is created with a zero interval, which struct ratelimit_state
treats as unlimited, and nothing can set a nonzero one yet, so no target
changes behaviour.
Skip the bucket while oops_in_progress is set, so a limit configured for
steady-state logging never truncates an oops, BUG() or panic().
The configfs files that expose it come next.
___ratelimit() only trylocks its own raw spinlock, so it is safe with
target_list_lock held and interrupts disabled, and safe from NMI. Set
RATELIMIT_MSG_ON_RELEASE so it does not report the suppressed count
itself, which would printk() from inside the console being serviced.
Signed-off-by: Breno Leitao <leitao@debian.org>
---
drivers/net/netconsole.c | 36 ++++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index b358e5c3673510..13292c3f818e9f 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -49,6 +49,7 @@
#include <linux/rtnetlink.h>
#include <linux/workqueue.h>
#include <linux/delay.h>
+#include <linux/ratelimit.h>
MODULE_AUTHOR("Matt Mackall <mpm@selenic.com>");
MODULE_DESCRIPTION("Console driver for network interfaces");
@@ -175,6 +176,7 @@ struct netcons_userdata {
* @sysdata: Cached, formatted string of append
* @sysdata_fields: Sysdata features enabled.
* @msgcounter: Message sent counter.
+ * @ratelimit: Token bucket used to rate limit messages
* @stats: Packet send stats for the target. Used for debugging.
* @state: State of the target.
* Visible from userspace (read-write).
@@ -219,6 +221,7 @@ struct netconsole_target {
u32 sysdata_fields;
/* protected by target_list_lock */
u32 msgcounter;
+ struct ratelimit_state ratelimit;
#endif
struct netconsole_target_stats stats;
enum target_state state;
@@ -282,6 +285,26 @@ static void dynamic_netconsole_mutex_unlock(void)
mutex_unlock(&dynamic_netconsole_mutex);
}
+static void netconsole_ratelimit_init(struct netconsole_target *nt)
+{
+ ratelimit_state_init(&nt->ratelimit, 0, DEFAULT_RATELIMIT_BURST);
+ /* The flag keeps ___ratelimit() from reporting the suppressed count
+ * itself, which would printk() from inside the console being
+ * serviced. Nothing calls ratelimit_state_exit(), so the count is
+ * never reported on release either.
+ */
+ ratelimit_set_flags(&nt->ratelimit, RATELIMIT_MSG_ON_RELEASE);
+}
+
+static bool netconsole_ratelimited(struct netconsole_target *nt)
+{
+ /* A limit meant for steady-state logging must not eat a crash dump. */
+ if (oops_in_progress)
+ return false;
+
+ return !__ratelimit(&nt->ratelimit);
+}
+
#else /* !CONFIG_NETCONSOLE_DYNAMIC */
static int __init dynamic_netconsole_init(void)
@@ -318,6 +341,15 @@ static void dynamic_netconsole_mutex_unlock(void)
{
}
+static void netconsole_ratelimit_init(struct netconsole_target *nt)
+{
+}
+
+static bool netconsole_ratelimited(struct netconsole_target *nt)
+{
+ return false;
+}
+
#endif /* CONFIG_NETCONSOLE_DYNAMIC */
/* Check if the target was bound by mac address. */
@@ -686,6 +718,7 @@ static struct netconsole_target *alloc_and_init(void)
nt->remote_port = 6666;
eth_broadcast_addr(nt->remote_mac);
nt->state = STATE_DISABLED;
+ netconsole_ratelimit_init(nt);
INIT_WORK(&nt->resume_wq, process_resume_target);
/* Set up the skb pool primitives once; enabling only refills it. */
skb_queue_head_init(&nt->skb_pool);
@@ -2482,6 +2515,9 @@ static void netconsole_write(struct nbcon_write_context *wctxt, bool extended)
!netif_running(nt->np.dev))
continue;
+ if (netconsole_ratelimited(nt))
+ continue;
+
/* If nbcon_enter_unsafe() fails, just return given netconsole
* lost the ownership, and iterating over the targets will not
* be able to re-acquire.
--
2.53.0-Meta
next prev parent reply other threads:[~2026-09-10 13:46 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-10 13:46 [PATCH net-next v2 0/4] netconsole: Support messages ratelimit-ing Breno Leitao
2026-09-10 13:46 ` Breno Leitao [this message]
2026-09-12 0:06 ` [PATCH net-next v2 1/4] netconsole: add a per-target message rate limit netdev-bot+sashiko
2026-09-10 13:46 ` [PATCH net-next v2 2/4] netconsole: allow configuring the rate limit interval through configfs Breno Leitao
2026-09-12 0:06 ` netdev-bot+sashiko
2026-09-10 13:46 ` [PATCH net-next v2 3/4] netconsole: allow configuring the rate limit burst " Breno Leitao
2026-09-12 0:06 ` netdev-bot+sashiko
2026-09-10 13:46 ` [PATCH net-next v2 4/4] docs: netconsole: document rate limit feature Breno Leitao
2026-09-12 0:06 ` netdev-bot+sashiko
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260910-netcons_ratelimit-v2-1-ebf0dd91e26e@debian.org \
--to=leitao@debian.org \
--cc=andrew+netdev@lunn.ch \
--cc=asantostc@gmail.com \
--cc=corbet@lwn.net \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=gustavold@gmail.com \
--cc=horms@kernel.org \
--cc=kernel-team@meta.com \
--cc=kuba@kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=paulmck@kernel.org \
--cc=rdunlap@infradead.org \
--cc=shuah@kernel.org \
--cc=skhan@linuxfoundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®