[PATCH net-next v5 1/4] printk: Add execution context (task name/CPU) to printk_info

Breno Leitao posted 4 patches 1 week, 4 days ago
There is a newer version of this series
[PATCH net-next v5 1/4] printk: Add execution context (task name/CPU) to printk_info
Posted by Breno Leitao 1 week, 4 days ago
Extend struct printk_info to include the task name, pid, and CPU
number where printk messages originate. This information is captured
at vprintk_store() time and propagated through printk_message to
nbcon_write_context, making it available to nbcon console drivers.

This is useful for consoles like netconsole that want to include
execution context in their output, allowing correlation of messages
with specific tasks and CPUs regardless of where the console driver
actually runs.

The feature is controlled by CONFIG_PRINTK_EXECUTION_CTX, which is
automatically selected by CONFIG_NETCONSOLE_DYNAMIC. When disabled,
the helper functions compile to no-ops with no overhead.

Suggested-by: John Ogness <john.ogness@linutronix.de>
Signed-off-by: Breno Leitao <leitao@debian.org>
Signed-off-by: Petr Mladek <pmladek@suse.com>
---
 drivers/net/Kconfig               |  2 ++
 include/linux/console.h           |  8 ++++++
 kernel/printk/internal.h          |  8 ++++++
 kernel/printk/nbcon.c             | 16 ++++++++++++
 kernel/printk/printk.c            | 54 ++++++++++++++++++++++++++++++++++++++-
 kernel/printk/printk_ringbuffer.h |  5 ++++
 lib/Kconfig.debug                 | 20 +++++++++++++++
 7 files changed, 112 insertions(+), 1 deletion(-)

diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 9c7953f8e6377..356c70be868ff 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -341,6 +341,8 @@ config NETCONSOLE_DYNAMIC
 	bool "Dynamic reconfiguration of logging targets"
 	depends on NETCONSOLE && SYSFS && CONFIGFS_FS && \
 			!(NETCONSOLE=y && CONFIGFS_FS=m)
+	select PRINTK_EXECUTION_CTX
+	select CONSOLE_HAS_EXECUTION_CTX
 	help
 	  This option enables the ability to dynamically reconfigure target
 	  parameters (interface, IP addresses, port numbers, MAC addresses)
