add support show process information on printks
authorHuang, Tao <huangtao@rock-chips.com>
Tue, 2 Jun 2015 11:09:35 +0000 (19:09 +0800)
committerHuang, Tao <huangtao@rock-chips.com>
Wed, 3 Jun 2015 09:40:01 +0000 (17:40 +0800)
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
kernel/printk.c
lib/Kconfig.debug

index 7d9dc9ad97f653ec084e33346564cf0b213a81c9..7c36e3eb7a543d3f7cda8af15f6a52d45faeba77 100644 (file)
@@ -212,6 +212,12 @@ struct log {
        u8 facility;            /* syslog facility */
        u8 flags:5;             /* internal record flags */
        u8 level:3;             /* syslog level */
+#ifdef CONFIG_PRINTK_PROCESS
+       char process[16];       /* process name */
+       pid_t pid;              /* process id */
+       u8 cpu;                 /* cpu id */
+       u8 in_interrupt;        /* interrupt context */
+#endif
 };
 
 /*
@@ -245,7 +251,11 @@ static enum log_flags console_prev;
 static u64 clear_seq;
 static u32 clear_idx;
 
+#ifdef CONFIG_PRINTK_PROCESS
+#define PREFIX_MAX             48
+#else
 #define PREFIX_MAX             32
+#endif
 #define LOG_LINE_MAX           1024 - PREFIX_MAX
 
 /* record buffer */
@@ -306,6 +316,25 @@ static u32 log_next(u32 idx)
        return idx + msg->len;
 }
 
+#ifdef CONFIG_PRINTK_PROCESS
+static bool printk_process = 1;
+static size_t print_process(const struct log *msg, char *buf)
+{
+       if (!printk_process)
+               return 0;
+
+       if (!buf)
+               return snprintf(NULL, 0, "%c[%1d:%15s:%5d] ", ' ', 0, " ", 0);
+
+       return sprintf(buf, "%c[%1d:%15s:%5d] ",
+                       msg->in_interrupt ? 'I' : ' ',
+                       msg->cpu,
+                       msg->process,
+                       msg->pid);
+}
+module_param_named(process, printk_process, bool, S_IRUGO | S_IWUSR);
+#endif
+
 #ifdef CONFIG_RK_LAST_LOG
 extern void rk_last_log_text(char *text, size_t size);
 static char rk_text[1024];
@@ -368,6 +397,16 @@ static void log_store(int facility, int level,
        memset(log_dict(msg) + dict_len, 0, pad_len);
        msg->len = sizeof(struct log) + text_len + dict_len + pad_len;
 
+#ifdef CONFIG_PRINTK_PROCESS
+       if (printk_process) {
+               strncpy(msg->process, current->comm, sizeof(msg->process)-1);
+               msg->process[sizeof(msg->process) - 1] = '\0';
+               msg->pid = task_pid_nr(current);
+               msg->cpu = smp_processor_id();
+               msg->in_interrupt = in_interrupt() ? 1 : 0;
+       }
+#endif
+
 #ifdef CONFIG_RK_LAST_LOG
        size = msg_print_text(msg, msg->flags, true, rk_text, sizeof(rk_text));
        rk_last_log_text(rk_text, size);
@@ -918,6 +957,9 @@ static size_t print_prefix(const struct log *msg, bool syslog, char *buf)
        }
 
        len += print_time(msg->ts_nsec, buf ? buf + len : NULL);
+#ifdef CONFIG_PRINTK_PROCESS
+       len += print_process(msg, buf ? buf + len : NULL);
+#endif
        return len;
 }
 
@@ -1486,6 +1528,10 @@ static size_t cont_print_text(char *text, size_t size)
 
        if (cont.cons == 0 && (console_prev & LOG_NEWLINE)) {
                textlen += print_time(cont.ts_nsec, text);
+#ifdef CONFIG_PRINTK_PROCESS
+               *(text+textlen) = ' ';
+               textlen += print_process(NULL, NULL);
+#endif
                size -= textlen;
        }
 
index d317c1ad62ab0c747e9d77dfb8eda6d813581397..d3c6363076efd3e701015022cdff9d25cc88028c 100644 (file)
@@ -14,6 +14,13 @@ config PRINTK_TIME
          The behavior is also controlled by the kernel command line
          parameter printk.time=1. See Documentation/kernel-parameters.txt
 
+config PRINTK_PROCESS
+       bool "Show process information on printks"
+       depends on PRINTK
+       help
+         Selecting this option causes process to be
+         included in printk output. Or add printk.process=1 at boot-time.
+
 config DEFAULT_MESSAGE_LOGLEVEL
        int "Default message log level (1-7)"
        range 1 7