2

I am developing a kernel module, and I need to get an approximate value of the CPU time consumed by some process (iterating the processes is not an issue). Specifically, I want the same behavior provided by the libc clock or the times syscall. I tried calling do_sys_times but seems it's not exported (undefined symbol when compiled).

Is there a way to call times inside a kernel module? Are there any other alternatives?

MEE
  • 2,114
  • 17
  • 21
  • Possible duplicate of http://stackoverflow.com/questions/13552536/get-current-time-in-seconds-in-kernel-module – Atsby Apr 07 '15 at 23:59
  • It is not a duplicate. I want the elapsed per-process CPU clock ticks (see man 2 times). The post you linked to asked for the wallclock time in seconds. – MEE Apr 08 '15 at 00:03
  • Ah I think I see now. Maybe you can try reading this information out of somewhere in /proc as a quick hack (assuming you can access files from inside a kernel module). – Atsby Apr 08 '15 at 00:06
  • Kernel modules typically do not care about processes. Why can't you call `times()` from userspace? What is the actual problem you're trying to solve? – CL. Apr 08 '15 at 07:52
  • I cannot control the processes. The module needs to monitor the ticks consumed by arbitrary processes whenever they leave the scheduler. – MEE Apr 08 '15 at 11:24

1 Answers1

1

If you want precisely measure times between some events in kernel (like context switching), you need some tracer, like SystemTap. From kernel module you may directly bind probes through various tracing and profiling subsystems like ftrace, perf or kprobes.

Here is an example which dumps message to kernel log when context is switched:

#include <linux/sched.h>
#include <linux/module.h>
#include <linux/printk.h>
#include <linux/tracepoint.h>

#include <trace/events/sched.h>

...

void my_sched_switch_probe(void* ignore, struct task_struct* prev, struct task_struct* next) {
    printk("my_sched_switch_probe: %s -> %s at %lu\n", prev->comm, next->comm, 
        (unsigned long) sched_clock());
}

int cswtracer_init(void) {
    register_trace_sched_switch(my_sched_switch_probe, NULL);

    return 0;
}

void cswtracer_fini(void) {
    unregister_trace_sched_switch(my_sched_switch_probe, NULL);
}

module_init(cswtracer_init);
module_exit(cswtracer_fini);

NOTE: do not run it, it will slow your system dramatically.

So analyze name of processes in my_sched_switch_probe() and calculate difference between time when process entered CPU (next->comm == "myprocessname") and when it leaves CPU (prev->comm == "myprocessname"). That difference is the last time period process spent on CPU during.

myaut
  • 11,174
  • 2
  • 30
  • 62