Re: [PATCH] printk: add cpu id information to printk() output

2023-09-15 Thread Petr Mladek
On Fri 2023-09-15 11:53:13, Greg KH wrote:
> On Fri, Sep 15, 2023 at 04:46:02PM +0800, Enlin Mu wrote:
> > John Ogness  于2023年9月15日周五 16:34写道:
> > >
> > > On 2023-09-15, Enlin Mu  wrote:
> > > > Sometimes we want to print cpu id of printk() messages to consoles
> > > >
> > > > diff --git a/include/linux/threads.h b/include/linux/threads.h
> > > > index c34173e6c5f1..6700bd9a174f 100644
> > > > --- a/include/linux/threads.h
> > > > +++ b/include/linux/threads.h
> > > > @@ -34,6 +34,9 @@
> > > >  #define PID_MAX_LIMIT (CONFIG_BASE_SMALL ? PAGE_SIZE * 8 : \
> > > >   (sizeof(long) > 4 ? 4 * 1024 * 1024 : PID_MAX_DEFAULT))
> > > >
> > > > +#define CPU_ID_SHIFT 23
> > > > +#define CPU_ID_MASK  0xff80
> > >
> > > This only supports 256 CPUs. I think it doesn't make sense to try to
> > > squish CPU and Task IDs into 32 bits.
> > Yes, it is not good way,
> > >
> > > What about introducing a caller_id option to always only print the CPU
> > > ID? Or do you really need Task _and_ CPU?
> >Yes, I need it.Because I need to know which CPU is printing the
> > log, so that I can identify the current system operation, such as load
> > situation and CPU busy/idle status
> 
> The cpu that is printing the log isn't the one that added the log
> message, so I think you will have incorrect data here, right?

We already store some metadata about the caller:

 * All fields are set by the printk code except for @seq, which is
 * set by the ringbuffer code.
 */
struct printk_info {
u64 seq;/* sequence number */
u64 ts_nsec;/* timestamp in nanoseconds */
u16 text_len;   /* length of text message */
u8  facility;   /* syslog facility */
u8  flags:5;/* internal record flags */
u8  level:3;/* syslog level */
u32 caller_id;  /* thread id or processor id */

struct dev_printk_info  dev_info;
};

The 32-bit caller ID is generated using:

static inline u32 printk_caller_id(void)
{
return in_task() ? task_pid_nr(current) :
0x8000 + smp_processor_id();
}

We could add more metadata and always store the CPU ID and something
like:

   [CTXT][ Tpid][  Ccpu]

for example

   [TASK][  T234][C4]
   [ IRQ][ T4567][   C17]
   [SIRQ][T5][C0]
   [ NMI][  T356][  C128]


The biggest problem is that it would change the format of the
ringbuffer so that it would require updating external tools,
working with crashdump, especially crash but there are also
alternative python extensions for gdb.


See below POC of the kernel part. It is not even compile tested. The size
of the buffers is updated by a guess. Comments are not updated, ...

diff --git a/kernel/printk/internal.h b/kernel/printk/internal.h
index 7d4979d5c3ce..e3e0a9fdc0cf 100644
--- a/kernel/printk/internal.h
+++ b/kernel/printk/internal.h
@@ -15,7 +15,7 @@ int devkmsg_sysctl_set_loglvl(struct ctl_table *table, int 
write,
 #ifdef CONFIG_PRINTK
 
 #ifdef CONFIG_PRINTK_CALLER
-#define PRINTK_PREFIX_MAX  48
+#define PRINTK_PREFIX_MAX  64
 #else
 #define PRINTK_PREFIX_MAX  32
 #endif
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 7e0b4dd02398..bb393ccbd5e9 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -621,16 +621,20 @@ static void append_char(char **pp, char *e, char c)
*(*pp)++ = c;
 }
 