diff --git a/include/linux/console.h b/include/linux/console.h
index fc9f5c5c1b04c..cc5dc3bf58b60 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -298,12 +298,20 @@ struct nbcon_context {
  * @outbuf:		Pointer to the text buffer for output
  * @len:		Length to write
  * @unsafe_takeover:	If a hostile takeover in an unsafe state has occurred
+ * @cpu:		CPU on which the message was generated
+ * @pid:		PID of the task that generated the message
+ * @comm:		Name of the task that generated the message
  */
 struct nbcon_write_context {
 	struct nbcon_context	__private ctxt;
 	char			*outbuf;
 	unsigned int		len;
 	bool			unsafe_takeover;
+#ifdef CONFIG_PRINTK_EXECUTION_CTX
+	int			cpu;
+	pid_t			pid;
+	char			comm[TASK_COMM_LEN];
+#endif
 };
 
 /**
diff --git a/kernel/printk/internal.h b/kernel/printk/internal.h
index 5f5f626f42794..5fdea56827564 100644
--- a/kernel/printk/internal.h
+++ b/kernel/printk/internal.h
@@ -281,12 +281,20 @@ struct printk_buffers {
  *		nothing to output and this record should be skipped.
  * @seq:	The sequence number of the record used for @pbufs->outbuf.
  * @dropped:	The number of dropped records from reading @seq.
+ * @cpu:	CPU on which the message was generated.
+ * @pid:	PID of the task that generated the message
+ * @comm:	Name of the task that generated the message.
  */
 struct printk_message {
 	struct printk_buffers	*pbufs;
 	unsigned int		outbuf_len;
 	u64			seq;
 	unsigned long		dropped;
+#ifdef CONFIG_PRINTK_EXECUTION_CTX
+	int			cpu;
+	pid_t			pid;
+	char			comm[TASK_COMM_LEN];
+#endif
 };
 
 bool printk_get_next_message(struct printk_message *pmsg, u64 seq,
diff --git a/kernel/printk/nbcon.c b/kernel/printk/nbcon.c
index 32fc12e536752..f6d22510fdc3a 100644
--- a/kernel/printk/nbcon.c
+++ b/kernel/printk/nbcon.c
@@ -946,6 +946,20 @@ void nbcon_reacquire_nobuf(struct nbcon_write_context *wctxt)
 }
 EXPORT_SYMBOL_GPL(nbcon_reacquire_nobuf);
 
+#ifdef CONFIG_PRINTK_EXECUTION_CTX
+static void wctxt_load_execution_ctx(struct nbcon_write_context *wctxt,
+				     struct printk_message *pmsg)
+{
+	wctxt->cpu = pmsg->cpu;
+	wctxt->pid = pmsg->pid;
+	memcpy(wctxt->comm, pmsg->comm, sizeof(wctxt->comm));
+	static_assert(sizeof(wctxt->comm) == sizeof(pmsg->comm));
+}
+#else
+static void wctxt_load_execution_ctx(struct nbcon_write_context *wctxt,
+				     struct printk_message *pmsg) {}
+#endif
+
 /**
  * nbcon_emit_next_record - Emit a record in the acquired context
  * @wctxt:	The write context that will be handed to the write function
@@ -1048,6 +1062,8 @@ static bool nbcon_emit_next_record(struct nbcon_write_context *wctxt, bool use_a
 	/* Initialize the write context for driver callbacks. */
 	nbcon_write_context_set_buf(wctxt, &pmsg.pbufs->outbuf[0], pmsg.outbuf_len);
 
+	wctxt_load_execution_ctx(wctxt, &pmsg);
+
 	if (use_atomic)
 		con->write_atomic(con, wctxt);
 	else
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 1d765ad242b82..cf6b528610366 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -2131,11 +2131,39 @@ static inline void printk_delay(int level)
 	}
 }
 
+#define CALLER_ID_MASK 0x80000000
+
 static inline u32 printk_caller_id(void)
 {
 	return in_task() ? task_pid_nr(current) :
-		0x80000000 + smp_processor_id();
+		CALLER_ID_MASK + smp_processor_id();
+}
+
+#ifdef CONFIG_PRINTK_EXECUTION_CTX
+/* Store the opposite info than caller_id. */
+static u32 printk_caller_id2(void)
+{
+	return !in_task() ? task_pid_nr(current) :
+		CALLER_ID_MASK + smp_processor_id();
+}
+
+static pid_t printk_info_get_pid(const struct printk_info *info)
+{
+	u32 caller_id = info->caller_id;
+	u32 caller_id2 = info->caller_id2;
+
+	return caller_id & CALLER_ID_MASK ? caller_id2 : caller_id;
+}
+
+static int printk_info_get_cpu(const struct printk_info *info)
+{
+	u32 caller_id = info->caller_id;
+	u32 caller_id2 = info->caller_id2;
+
+	return ((caller_id & CALLER_ID_MASK ?
+		 caller_id : caller_id2) & ~CALLER_ID_MASK);
 }
+#endif
 
 /**
  * printk_parse_prefix - Parse level and control flags.
@@ -2213,6 +2241,28 @@ static u16 printk_sprint(char *text, u16 size, int facility,
 	return text_len;
 }
 
+#ifdef CONFIG_PRINTK_EXECUTION_CTX
+static void printk_store_execution_ctx(struct printk_info *info)
+{
+	info->caller_id2 = printk_caller_id2();
+	get_task_comm(info->comm, current);
+}
+
+static void pmsg_load_execution_ctx(struct printk_message *pmsg,
+				    const struct printk_info *info)
+{
+	pmsg->cpu = printk_info_get_cpu(info);
+	pmsg->pid = printk_info_get_pid(info);
+	memcpy(pmsg->comm, info->comm, sizeof(pmsg->comm));
+	static_assert(sizeof(pmsg->comm) == sizeof(info->comm));
+}
+#else
+static void printk_store_execution_ctx(struct printk_info *info) {}
+
+static void pmsg_load_execution_ctx(struct printk_message *pmsg,
+				    const struct printk_info *info) {}
+#endif
+
 __printf(4, 0)
 int vprintk_store(int facility, int level,
 		  const struct dev_printk_info *dev_info,
@@ -2320,6 +2370,7 @@ int vprintk_store(int facility, int level,
 	r.info->caller_id = caller_id;
 	if (dev_info)
 		memcpy(&r.info->dev_info, dev_info, sizeof(r.info->dev_info));
+	printk_store_execution_ctx(r.info);
 
 	/* A message without a trailing newline can be continued. */
 	if (!(flags & LOG_NEWLINE))
