在内核中使用printk

时间:2013-01-11 22:26:32

标签: c linux linux-kernel kernel

我正在尝试实现自己的新schedule()。我想调试我的代码。

我可以在printk中使用sched.c功能吗?

我使用printk但它不起作用。我错过了什么?

4 个答案:

答案 0 :(得分:7)

你知道调用schedule()的频率是多少?它可能比计算机可以将打印缓冲区刷新到日志更快。我建议使用另一种调试方法。例如,通过将kernel.syms文件作为符号表加载并设置断点,在QEMU中运行内核并使用远程GDB。其他虚拟化软件提供类似功能。或者以手动方式完成并遍历您的代码。在中断处理程序中使用printk通常是一个坏主意(除非您即将恐慌或停顿)。

如果您看到的错误没有发生,通常会考虑使用BUG()BUG_ON(cond)。这些是条件错误消息,不应该像非条件printk

那样频繁发生

编辑schedule()函数本身通常是一个坏主意(除非你想支持多个运行队列等...)。相反,修改调度程序类会更好,更容易。查看CFS调度程序的代码来执行此操作。如果你想完成别的事情,我可以提供更好的建议。

答案 1 :(得分:2)

在持有runqueue锁的同时调用printk是不安全的。引入了一个特殊函数printk_sched,以便在持有runqueue锁(https://lkml.org/lkml/2012/3/13/13)时有一个使用printk的机制。不幸的是,它只能在一个勾号内打印一条消息(并且在保持运行队列锁定时不能有多个勾号,因为中断被禁用)。这是因为内部缓冲区用于保存消息。

您可以使用lttng2来记录用户空间,也可以修补printk_sched的实现,以使用静态分配的缓冲池,这些缓冲区可以在刻度线内使用。

答案 2 :(得分:2)

试试trace_printk()printk()有太多的开销,并且在之前的schedule()调用完成之前会再次调用printk()。这会创建一个实时锁定。 这是一篇很好的文章:https://lwn.net/Articles/365835/

答案 3 :(得分:0)

这取决于,基本上它应该可以正常工作。

尝试在shell中使用dmesg跟踪你的​​printk,如果它不存在,你显然没有调用它。

2396         if (p->mm && printk_ratelimit()) {
2397                 printk(KERN_INFO "process %d (%s) no longer affine to cpu%d\n",
2398                                 task_pid_nr(p), p->comm, cpu);
2399         }
2400 
2401         return dest_cpu;
2402 }

sched.c中有printk部分不起作用的部分,例如

1660 static int double_lock_balance(struct rq *this_rq, struct rq *busiest)
1661 {
1662         if (unlikely(!irqs_disabled())) {
1663                 /* printk() doesn't work good under rq->lock */
1664                 raw_spin_unlock(&this_rq->lock);
1665                 BUG_ON(1);
1666         }
1667 
1668         return _double_lock_balance(this_rq, busiest);
1669 }

修改

你可以尝试printk一次1000次,而不是每次。