perf: Track PIDs for kernel samples (XCC)
authorBarret Rhoden <brho@cs.berkeley.edu>
Thu, 16 Jun 2016 18:19:14 +0000 (14:19 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Fri, 17 Jun 2016 16:17:55 +0000 (12:17 -0400)
When the kernel is running on behalf of the user, we'd like to attribute
those samples to that process.  We now report that info.

Incidentally, I dabbled with reporting the vcoreid for user samples as the
TID.  That won't work, since TID is more of a PID on Linux.

Reinstall your kernel headers.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/include/ros/profiler_records.h
kern/src/profiler.c
tools/profile/perf/perfconv.c

index 4a81e9c..fb6b785 100644 (file)
@@ -12,6 +12,7 @@
 struct proftype_kern_trace64 {
        uint64_t info;
        uint64_t tstamp;
+       uint32_t pid;
        uint16_t cpu;
        uint16_t num_traces;
        uint64_t trace[0];
index 6e68b53..8ab9646 100644 (file)
@@ -130,6 +130,7 @@ static void profiler_push_kernel_trace64(struct profiler_cpu_context *cpu_buf,
                                          const uintptr_t *trace, size_t count,
                                          uint64_t info)
 {
+       struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
        size_t size = sizeof(struct proftype_kern_trace64) +
                count * sizeof(uint64_t);
        struct block *b;
@@ -151,6 +152,10 @@ static void profiler_push_kernel_trace64(struct profiler_cpu_context *cpu_buf,
 
                record->info = info;
                record->tstamp = nsec();
+               if (is_ktask(pcpui->cur_kthread) || !pcpui->cur_proc)
+                       record->pid = -1;
+               else
+                       record->pid = pcpui->cur_proc->pid;
                record->cpu = cpu_buf->cpu;
                record->num_traces = count;
                for (size_t i = 0; i < count; i++)
index fdcd2f5..f00a222 100644 (file)
@@ -663,14 +663,16 @@ static void emit_kernel_trace64(struct perf_record *pr,
        xrec->header.misc = PERF_RECORD_MISC_KERNEL;
        xrec->header.size = size;
        xrec->ip = rec->trace[0];
-       /* TODO: We could have pid/tid for kernel tasks during their lifetime.
-        * During syscalls, we could use the pid of the process.  For the kernel
-        * itself, -1 seems to be generic kernel stuff, and tid == 0 is 'swapper'.
-        *
-        * Right now, the kernel doesn't even tell us the pid, so we have no way of
-        * knowing from userspace. */
-       xrec->pid = -1;
-       xrec->tid = 0;
+       /* TODO: -1 means "not a process".  We could track ktasks with IDs, emit
+        * COMM events for them (probably!) and report them as the tid.  For now,
+        * tid of 0 means [swapper] to Linux. */
+       if (rec->pid == -1) {
+               xrec->pid = -1;
+               xrec->tid = 0;
+       } else {
+               xrec->pid = rec->pid;
+               xrec->tid = rec->pid;
+       }
        xrec->time = rec->tstamp;
        xrec->addr = rec->trace[0];
        xrec->identifier = perfconv_get_event_id(cctx, rec->info);