@@ -3002,6 +3053,7 @@ bool printk_get_next_message(struct printk_message *pmsg, u64 seq,
 	pmsg->seq = r.info->seq;
 	pmsg->dropped = r.info->seq - seq;
 	force_con = r.info->flags & LOG_FORCE_CON;
+	pmsg_load_execution_ctx(pmsg, r.info);
 
 	/*
 	 * Skip records that are not forced to be printed on consoles and that
diff --git a/kernel/printk/printk_ringbuffer.h b/kernel/printk/printk_ringbuffer.h
index 4ef81349d9fbe..1651b53ece34f 100644
--- a/kernel/printk/printk_ringbuffer.h
+++ b/kernel/printk/printk_ringbuffer.h
@@ -23,6 +23,11 @@ struct printk_info {
 	u8	flags:5;	/* internal record flags */
 	u8	level:3;	/* syslog level */
 	u32	caller_id;	/* thread id or processor id */
+#ifdef CONFIG_PRINTK_EXECUTION_CTX
+	u32	caller_id2;	/* caller_id complement */
+	/* name of the task that generated the message */
+	char	comm[TASK_COMM_LEN];
+#endif
 
 	struct dev_printk_info	dev_info;
 };
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index ba36939fda79b..57f91ee10b8e6 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -35,6 +35,26 @@ config PRINTK_CALLER
 	  no option to enable/disable at the kernel command line parameter or
 	  sysfs interface.
 
+config CONSOLE_HAS_EXECUTION_CTX
+	bool
+	help
+	  Selected by console drivers that support execution context
+	  (task name/CPU) in their output. This enables PRINTK_EXECUTION_CTX
+	  to provide the necessary infrastructure.
+
+config PRINTK_EXECUTION_CTX
+	bool "Include execution context (task/CPU) in printk messages"
+	depends on PRINTK && CONSOLE_HAS_EXECUTION_CTX
+	default CONSOLE_HAS_EXECUTION_CTX
+	help
+	  This option extends struct printk_info to include extra execution
+	  context in printk, such as task name and CPU number from where the
+	  message originated. This is useful for correlating printk messages
+	  with specific execution contexts.
+
+	  This is automatically enabled when a console driver that supports
+	  execution context is selected.
+
 config STACKTRACE_BUILD_ID
 	bool "Show build ID information in stacktraces"
 	depends on PRINTK

-- 
2.47.3
Re: [PATCH net-next v5 1/4] printk: Add execution context (task name/CPU) to printk_info
Posted by Jakub Kicinski 1 week, 1 day ago
On Wed, 28 Jan 2026 06:17:37 -0800 Breno Leitao wrote:
> +config CONSOLE_HAS_EXECUTION_CTX
> +	bool
> +	help
> +	  Selected by console drivers that support execution context
> +	  (task name/CPU) in their output. This enables PRINTK_EXECUTION_CTX
> +	  to provide the necessary infrastructure.
> +
> +config PRINTK_EXECUTION_CTX
> +	bool "Include execution context (task/CPU) in printk messages"
> +	depends on PRINTK && CONSOLE_HAS_EXECUTION_CTX
> +	default CONSOLE_HAS_EXECUTION_CTX

AFAIU the double-symbol thing serves no practical purpose?
If none of the console drivers uses the metadata what would be the
point of capturing it?

Conversely if some console driver wants this data there's no option 
for the user to disable it.

