1
votes

Say I am executing a program in user space and there is a function in that program. Now I want to know the cpu-time spent in execution of that function.

What did I figure out till now ?

On starting of that program I will get the PID of that process, which I will pass to the kernel module and will get the task_struct for that process. After that in thread_info we can get instruction pointer and Stack pointer.

From user space we can give starting and ending offset of that function to the kernel module and then in kernel we can check these two with the help of instruction pointer to get the execution time. So is there anyway to do it or is there another way to achieve the goal.

Please don't specify some pre-exiting tools. I want to do it on my own by writing a kernel module for this.

1
Which exactly task you are trying to solve? It looks like profiling task for me. If it is so -- look into OProfile. - Sam Protsenko
@SamProtsenko Yes I want to do profiling, but in my kernel module. I checked perf and ftrace for that. Let me check OProfile. - A-B
You can profile your module with OProfile. It may require rebuilding your kernel with OProfile config options enabled though. Here is an example how to do so: lainoox.com/profiling-kernel-modules-using-oprofile . I used to use OProfile and it was working just fine for my kernel modules (don't remember if they were external or built-in though). - Sam Protsenko
@SamProtsenko I don't want to profile the module. I want to profile a user process in/using a linux kernel module. - A-B
I believe OProfile can do that too. I'd also recommend you try Valgrind (Callgrind, more specifically, it's one of Valgrind tools). It helped me back in days to optimize my user-space application. KCacheGrind may be used to visualize data collected by Callgrind. This way you don't need to rebuild your kernel. - Sam Protsenko

1 Answers

0
votes

There is already tool for that called SystemTap. It generates modules on-the-fly.

In userspace you may use this:

stap -ve ' global start;
probe process("/usr/bin/python2.7").function("builtin_range")
{ start = local_clock_us(); }
probe process("/usr/bin/python2.7").function("builtin_range").return
{ printf("range(%d, %d, %d) took %d us\n", 
            user_int(&$ilow), user_int(&$ihigh), 
            user_int(&$istep), local_clock_us() - start); }'

it will measure wall time for the Python 2 range() builtin. Assuming it won't sleep, the wall time will match cpu time.

In-kernel functions may be traced the same way:

stap -ve ' global start;
probe kernel.function("__schedule") 
{ start[cpu()] = local_clock_us(); }
probe kernel.function("__schedule").return 
{ printf("schedule() on CPU %d took %d us\n", cpu(), 
            local_clock_us() - start[cpu()]); }'