是否有任何提示或方法可以避免内核日志丢失或日志缓冲区溢出?
我已将日志缓冲区大小增加到最大值,但代码更改不足。我只在高端设备上运行。但是,当我想从我的驱动程序(写入大量日志)中获取完整日志时,我发现有时会删除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
仅在调试时,如果我的驱动程序性能下降,我可以,但我不想丢弃任何日志。我知道我们不能让工作队列/线程等到打印完成。但是,仍然有任何方法可以保证不会丢弃日志。
答案 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)
两种方式:
cat / proc / kmsg&gt;一些文件位置&amp;
这是更详细的: 由于日志记录过多,请不要使用dmesg缓冲区吗?
A&gt;在您的驱动程序初始化期间,为记录所需大小(大缓冲区)分配单独的缓冲区空间
B个创建一个单独的函数来记录它my_log_buf(“Debug check point 1”);登录前面提到的缓冲区
C&gt;提供一个读取系统接口并使用cat / sys /(某些公开的接口)
读取它