Re: [PATCH net-next 1/2] netconsole: publish the userdata payload with RCU

Gustavo Luiz Duarte <[email protected]>
Newsgroups gmane.linux.network,gmane.linux.kernel
Message-ID <CAGSyskVKAwf8nb_3uFDbYUugR+dtO-cwSef8C9nSEgKZt_K=CQ@mail.gmail.com>
On Mon, Aug 3, 2026 at 12:30 PM Breno Leitao <[email protected]> wrote:
>
> 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 <[email protected]>
> ---
>  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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.