+char printk_caller_ctxt_txt[][] = { "TSK", "IRQ", "SIRQ", "NMI"' };
+
 static ssize_t info_print_ext_header(char *buf, size_t size,
 struct printk_info *info)
 {
u64 ts_usec = info->ts_nsec;
-   char caller[20];
+   char caller[40];
 #ifdef CONFIG_PRINTK_CALLER
-   u32 id = info->caller_id;
+   struct printk_caller_info *ci = info->caller_info;
 
-   snprintf(caller, sizeof(caller), ",caller=%c%u",
-id & 0x8000 ? 'C' : 'T', id & ~0x8000);
+   snprintf(caller, sizeof(caller),
+",caller.ctxt=%s,caller.pid=%d,caller.cpu=%d",
+printk_caller_ctxt_txt[ci->ctxt],
+ci->pid,ci->cpu);
 #else
caller[0] = '\0';
 #endif
@@ -996,11 +1000,16 @@ void log_buf_vmcoreinfo_setup(void)
VMCOREINFO_OFFSET(prb_data_blk_lpos, begin);
VMCOREINFO_OFFSET(prb_data_blk_lpos, next);
 
+   VMCOREINFO_STRUCT_SIZE(printk_caller_info);
+   VMCOREINFO_OFFSET(printk_caller_info, ctxt);
+   VMCOREINFO_OFFSET(printk_caller_info, cpu);
+   VMCOREINFO_OFFSET(printk_caller_info, pid);
+
VMCOREINFO_STRUCT_SIZE(printk_info);
VMCOREINFO_OFFSET(printk_info, seq);
VMCOREINFO_OFFSET(printk_info, ts_nsec);
VMCOREINFO_OFFSET(printk_info, text_len);
-   VMCOREINFO_OFFSET(printk_info, caller_id);
+   VMCOREINFO_OFFSET(printk_info, caller_info);
VMCOREINFO_OFFSET(printk_info, dev_info);
 
VMCOREINFO_STRUCT_SIZE(dev_printk_info);
@@ -,7 +1120,7 @@ static unsigned int __init a

RE: [PATCH] printk: add cpu id information to printk() output

2023-09-15 Thread Luck, Tony
> + return in_task() ? task_pid_nr(current) | (smp_processor_id() << 
> CPU_ID_SHIFT) :

There are contexts and CONFIG options around pre-emption where 
smp_processor_id()
will throw a warning. Use raw_smp_processor_id().

-Tony


Re: [PATCH] printk: add cpu id information to printk() output

2023-09-15 Thread Greg KH
On Fri, Sep 15, 2023 at 04:46:02PM +0800, Enlin Mu wrote:
> John Ogness  于2023年9月15日周五 16:34写道:
> >
> > On 2023-09-15, Enlin Mu  wrote:
> > > Sometimes we want to print cpu id of printk() messages to consoles
> > >
> > > diff --git a/include/linux/threads.h b/include/linux/threads.h
> > > index c34173e6c5f1..6700bd9a174f 100644
> > > --- a/include/linux/threads.h
> > > +++ b/include/linux/threads.h
> > > @@ -34,6 +34,9 @@
> > >  #define PID_MAX_LIMIT (CONFIG_BASE_SMALL ? PAGE_SIZE * 8 : \
> > >   (sizeof(long) > 4 ? 4 * 1024 * 1024 : PID_MAX_DEFAULT))
> > >
> > > +#define CPU_ID_SHIFT 23
> > > +#define CPU_ID_MASK  0xff80
> >
> > This only supports 256 CPUs. I think it doesn't make sense to try to
> > squish CPU and Task IDs into 32 bits.
> Yes, it is not good way,
> >
> > What about introducing a caller_id option to always only print the CPU
> > ID? Or do you really need Task _and_ CPU?
>Yes, I need it.Because I need to know which CPU is printing the
> log, so that I can identify the current system operation, such as load
> situation and CPU busy/idle status

The cpu that is printing the log isn't the one that added the log
message, so I think you will have incorrect data here, right?

thanks,

greg k-h


Re: [PATCH] printk: add cpu id information to printk() output

2023-09-15 Thread Greg KH
On Fri, Sep 15, 2023 at 03:40:34PM +0800, Enlin Mu wrote:
> From: Enlin Mu 
> 
> Sometimes we want to print cpu id of printk() messages to consoles

This is rejected every few years.  What has changes from the previous
times this was sent?

And why can't you use trace_printk()?

thanks,

greg k-h


Re: [PATCH] printk: add cpu id information to printk() output

2023-09-15 Thread Enlin Mu
John Ogness  于2023年9月15日周五 16:34写道:
>
> On 2023-09-15, Enlin Mu  wrote:
> > Sometimes we want to print cpu id of printk() messages to consoles
> >
> > diff --git a/include/linux/threads.h b/include/linux/threads.h
> > index c34173e6c5f1..6700bd9a174f 100644
> > --- a/include/linux/threads.h
> > +++ b/include/linux/threads.h
> > @@ -34,6 +34,9 @@
> >  #define PID_MAX_LIMIT (CONFIG_BASE_SMALL ? PAGE_SIZE * 8 : \
> >   (sizeof(long) > 4 ? 4 * 1024 * 1024 : PID_MAX_DEFAULT))
> >
> > +#define CPU_ID_SHIFT 23
> > +#define CPU_ID_MASK  0xff80
>
> This only supports 256 CPUs. I think it doesn't make sense to try to
> squish CPU and Task IDs into 32 bits.
Yes, it is not good way,
>
> What about introducing a caller_id option to always only print the CPU
> ID? Or do you really need Task _and_ CPU?
   Yes, I need it.Because I need to know which CPU is printing the