AFAICT this patch should only add one invisible symbol for capturing
the context and have netcons enable it. I don't see a reason at this
stage to prompt users with netcons disabled whether they want
PRINTK_EXECUTION_CTX
-- 
pw-bot: cr
Re: [PATCH net-next v5 1/4] printk: Add execution context (task name/CPU) to printk_info
Posted by Breno Leitao 6 days, 6 hours ago
Hello Jakub,

On Fri, Jan 30, 2026 at 05:32:43PM -0800, Jakub Kicinski wrote:
> On Wed, 28 Jan 2026 06:17:37 -0800 Breno Leitao wrote:
> > +config CONSOLE_HAS_EXECUTION_CTX
> > +	bool
> > +	help
> > +	  Selected by console drivers that support execution context
> > +	  (task name/CPU) in their output. This enables PRINTK_EXECUTION_CTX
> > +	  to provide the necessary infrastructure.
> > +
> > +config PRINTK_EXECUTION_CTX
> > +	bool "Include execution context (task/CPU) in printk messages"
> > +	depends on PRINTK && CONSOLE_HAS_EXECUTION_CTX
> > +	default CONSOLE_HAS_EXECUTION_CTX
>
> AFAIU the double-symbol thing serves no practical purpose?
>
> If none of the console drivers uses the metadata what would be the
> point of capturing it?
>
> Conversely if some console driver wants this data there's no option
> for the user to disable it.
>
> AFAICT this patch should only add one invisible symbol for capturing
> the context and have netcons enable it.

The two-symbol design establishes a clear separation between what console
drivers require and how the printk core implements it.

This approach was discussed here:
https://lore.kernel.org/all/87eco09hgb.fsf@jogness.linutronix.de/

> I don't see a reason at this
> stage to prompt users with netcons disabled whether they want
> PRINTK_EXECUTION_CTX

Users won't see a prompt when netconsole is disabled. Since
CONSOLE_HAS_EXECUTION_CTX is only selected when NETCONSOLE_DYNAMIC is
enabled, PRINTK_EXECUTION_CTX will be automatically deselected without
prompting. Additionally, CONSOLE_HAS_EXECUTION_CTX is a hidden symbol that
cannot be manually forced.

That said, I'm open to making PRINTK_EXECUTION_CTX invisible as well,
given it is behaving like one already.
Re: [PATCH net-next v5 1/4] printk: Add execution context (task name/CPU) to printk_info
Posted by Jakub Kicinski 5 days, 18 hours ago
On Mon, 2 Feb 2026 03:49:32 -0800 Breno Leitao wrote:
> > I don't see a reason at this
> > stage to prompt users with netcons disabled whether they want
> > PRINTK_EXECUTION_CTX  
> 
> Users won't see a prompt when netconsole is disabled. Since
> CONSOLE_HAS_EXECUTION_CTX is only selected when NETCONSOLE_DYNAMIC is
> enabled, PRINTK_EXECUTION_CTX will be automatically deselected without
> prompting. Additionally, CONSOLE_HAS_EXECUTION_CTX is a hidden symbol that
> cannot be manually forced.
> 
> That said, I'm open to making PRINTK_EXECUTION_CTX invisible as well,
> given it is behaving like one already.

I see, it doesn't prompt because netconsole 'selects' both.
Why y'all think this is clean I'm not sure, but yes, if you want
two symbols please make them both invisible. netconsole should
not have to select a printk symbol.
Re: [PATCH net-next v5 1/4] printk: Add execution context (task name/CPU) to printk_info
Posted by John Ogness 1 week, 4 days ago
On 2026-01-28, Breno Leitao <leitao@debian.org> wrote:
> Extend struct printk_info to include the task name, pid, and CPU
> number where printk messages originate. This information is captured
> at vprintk_store() time and propagated through printk_message to
> nbcon_write_context, making it available to nbcon console drivers.
>
> This is useful for consoles like netconsole that want to include
> execution context in their output, allowing correlation of messages
> with specific tasks and CPUs regardless of where the console driver
> actually runs.
>
> The feature is controlled by CONFIG_PRINTK_EXECUTION_CTX, which is
> automatically selected by CONFIG_NETCONSOLE_DYNAMIC. When disabled,
> the helper functions compile to no-ops with no overhead.
>
> Suggested-by: John Ogness <john.ogness@linutronix.de>
> Signed-off-by: Breno Leitao <leitao@debian.org>
> Signed-off-by: Petr Mladek <pmladek@suse.com>

