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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.