log, so that I can identify the current system operation, such as load
situation and CPU busy/idle status
>
> John Ogness

Thanks

Enlin


Re: [PATCH] printk: add cpu id information to printk() output

2023-09-15 Thread John Ogness
On 2023-09-15, Enlin Mu  wrote:
> Sometimes we want to print cpu id of printk() messages to consoles
>
> diff --git a/include/linux/threads.h b/include/linux/threads.h
> index c34173e6c5f1..6700bd9a174f 100644
> --- a/include/linux/threads.h
> +++ b/include/linux/threads.h
> @@ -34,6 +34,9 @@
>  #define PID_MAX_LIMIT (CONFIG_BASE_SMALL ? PAGE_SIZE * 8 : \
>   (sizeof(long) > 4 ? 4 * 1024 * 1024 : PID_MAX_DEFAULT))
>  
> +#define CPU_ID_SHIFT 23
> +#define CPU_ID_MASK  0xff80

This only supports 256 CPUs. I think it doesn't make sense to try to
squish CPU and Task IDs into 32 bits.

What about introducing a caller_id option to always only print the CPU
ID? Or do you really need Task _and_ CPU?

John Ogness


[PATCH] printk: add cpu id information to printk() output

2023-09-15 Thread Enlin Mu
From: Enlin Mu 

Sometimes we want to print cpu id of printk() messages to consoles

Signed-off-by: Enlin Mu 
---
 include/linux/threads.h |  3 +++
 kernel/printk/printk.c  | 18 +-
 2 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/include/linux/threads.h b/include/linux/threads.h
index c34173e6c5f1..6700bd9a174f 100644
--- a/include/linux/threads.h
+++ b/include/linux/threads.h
@@ -34,6 +34,9 @@
 #define PID_MAX_LIMIT (CONFIG_BASE_SMALL ? PAGE_SIZE * 8 : \
(sizeof(long) > 4 ? 4 * 1024 * 1024 : PID_MAX_DEFAULT))
 
+#define CPU_ID_SHIFT 23
+#define CPU_ID_MASK  0xff80
+
 /*
  * Define a minimum number of pids per cpu.  Heuristically based
  * on original pid max of 32k for 32 cpus.  Also, increase the
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 7e0b4dd02398..f3f3ca89b251 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -629,8 +629,12 @@ static ssize_t info_print_ext_header(char *buf, size_t 
size,
 #ifdef CONFIG_PRINTK_CALLER
u32 id = info->caller_id;
 
-   snprintf(caller, sizeof(caller), ",caller=%c%u",
-id & 0x8000 ? 'C' : 'T', id & ~0x8000);
+   if (id&0x8000)
+   snprintf(caller, sizeof(caller), ",caller=C%u",
+   id & ~0x8000);
+   else
+   snprintf(caller, sizeof(caller), ",caller=T%uC%u",
+   id & ~CPU_ID_MASK, id >> CPU_ID_SHIFT);
 #else
caller[0] = '\0';
 #endif
@@ -1333,8 +1337,12 @@ static size_t print_caller(u32 id, char *buf)
 {
char caller[12];
 
-   snprintf(caller, sizeof(caller), "%c%u",
-id & 0x8000 ? 'C' : 'T', id & ~0x8000);
+   if (id & 0x8000)
+   snprintf(caller, sizeof(caller), "C%u",
+   id & ~0x8000);
+   else
+   snprintf(caller, sizeof(caller), "T%uC%u",
+   id & ~CPU_ID_MASK, id >> CPU_ID_SHIFT);
return sprintf(buf, "[%6s]", caller);
 }
 #else
@@ -2069,7 +2077,7 @@ static inline void printk_delay(int level)
 
 static inline u32 printk_caller_id(void)
 {
-   return in_task() ? task_pid_nr(current) :
+   return in_task() ? task_pid_nr(current) | (smp_processor_id() << 
CPU_ID_SHIFT) :
0x8000 + smp_processor_id();
 }
 
-- 
2.25.1