Re: [PATCH net-next 1/2] netconsole: publish the userdata payload with RCU
From: Gustavo Luiz Duarte <hidden>
Date: 2026-08-04 17:09:57
Also in:
linux-kselftest, lkml
On Mon, Aug 3, 2026 at 12:30 PM Breno Leitao [off-list ref] wrote:
quoted hunk ↗ jump to hunk
update_userdata() takes target_list_lock to swap nt->userdata and nt->userdata_length, then frees the old buffer. Since commit 7eab73b18630 ("netconsole: convert to NBCON console infrastructure") that lock is also the console's device_lock, so writing a userdata value from configfs serialises against the printk core emitting messages. The buffer is immutable once published, which is what RCU is for. Move the string and its length into a single netconsole_userdata object and publish it with rcu_replace_pointer(), freeing the old one with kfree_rcu(). New userdata design: 0) Unify the userdata fields into a struct netcons_userdata 1) update_userdata() no longer needs target_list_lock. 2) writers stay serialised by dynamic_netconsole_mutex. 3) reading userdata needs an RCU read lock. No functional change intended. Signed-off-by: Breno Leitao <leitao@debian.org> --- drivers/net/netconsole.c | 88 +++++++++++++++++++++++++++++------------------- 1 file changed, 54 insertions(+), 34 deletions(-)diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index 862001d09aa84..c88c82f2136cb 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c@@ -135,13 +135,27 @@ enum target_state { STATE_DEACTIVATED, }; +/** + * struct netcons_userdata - Formatted userdata payload of a target. + * @rcu: Used to free the payload after a grace period. + * @length: Length of @data, excluding the NUL terminator. + * @data: Formatted " key=value\n" entries, NUL terminated. + * + * Immutable once published, so the transmit path never observes @data and + * @length disagreeing. + */ +struct netcons_userdata { + struct rcu_head rcu; + size_t length; + char data[]; +}; + /** * struct netconsole_target - Represents a configured netconsole target. * @list: Links this target into the target_list. * @group: Links us into the configfs subsystem hierarchy. * @userdata_group: Links to the userdata configfs hierarchy - * @userdata: Cached, formatted string of append - * @userdata_length: String length of userdata. + * @userdata: Cached, formatted userdata payload. RCU protected. * @sysdata: Cached, formatted string of append * @sysdata_fields: Sysdata features enabled. * @msgcounter: Message sent counter.@@ -176,8 +190,7 @@ struct netconsole_target { #ifdef CONFIG_NETCONSOLE_DYNAMIC struct config_group group; struct config_group userdata_group; - char *userdata; - size_t userdata_length; + struct netcons_userdata __rcu *userdata;
With userdata now annotated with __rcu, it should be freed with kfree(rcu_access_pointer(nt->userdata)) to avoid a sparse warning: $ make C=1 drivers/net/netconsole.o DESCEND objtool DESCEND bpf/resolve_btfids INSTALL libsubcmd_headers CC drivers/net/netconsole.o CHECK drivers/net/netconsole.c drivers/net/netconsole.c:1702:17: expected void const *objp drivers/net/netconsole.c:1702:17: got struct netcons_userdata [noderef] __rcu *userdata drivers/net/netconsole.c:2689:17: expected void const *objp drivers/net/netconsole.c:2689:17: got struct netcons_userdata [noderef] __rcu *userdata