public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Petr Mladek <pmladek@suse.com>
To: Chris Down <chris@chrisdown.name>
Cc: linux-kernel@vger.kernel.org,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Sergey Senozhatsky <senozhatsky@chromium.org>,
	Steven Rostedt <rostedt@goodmis.org>,
	John Ogness <john.ogness@linutronix.de>,
	Geert Uytterhoeven <geert@linux-m68k.org>,
	Joel Granados <joel.granados@kernel.org>,
	Tony Lindgren <tony.lindgren@linux.intel.com>,
	kernel-team@fb.com
Subject: Re: [PATCH v8 18/21] printk: Deconstruct kernel.printk into discrete sysctl controls
Date: Fri, 12 Dec 2025 16:24:17 +0100	[thread overview]
Message-ID: <aTwzoSMUFJ2XiSBm@pathway> (raw)
In-Reply-To: <c3e5cc507eb3fd7db0a002f31d7e47d764cad176.1764272407.git.chris@chrisdown.name>

Adding Joel into Cc. Joel, see the original patch at
https://lore.kernel.org/all/c3e5cc507eb3fd7db0a002f31d7e47d764cad176.1764272407.git.chris@chrisdown.name/

On Fri 2025-11-28 03:44:25, Chris Down wrote:
> Introduce two new sysctl interfaces for configuring global loglevels:
> 
> - kernel.console_loglevel: Sets the global console loglevel, determining
>   the minimum priority of messages printed to consoles. Messages with a
>   loglevel lower than this value will be printed.
> - kernel.default_message_loglevel: Sets the default loglevel for
>   messages that do not specify an explicit loglevel.
> 
> The kernel.printk sysctl was previously used to set multiple loglevel
> parameters simultaneously, but it was confusing and lacked proper
> validation. By introducing these dedicated sysctl interfaces, we provide
> a clearer and more granular way to configure the loglevels.
> 
> Reviewed-by: Petr Mladek <pmladek@suse.com>
> Tested-by: Petr Mladek <pmladek@suse.com>
> Signed-off-by: Chris Down <chris@chrisdown.name>

This patch requires non-trivial changes when rebased on top of v6.19.
There have been some conflicting changes in the sysctl API, see
https://lore.kernel.org/lkml/20251016-jag-sysctl_conv-v2-0-a2f16529acc4@kernel.org/

