user1967799
user1967799

Reputation: 61

Use printk in kernel

I am trying to implement my own new schedule(). I want to debug my code.

Can I use printk function in sched.c?

I used printk but it doesn't work. What did I miss?

Upvotes: 6

Views: 2822

Answers (4)

nico
nico

Reputation: 9736

Try trace_printk(). printk() has too much of an overhead and schedule() gets called again before previous printk() calls finish. This creates a live lock. Here is a good article about it: https://lwn.net/Articles/365835/

Upvotes: 2

brietz
brietz

Reputation: 61

It's not safe to call printk while holding the runqueue lock. A special function printk_sched was introduced in order to have a mechanism to use printk when holding the runqueue lock (https://lkml.org/lkml/2012/3/13/13). Unfortunatly it can just print one message within a tick (and there cannot be more than one tick when holding the run queue lock because interrupts are disabled). This is because an internal buffer is used to save the message.

You can either use lttng2 for logging to user space or patch the implementation of printk_sched to use a statically allocated pool of buffers that can be used within a tick.

Upvotes: 2

Jesus Ramos
Jesus Ramos

Reputation: 23268

Do you know how often schedule() is called? It's probably called faster than your computer can flush the print buffer to the log. I would suggest using another method of debugging. For instance running your kernel in QEMU and using remote GDB by loading the kernel.syms file as a symbol table and setting a breakpoint. Other virtualization software offers similar features. Or do it the manual way and walk through your code. Using printk in interrupt handlers is typically a bad idea (unless you're about to panic or stall).

If the error you are seeing doesn't happen often think of using BUG() or BUG_ON(cond) instead. These do conditional error messages and shouldn't happen as often as a non-conditional printk

Editing the schedule() function itself is typically a bad idea (unless you want to support multiple run queue's etc...). It's much better and easier to instead modify a scheduler class. Look at the code of the CFS scheduler to do this. If you want to accomplish something else I can give better advice.

Upvotes: 8

0x90
0x90

Reputation: 40982

It depends, basically it should be work fine.

try to use dmesg in shell to trace your printk if it is not there you apparently didn't invoked it.

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 }

there is a sections in sched.c that printk doesn't work e.g.

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 }

EDIT

you may try to printk once in 1000 times instead of each time.

Upvotes: 0

Related Questions