Reviewed-by: John Ogness <john.ogness@linutronix.de>

Thanks!
Re: [PATCH net-next v5 1/4] printk: Add execution context (task name/CPU) to printk_info
Posted by Breno Leitao 1 week, 2 days ago
On Wed, Jan 28, 2026 at 03:48:16PM +0106, John Ogness wrote:
> On 2026-01-28, Breno Leitao <leitao@debian.org> wrote:
> > Extend struct printk_info to include the task name, pid, and CPU
> > number where printk messages originate. This information is captured
> > at vprintk_store() time and propagated through printk_message to
> > nbcon_write_context, making it available to nbcon console drivers.
> >
> > This is useful for consoles like netconsole that want to include
> > execution context in their output, allowing correlation of messages
> > with specific tasks and CPUs regardless of where the console driver
> > actually runs.
> >
> > The feature is controlled by CONFIG_PRINTK_EXECUTION_CTX, which is
> > automatically selected by CONFIG_NETCONSOLE_DYNAMIC. When disabled,
> > the helper functions compile to no-ops with no overhead.
> >
> > Suggested-by: John Ogness <john.ogness@linutronix.de>
> > Signed-off-by: Breno Leitao <leitao@debian.org>
> > Signed-off-by: Petr Mladek <pmladek@suse.com>
> 
> Reviewed-by: John Ogness <john.ogness@linutronix.de>

Thank you for the review. To confirm, it is acceptable to queue this for
the next netdev version, isn't it?
Re: [PATCH net-next v5 1/4] printk: Add execution context (task name/CPU) to printk_info
Posted by John Ogness 1 week, 2 days ago
On 2026-01-30, Breno Leitao <leitao@debian.org> wrote:
>> > Suggested-by: John Ogness <john.ogness@linutronix.de>
>> > Signed-off-by: Breno Leitao <leitao@debian.org>
>> > Signed-off-by: Petr Mladek <pmladek@suse.com>
>> 
>> Reviewed-by: John Ogness <john.ogness@linutronix.de>
>
> Thank you for the review. To confirm, it is acceptable to queue this for
> the next netdev version, isn't it?

From me, yes. I would be happy to see it in netdev-next and be included
in the next merge window.

John
Re: [PATCH net-next v5 1/4] printk: Add execution context (task name/CPU) to printk_info
Posted by Petr Mladek 1 week, 2 days ago
On Fri 2026-01-30 01:01:11, Breno Leitao wrote:
> On Wed, Jan 28, 2026 at 03:48:16PM +0106, John Ogness wrote:
> > On 2026-01-28, Breno Leitao <leitao@debian.org> wrote:
> > > Extend struct printk_info to include the task name, pid, and CPU
> > > number where printk messages originate. This information is captured
> > > at vprintk_store() time and propagated through printk_message to
> > > nbcon_write_context, making it available to nbcon console drivers.
> > >
> > > This is useful for consoles like netconsole that want to include
> > > execution context in their output, allowing correlation of messages
> > > with specific tasks and CPUs regardless of where the console driver
> > > actually runs.
> > >
> > > The feature is controlled by CONFIG_PRINTK_EXECUTION_CTX, which is
> > > automatically selected by CONFIG_NETCONSOLE_DYNAMIC. When disabled,
> > > the helper functions compile to no-ops with no overhead.
> > >
> > > Suggested-by: John Ogness <john.ogness@linutronix.de>
> > > Signed-off-by: Breno Leitao <leitao@debian.org>
> > > Signed-off-by: Petr Mladek <pmladek@suse.com>
> > 
> > Reviewed-by: John Ogness <john.ogness@linutronix.de>
> 
> Thank you for the review. To confirm, it is acceptable to queue this for
> the next netdev version, isn't it?

Go on with it. At least I do not have anything against it. :-)

Best Regards,
Petr