如何避免在linux内核中删除printk日志

时间:2014-10-16 20:56:34

标签: logging linux-kernel linux-device-driver embedded-linux printk

是否有任何提示或方法可以避免内核日志丢失或日志缓冲区溢出?

我已将日志缓冲区大小增加到最大值,但代码更改不足。我只在高端设备上运行。但是,当我想从我的驱动程序(写入大量日志)中获取完整日志时,我发现有时会删除printk日志。我将printk与KERN_INFO一起使用,通过动态调试(dprintk)启用。

改变我的行为:

--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -55,7 +55,7 @@ void asmlinkage __attribute__((weak)) early_printk(const char *fmt, ...)
 {
 }

-#define __LOG_BUF_LEN  (1 << CONFIG_LOG_BUF_SHIFT)
+#define __LOG_BUF_LEN  (1 << 17)

我用来写入文件的命令:

cat "/proc/kmsg">/sdcard/klog.txt

仅在调试时,如果我的驱动程序性能下降,我可以,但我不想丢弃任何日志。我知道我们不能让工作队列/线程等到打印完成。但是,仍然有任何方法可以保证不会丢弃日志。

2 个答案:

答案 0 :(得分:2)

很简单,只需将“ printk.synchronous = 1 ”添加到内核cmdline。

printk()现在变得完全异步。您可以添加printk.synchronous = 1以使printk()同步。

请参阅补丁“printk:Make printk()完全异步”:

  

目前,printk()有时会等待要打印的消息   控制台,有时它没有(当某些人持有console_sem时   其他过程)。如果printk()抓取console_sem并开始打印   到控制台,它从内核printk缓冲区打印消息,直到   缓冲区是空的。连接串行控制台时,打印速度很慢   因此系统中的其他CPU有足够的时间来追加新的   一个CPU正在打印时发送到缓冲区的消息。因此CPU可以   花费无限的时间在console_unlock()中进行打印。   如果printk()调用,这是特别严重的问题   调用console_unlock()时禁用了中断。

     

在实践中,用户观察到CPU可以花费数十秒   在console_unlock()中打印(通常在启动时数百个   发现了SCSI设备)导致RCU停顿(CPU正在运行)   打印长时间没有达到静止状态),softlockup   报告(打印CPU的IPI不会被提供,因此其他   CPU正在旋转等待打印CPU处理IPI),以及   最终机器死亡(来自摊位和锁定的消息附加   printk缓冲区比我们能够打印更快)。所以这些机器   无法使用连接的串行控制台启动。另一个观察   问题是由于printk缓慢,硬件发现很慢而且udev   在内核设法发现所有连接的HW之前超时。也   在人工压力测试期间,SATA磁盘从系统中消失   因为它的中断时间不长。

     

这个补丁使得printk()完全异步(类似于什么   printk_deferred()直到现在才这样做了)。它将消息附加到内核   printk buffer和wake_up()是一个特殊的专用kthread来做   打印到控制台。这具有始终打印的优点   从可调度的上下文发生,因此我们不会锁定任何   特殊的CPU甚至中断。它还有一个优点   printk()速度很快,因此内核启动不会因速度慢而减慢   串行控制台。这种方法的缺点是在崩溃的情况下   重要消息不会出现在控制台中的可能性更高   输出(我们可能需要工作安排将消息打印到控制台)。   我们通过将printk切换到原始版本来减轻这种风险   如果正在进行oops,则立即打印到控制台的方法。

     

Async printk目前被认为不太可靠   比同步的,所以默认我们保持printk操作   同步模式。有一个printk.synchronous内核参数   允许选择同步/异步模式作为启动参数或稍后启用   用户空间通过sysfs旋钮。

     

printk()预计会在不同条件下工作   不同的场景,包括所有的OOM角落案例   工作人员很忙(例如分配内存),因此printk()使用它自己的   专门印刷kthread,而不是依靠工作队伍(甚至   如果设置了WQ_MEM_RECLAIM位,我们可能会收到延迟   如Tetsuo所述,打印直到workqueue宣布a - &gt; mayday   半田)。

答案 1 :(得分:1)

两种方式:

  1. cat / proc / kmsg&gt;一些文件位置&amp;

  2. 这是更详细的: 由于日志记录过多,请不要使用dmesg缓冲区吗?

  3. A&gt;在您的驱动程序初始化期间,为记录所需大小(大缓冲区)分配单独的缓冲区空间

    B个创建一个单独的函数来记录它my_log_buf(“Debug check point 1”);登录前面提到的缓冲区

    C&gt;提供一个读取系统接口并使用cat / sys /(某些公开的接口)

    读取它