> --- a/include/linux/sysctl.h
> +++ b/include/linux/sysctl.h
> @@ -235,6 +235,13 @@ extern struct ctl_table_header *register_sysctl_mount_point(const char *path);
>  
>  void do_sysctl_args(void);
>  bool sysctl_is_alias(char *param);
> +int do_proc_dointvec_conv(bool *negp, unsigned long *lvalp, int *valp,
> +			  int write, void *data);
> +int do_proc_dointvec(const struct ctl_table *table, int write,
> +		     void *buffer, size_t *lenp, loff_t *ppos,
> +		     int (*conv)(bool *negp, unsigned long *lvalp, int *valp,
> +				 int write, void *data),
> +		     void *data);
>  int do_proc_douintvec(const struct ctl_table *table, int write,
>  		      void *buffer, size_t *lenp, loff_t *ppos,
>  		      int (*conv)(unsigned long *lvalp,

This hunk can be removed in v6.19. There is another interface in 6.19,
see below.

> diff --git a/kernel/printk/sysctl.c b/kernel/printk/sysctl.c
> index da77f3f5c1fe..034739939a61 100644
> --- a/kernel/printk/sysctl.c
> +++ b/kernel/printk/sysctl.c
> @@ -11,6 +11,9 @@
>  
>  static const int ten_thousand = 10000;
>  
> +static int min_msg_loglevel = LOGLEVEL_EMERG;
> +static int max_msg_loglevel = LOGLEVEL_DEBUG;
> +
>  static int proc_dointvec_minmax_sysadmin(const struct ctl_table *table, int write,
>  				void *buffer, size_t *lenp, loff_t *ppos)
>  {
> @@ -20,6 +23,50 @@ static int proc_dointvec_minmax_sysadmin(const struct ctl_table *table, int writ
>  	return proc_dointvec_minmax(table, write, buffer, lenp, ppos);
>  }

The new way is to define the needed helpers using macros. We need this:

static SYSCTL_USER_TO_KERN_INT_CONV(, SYSCTL_CONV_IDENTITY)
static SYSCTL_KERN_TO_USER_INT_CONV(, SYSCTL_CONV_IDENTITY)
static SYSCTL_INT_CONV_CUSTOM(, sysctl_user_to_kern_int_conv,
			      sysctl_kern_to_user_int_conv, false)


> +static int do_proc_dointvec_console_loglevel(bool *negp, unsigned long *lvalp,
> +					     int *valp,
> +					     int write, void *data)

There parameters have got renamed and @table is passed instead or @data:

static int do_proc_dointvec_console_loglevel(bool *negp, unsigned long *u_ptr,
					     int *k_ptr, int dir,
					     const struct ctl_table *table)


> +{
> +	int level, ret;
> +
> +	/*
> +	 * If writing, first do so via a temporary local int so we can
> +	 * bounds-check it before touching *valp.
> +	 */
> +	int *intp = write ? &level : valp;

The direction is newly checked by macro:

	int *int_ptr = SYSCTL_USER_TO_KERN(dir) ? &level : k_ptr;

> +	ret = do_proc_dointvec_conv(negp, lvalp, intp, write, data);

The following helper is defined by the above mentioned macros:

	ret = do_proc_int_conv(negp, u_ptr, int_ptr, dir, table);

> +	if (ret)
> +		return ret;
> +
> +	if (write) {

The new way:

	if (SYSCTL_USER_TO_KERN(dir)) {

> +		if (level != console_clamp_loglevel(level))
> +			return -ERANGE;
> +
> +		/*
> +		 * Honour the administrator-configured minimum console
> +		 * loglevel (third element of kernel.printk).  This mirrors
> +		 * the syslog() and sysfs control paths so that once the floor
> +		 * is raised we do not let this sysctl silently bypass it.
> +		 */
> +		if (minimum_console_loglevel > CONSOLE_LOGLEVEL_MIN &&
> +		    level < minimum_console_loglevel)
> +			level = minimum_console_loglevel;
> +
> +		WRITE_ONCE(*valp, level);

New parameter name:

		WRITE_ONCE(*k_ptr, level);

> +	}
> +
> +	return 0;
> +}
> +
> +static int proc_dointvec_console_loglevel(const struct ctl_table *table,
> +					  int write, void *buffer, size_t *lenp,
> +					  loff_t *ppos)
> +{
> +	return do_proc_dointvec(table, write, buffer, lenp, ppos,
> +			       do_proc_dointvec_console_loglevel, NULL);

There is a new function where the last NULL parameter is not longer passed:

	return proc_dointvec_conv(table, write, buffer, lenp, ppos,
			       do_proc_dointvec_console_loglevel);

> +}
> +
>  static const struct ctl_table printk_sysctls[] = {
>  	{
>  		.procname	= "printk",


Here are the above described changes made by diff:

--- a/kernel/printk/sysctl.c
+++ b/kernel/printk/sysctl.c
@@ -24,9 +24,14 @@ static int proc_dointvec_minmax_sysadmin(const struct ctl_table *table, int writ
 	return proc_dointvec_minmax(table, write, buffer, lenp, ppos);
 }
 
-static int do_proc_dointvec_console_loglevel(bool *negp, unsigned long *lvalp,
-					     int *valp,
-					     int write, void *data)
+static SYSCTL_USER_TO_KERN_INT_CONV(, SYSCTL_CONV_IDENTITY)
+static SYSCTL_KERN_TO_USER_INT_CONV(, SYSCTL_CONV_IDENTITY)
+static SYSCTL_INT_CONV_CUSTOM(, sysctl_user_to_kern_int_conv,
+			      sysctl_kern_to_user_int_conv, false)
+
+static int do_proc_dointvec_console_loglevel(bool *negp, unsigned long *u_ptr,
+					     int *k_ptr, int dir,
+					     const struct ctl_table *table)
 {
 	int level, ret;
 
@@ -34,13 +39,13 @@ static int do_proc_dointvec_console_loglevel(bool *negp, unsigned long *lvalp,
 	 * If writing, first do so via a temporary local int so we can
 	 * bounds-check it before touching *valp.
 	 */
-	int *intp = write ? &level : valp;
+	int *int_ptr = SYSCTL_USER_TO_KERN(dir) ? &level : k_ptr;
 
-	ret = do_proc_dointvec_conv(negp, lvalp, intp, write, data);
+	ret = do_proc_int_conv(negp, u_ptr, int_ptr, dir, table);
 	if (ret)
 		return ret;
 
-	if (write) {
+	if (SYSCTL_USER_TO_KERN(dir)) {
 		if (level != console_clamp_loglevel(level))
 			return -ERANGE;
 
@@ -54,7 +59,7 @@ static int do_proc_dointvec_console_loglevel(bool *negp, unsigned long *lvalp,
 		    level < minimum_console_loglevel)
 			level = minimum_console_loglevel;
 
-		WRITE_ONCE(*valp, level);
+		WRITE_ONCE(*k_ptr, level);
 	}
 
 	return 0;
@@ -64,8 +69,8 @@ static int proc_dointvec_console_loglevel(const struct ctl_table *table,
 					  int write, void *buffer, size_t *lenp,
 					  loff_t *ppos)
 {
-	return do_proc_dointvec(table, write, buffer, lenp, ppos,
-			       do_proc_dointvec_console_loglevel, NULL);
+	return proc_dointvec_conv(table, write, buffer, lenp, ppos,
+			       do_proc_dointvec_console_loglevel);
 }
 
 static int proc_dointvec_printk_deprecated(const struct ctl_table *table, int write,


>  void __init printk_sysctl_init(void)
> diff --git a/kernel/sysctl.c b/kernel/sysctl.c
> index cb6196e3fa99..3ed010b8f6b3 100644
> --- a/kernel/sysctl.c
> +++ b/kernel/sysctl.c
> @@ -354,9 +354,9 @@ static void proc_put_char(void **buf, size_t *size, char c)
>  	}
>  }
>  
> -static int do_proc_dointvec_conv(bool *negp, unsigned long *lvalp,
> -				 int *valp,
> -				 int write, void *data)
> +int do_proc_dointvec_conv(bool *negp, unsigned long *lvalp,
> +			  int *valp,
> +			  int write, void *data)
>  {
>  	if (write) {
>  		if (*negp) {
> @@ -380,6 +380,7 @@ static int do_proc_dointvec_conv(bool *negp, unsigned long *lvalp,
>  	}
>  	return 0;
>  }
> +EXPORT_SYMBOL(do_proc_dointvec_conv);
>  
>  static int do_proc_douintvec_conv(unsigned long *lvalp,
>  				  unsigned int *valp,
> @@ -471,15 +472,16 @@ static int __do_proc_dointvec(void *tbl_data, const struct ctl_table *table,
>  	return err;
>  }
>  
> -static int do_proc_dointvec(const struct ctl_table *table, int write,
> -		  void *buffer, size_t *lenp, loff_t *ppos,
> -		  int (*conv)(bool *negp, unsigned long *lvalp, int *valp,
> -			      int write, void *data),
> -		  void *data)
> +int do_proc_dointvec(const struct ctl_table *table, int write,
> +		     void *buffer, size_t *lenp, loff_t *ppos,
> +		     int (*conv)(bool *negp, unsigned long *lvalp, int *valp,
> +				 int write, void *data),
> +		     void *data)
>  {
>  	return __do_proc_dointvec(table->data, table, write,
>  			buffer, lenp, ppos, conv, data);
>  }
> +EXPORT_SYMBOL(do_proc_dointvec);
>  
>  static int do_proc_douintvec_w(unsigned int *tbl_data,
>  			       const struct ctl_table *table,

Also all these changes in kernel/sysctl.c are not loger needed.

Best Regards,
Petr

  reply	other threads:[~2025-12-12 15:24 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-11-27 19:43 [PATCH v8 00/21] printk: console: Per-console loglevels Chris Down
2025-11-27 19:43 ` [PATCH v8 01/21] printk: Fully resolve loglevel before deciding printk delay suppression Chris Down
2025-12-09 16:40   ` Petr Mladek
2025-12-11 14:49     ` Petr Mladek
2025-12-11 15:28       ` Petr Mladek
2025-11-27 19:43 ` [PATCH v8 02/21] printk: Avoid spuriously delaying messages not solicited by any console Chris Down
2025-11-27 19:43 ` [PATCH v8 03/21] printk: Prioritise user-specified configuration over SPCR/DT Chris Down
2025-12-10 14:38   ` Petr Mladek
2025-11-27 19:43 ` [PATCH v8 04/21] printk: Use effective loglevel for suppression and extended console state Chris Down
2025-11-27 19:43 ` [PATCH v8 05/21] printk: console: Add per-console loglevel support to struct console Chris Down
2025-11-27 19:43 ` [PATCH v8 06/21] printk: nbcon: Synchronise console unregistration against atomic flushers Chris Down
2025-12-10 15:12   ` Petr Mladek
2025-11-27 19:43 ` [PATCH v8 07/21] printk: Introduce per-console loglevel support Chris Down
2025-11-27 19:43 ` [PATCH v8 08/21] printk: Iterate registered consoles for delay suppression decisions Chris Down
2025-11-27 19:43 ` [PATCH v8 09/21] printk: Optimise printk_delay() to avoid walking consoles under SRCU Chris Down
2025-12-11 14:37   ` Petr Mladek
2025-11-27 19:43 ` [PATCH v8 10/21] printk: Add synchronisation for concurrent console state changes Chris Down
2025-11-27 19:43 ` [PATCH v8 11/21] printk: Add ignore_per_console_loglevel module parameter Chris Down
2025-11-27 19:43 ` [PATCH v8 12/21] printk: Ensure sysrq output bypasses per-console filtering Chris Down
2025-11-27 19:44 ` [PATCH v8 13/21] printk: Toggle ignore_per_console_loglevel via syslog Chris Down
2025-11-27 19:44 ` [PATCH v8 14/21] printk: console: Introduce sysfs interface for per-console loglevels Chris Down
2025-12-12 14:04   ` Petr Mladek
2025-11-27 19:44 ` [PATCH v8 15/21] printk: sysrq: Clamp console loglevel to valid range Chris Down
2025-12-12 14:10   ` Petr Mladek
2025-11-27 19:44 ` [PATCH v8 16/21] printk: Constrain hardware-addressed console checks to name position Chris Down
2025-11-27 19:44 ` [PATCH v8 17/21] printk: Support setting initial console loglevel via console= on cmdline Chris Down
2025-11-27 19:44 ` [PATCH v8 18/21] printk: Deconstruct kernel.printk into discrete sysctl controls Chris Down
2025-12-12 15:24   ` Petr Mladek [this message]
2025-12-15 10:08     ` Joel Granados
2025-12-15 16:09       ` Petr Mladek
2025-11-27 19:44 ` [PATCH v8 19/21] printk: docs: Add comprehensive guidance for per-console loglevels Chris Down
2025-12-12 15:32   ` Petr Mladek
2025-11-27 19:44 ` [PATCH v8 20/21] printk: Deprecate the kernel.printk sysctl interface Chris Down
2025-12-12 15:51   ` Petr Mladek
2025-12-15  9:52     ` Joel Granados
2025-12-15 16:06       ` Petr Mladek
2025-12-17 11:47         ` Joel Granados
2025-12-17 14:33           ` Geert Uytterhoeven
2025-12-17 16:04             ` Steven Rostedt
2025-12-17 20:23               ` Joel Granados
2025-11-27 19:44 ` [PATCH v8 21/21] printk: Purge default_console_loglevel Chris Down
2025-12-12 16:11 ` [PATCH v8 00/21] printk: console: Per-console loglevels Petr Mladek

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=aTwzoSMUFJ2XiSBm@pathway \
    --to=pmladek@suse.com \
    --cc=chris@chrisdown.name \
    --cc=geert@linux-m68k.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=joel.granados@kernel.org \
    --cc=john.ogness@linutronix.de \
    --cc=kernel-team@fb.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=rostedt@goodmis.org \
    --cc=senozhatsky@chromium.org \
    --cc=tony.lindgren@linux.intel.com \
    /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