Search code examples
linuxlinux-kernelperf

perf : How to check processess running on particular cpu


Is there any option in perf to look into processes running on a particular cpu /core, and how much percentage of that core is taken by each process.

Reference links would be helpful.


Solution

  • perf is intended to do a profiling which is not good fit for your case. You may try to do sampling /proc/sched_debug (if it is compiled in your kernel). For example you may check which process is currently running on CPU:

    egrep '^R|cpu#' /proc/sched_debug 
    cpu#0, 917.276 MHz
    R          egrep  2614     37730.177313 ...
    cpu#1, 917.276 MHz
    R           bash  2023    218715.010833 ...
    

    By using his PID as a key, you may check how many CPU time in milliseconds it consumed:

    grep se.sum_exec_runtime /proc/2023/sched
    se.sum_exec_runtime                          :        279346.058986
    

    However, as @BrenoLeitão mentioned, SystemTap is quite useful for your script. Here is script for your task.

    global cputimes;
    global cmdline;
    global oncpu;
    
    global NS_PER_SEC = 1000000000;
    
    probe scheduler.cpu_on {
        oncpu[pid()] = local_clock_ns();
    }
    
    probe scheduler.cpu_off {
        if(oncpu[pid()] == 0)
            next;
    
        cmdline[pid()] = cmdline_str();
        cputimes[pid(), cpu()] <<< local_clock_ns() - oncpu[pid()];
    
        delete oncpu[pid()];
    }
    
    probe timer.s(1) {
        printf("%6s %3s %6s %s\n", "PID", "CPU", "PCT", "CMDLINE");
        foreach([pid+, cpu] in cputimes) {
            cpupct = @sum(cputimes[pid, cpu]) * 10000 / NS_PER_SEC;
    
            printf("%6d %3d %3d.%02d %s\n", pid, cpu, 
                cpupct / 100, cpupct % 100, cmdline[pid]);
        }
    
        delete cputimes;
    }
    

    It traces moments when process is running on CPU and stops execution on that (due to migration or sleeping) by attaching to scheduler.cpu_on and scheduler.cpu_off probes. Second probe calculates time difference between these events and saves it to cputimes aggregation along with process command line arguments.

    timer.s(1) fires once per second -- it walks over aggregation and calculates percentage. Here is sample output for Centos 7 with bash running infinite loop:

         0   0 100.16 
        30   1   0.00 
        51   0   0.00 
       380   0   0.02 /usr/bin/python -Es /usr/sbin/tuned -l -P
      2016   0   0.08 sshd: root@pts/0 "" "" "" ""
      2023   1 100.11 -bash
      2630   0   0.04 /usr/libexec/systemtap/stapio -R stap_3020c9e7ba76838179be68cd2390a10c_2630 -F3