perf-source: fix acquisition of time for comm and mmap events

We were not getting the proper value for time. We need sample_id_all set
according to my cursory reading of the core.c in the kernel. Also, the
time is aligned to 64-bit (after the comm field).
This commit is contained in:
Christian Hergert
2016-04-15 04:45:34 -07:00
parent 609ee997da
commit dd821b48e8
2 changed files with 20 additions and 25 deletions

View File

@ -31,18 +31,6 @@ typedef struct _SpPerfCounter SpPerfCounter;
#pragma pack(push, 1) #pragma pack(push, 1)
typedef struct
{
/*
* These fields are available as the suffix only because we have specified
* them when creating attributes. Be careful about using them.
* Ideally, we would probably switch from using structures overlaid with
* casts to a reader design, which knows about the attributes.
*/
guint32 pid, tid;
guint64 time;
} SpPerfCounterSuffix;
typedef struct typedef struct
{ {
struct perf_event_header header; struct perf_event_header header;

View File

@ -165,13 +165,21 @@ sp_perf_source_handle_sample (SpPerfSource *self,
n_ips); n_ips);
} }
static inline void
realign (gsize *pos,
gsize align)
{
*pos = (*pos + align - 1) & ~(align - 1);
}
static void static void
sp_perf_source_handle_event (SpPerfCounterEvent *event, sp_perf_source_handle_event (SpPerfCounterEvent *event,
guint cpu, guint cpu,
gpointer user_data) gpointer user_data)
{ {
SpPerfSource *self = user_data; SpPerfSource *self = user_data;
SpPerfCounterSuffix *suffix; gsize offset;
gint64 time;
g_assert (SP_IS_PERF_SOURCE (self)); g_assert (SP_IS_PERF_SOURCE (self));
g_assert (event != NULL); g_assert (event != NULL);
@ -179,13 +187,12 @@ sp_perf_source_handle_event (SpPerfCounterEvent *event,
switch (event->header.type) switch (event->header.type)
{ {
case PERF_RECORD_COMM: case PERF_RECORD_COMM:
suffix = (SpPerfCounterSuffix *)event->raw offset = strlen (event->comm.comm) + 1;
+ G_STRUCT_OFFSET (SpPerfCounterEventComm, comm) realign (&offset, sizeof (guint64));
+ strlen (event->comm.comm) memcpy (&time, event->comm.comm + offset, sizeof time);
+ 1;
sp_capture_writer_add_process (self->writer, sp_capture_writer_add_process (self->writer,
suffix->time, time,
cpu, cpu,
event->comm.pid, event->comm.pid,
event->comm.comm); event->comm.comm);
@ -230,13 +237,12 @@ sp_perf_source_handle_event (SpPerfCounterEvent *event,
break; break;
case PERF_RECORD_MMAP: case PERF_RECORD_MMAP:
suffix = (SpPerfCounterSuffix *)event->raw offset = strlen (event->mmap.filename) + 1;
+ G_STRUCT_OFFSET (SpPerfCounterEventMmap, filename) realign (&offset, sizeof (guint64));
+ strlen (event->mmap.filename) memcpy (&time, event->mmap.filename + offset, sizeof time);
+ 1;
sp_capture_writer_add_map (self->writer, sp_capture_writer_add_map (self->writer,
suffix->time, time,
cpu, cpu,
event->mmap.pid, event->mmap.pid,
event->mmap.addr, event->mmap.addr,
@ -275,7 +281,6 @@ sp_perf_source_start_pid (SpPerfSource *self,
g_assert (SP_IS_PERF_SOURCE (self)); g_assert (SP_IS_PERF_SOURCE (self));
attr.sample_type = PERF_SAMPLE_IP attr.sample_type = PERF_SAMPLE_IP
| PERF_SAMPLE_TID
| PERF_SAMPLE_CALLCHAIN | PERF_SAMPLE_CALLCHAIN
| PERF_SAMPLE_TIME; | PERF_SAMPLE_TIME;
attr.wakeup_events = N_WAKEUP_EVENTS; attr.wakeup_events = N_WAKEUP_EVENTS;
@ -284,9 +289,11 @@ sp_perf_source_start_pid (SpPerfSource *self,
attr.comm = 1; attr.comm = 1;
attr.task = 1; attr.task = 1;
attr.exclude_idle = 1; attr.exclude_idle = 1;
attr.size = sizeof attr;
attr.clockid = sp_clock; attr.clockid = sp_clock;
attr.use_clockid = 1; attr.use_clockid = 1;
attr.sample_id_all = 1;
attr.size = sizeof attr;
if (pid != -1) if (pid != -1)
{ {