6

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

我可以使用printk函数sched.c吗?

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

4

4 回答 4

8

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

如果您看到的错误没有发生,请经常考虑使用BUG()orBUG_ON(cond)代替。这些是有条件的错误消息,不应该像无条件的那样经常发生printk

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

于 2013-01-11T22:30:15.577 回答
2

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

于 2014-02-24T02:28:03.923 回答
2

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

您可以使用lttng2 记录到用户空间,也可以修补实现printk_sched以使用静态分配的缓冲区池,该缓冲区可以在一个滴答内使用。

于 2013-03-28T17:47:26.453 回答
0

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

尝试dmesg在 shell 中使用来跟踪你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 }

编辑

您可以尝试printk1000 次而不是每次。

于 2013-01-11T22:31:18.280 回答