Em Tue, Nov 26, 2013 at 06:54:37PM +0400, Stanislav Fomichev escreveu:
> Since b000c8065a92 "tracing: Remove the extra 4 bytes of padding in events"
> removed padding bytes, perf timechart got out of sync with the kernel's
> trace_entry structure.
> We can't just align perf's trace_entry definition with the kernel because we
> want timechart to continue working with old perf.data. Instead, we now
> calculate event data offset dynamically using offset of first non-common
> event field in the perf.data.

This doesn't apply on top of my acme/perf/core branch, that was where I
did the initial work on this patch, can you please redo on top of it?

Available at:

git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git

perf/core branch

- Arnaldo
 
> Signed-off-by: Stanislav Fomichev <stfomic...@yandex-team.ru>
> ---
>  tools/perf/builtin-timechart.c | 56 
> +++++++++++++++++++++++++++---------------
>  tools/perf/util/evsel.c        |  5 ++++
>  tools/perf/util/evsel.h        |  1 +
>  3 files changed, 42 insertions(+), 20 deletions(-)
> 
> diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c
> index 41c9bde2fb67..5c76a914031b 100644
> --- a/tools/perf/builtin-timechart.c
> +++ b/tools/perf/builtin-timechart.c
> @@ -41,6 +41,24 @@
>  #define SUPPORT_OLD_POWER_EVENTS 1
>  #define PWR_EVENT_EXIT -1
>  
> +static unsigned int payload_offset;
> +
> +static int timechart__set_payload_offset(struct perf_evlist *evlist)
> +{
> +     struct perf_evsel *evsel = perf_evlist__first(evlist);
> +     struct format_field *field = perf_evsel__fields(evsel);
> +
> +     if (!field)
> +             return -1;
> +
> +     payload_offset = field->offset;
> +     return 0;
> +}
> +
> +static void *timechart__payload(struct perf_sample *sample)
> +{
> +     return sample->raw_data + payload_offset;
> +}
>  
>  static unsigned int  numcpus;
>  static u64           min_freq;       /* Lowest CPU frequency seen */
> @@ -304,13 +322,11 @@ struct trace_entry {
>       unsigned char           flags;
>       unsigned char           preempt_count;
>       int                     pid;
> -     int                     lock_depth;
>  };
>  
>  #ifdef SUPPORT_OLD_POWER_EVENTS
>  static int use_old_power_events;
>  struct power_entry_old {
> -     struct trace_entry te;
>       u64     type;
>       u64     value;
>       u64     cpu_id;
> @@ -318,14 +334,12 @@ struct power_entry_old {
>  #endif
>  
>  struct power_processor_entry {
> -     struct trace_entry te;
>       u32     state;
>       u32     cpu_id;
>  };
>  
>  #define TASK_COMM_LEN 16
>  struct wakeup_entry {
> -     struct trace_entry te;
>       char comm[TASK_COMM_LEN];
>       int   pid;
>       int   prio;
> @@ -333,7 +347,6 @@ struct wakeup_entry {
>  };
>  
>  struct sched_switch {
> -     struct trace_entry te;
>       char prev_comm[TASK_COMM_LEN];
>       int  prev_pid;
>       int  prev_prio;
> @@ -402,11 +415,13 @@ static void p_state_change(int cpu, u64 timestamp, u64 
> new_freq)
>                       turbo_frequency = max_freq;
>  }
>  
> -static void
> -sched_wakeup(int cpu, u64 timestamp, int pid, struct trace_entry *te)
> +static void sched_wakeup(struct perf_sample *sample)
>  {
> +     struct trace_entry *te = sample->raw_data;
> +     struct wakeup_entry *wake = timechart__payload(sample);
> +     u64 timestamp = sample->time;
> +     int pid = sample->pid, cpu = sample->cpu;
>       struct per_pid *p;
> -     struct wakeup_entry *wake = (void *)te;
>       struct wake_event *we = zalloc(sizeof(*we));
>  
>       if (!we)
> @@ -434,11 +449,9 @@ sched_wakeup(int cpu, u64 timestamp, int pid, struct 
> trace_entry *te)
>       }
>  }
>  
> -static void sched_switch(int cpu, u64 timestamp, struct trace_entry *te)
> +static void sched_switch(int cpu, u64 timestamp, struct sched_switch *sw)
>  {
>       struct per_pid *p = NULL, *prev_p;
> -     struct sched_switch *sw = (void *)te;
> -
>  
>       prev_p = find_create_pid(sw->prev_pid);
>  
> @@ -495,7 +508,7 @@ static int
>  process_sample_cpu_idle(struct perf_evsel *evsel __maybe_unused,
>                       struct perf_sample *sample)
>  {
> -     struct power_processor_entry *ppe = sample->raw_data;
> +     struct power_processor_entry *ppe = timechart__payload(sample);
>  
>       if (ppe->state == (u32) PWR_EVENT_EXIT)
>               c_state_end(ppe->cpu_id, sample->time);
> @@ -508,7 +521,7 @@ static int
>  process_sample_cpu_frequency(struct perf_evsel *evsel __maybe_unused,
>                            struct perf_sample *sample)
>  {
> -     struct power_processor_entry *ppe = sample->raw_data;
> +     struct power_processor_entry *ppe = timechart__payload(sample);
>  
>       p_state_change(ppe->cpu_id, sample->time, ppe->state);
>       return 0;
> @@ -518,9 +531,7 @@ static int
>  process_sample_sched_wakeup(struct perf_evsel *evsel __maybe_unused,
>                           struct perf_sample *sample)
>  {
> -     struct trace_entry *te = sample->raw_data;
> -
> -     sched_wakeup(sample->cpu, sample->time, sample->pid, te);
> +     sched_wakeup(sample);
>       return 0;
>  }
>  
> @@ -528,9 +539,9 @@ static int
>  process_sample_sched_switch(struct perf_evsel *evsel __maybe_unused,
>                           struct perf_sample *sample)
>  {
> -     struct trace_entry *te = sample->raw_data;
> +     struct sched_switch *sw = timechart__payload(sample);
>  
> -     sched_switch(sample->cpu, sample->time, te);
> +     sched_switch(sample->cpu, sample->time, sw);
>       return 0;
>  }
>  
> @@ -539,7 +550,7 @@ static int
>  process_sample_power_start(struct perf_evsel *evsel __maybe_unused,
>                          struct perf_sample *sample)
>  {
> -     struct power_entry_old *peo = sample->raw_data;
> +     struct power_entry_old *peo = timechart__payload(sample);
>  
>       c_state_start(peo->cpu_id, sample->time, peo->value);
>       return 0;
> @@ -557,7 +568,7 @@ static int
>  process_sample_power_frequency(struct perf_evsel *evsel __maybe_unused,
>                              struct perf_sample *sample)
>  {
> -     struct power_entry_old *peo = sample->raw_data;
> +     struct power_entry_old *peo = timechart__payload(sample);
>  
>       p_state_change(peo->cpu_id, sample->time, peo->value);
>       return 0;
> @@ -1012,6 +1023,11 @@ static int __cmd_timechart(const char *output_name)
>               goto out_delete;
>       }
>  
> +     if (timechart__set_payload_offset(session->evlist)) {
> +             pr_err("Field format not found, please try updating this 
> tool\n");
> +             goto out_delete;
> +     }
> +
>       ret = perf_session__process_events(session, &perf_timechart);
>       if (ret)
>               goto out_delete;
> diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
> index 46dd4c2a41ce..4847d373fe2a 100644
> --- a/tools/perf/util/evsel.c
> +++ b/tools/perf/util/evsel.c
> @@ -1767,6 +1767,11 @@ struct format_field *perf_evsel__field(struct 
> perf_evsel *evsel, const char *nam
>       return pevent_find_field(evsel->tp_format, name);
>  }
>  
> +struct format_field *perf_evsel__fields(struct perf_evsel *evsel)
> +{
> +     return evsel->tp_format->format.fields;
> +}
> +
>  void *perf_evsel__rawptr(struct perf_evsel *evsel, struct perf_sample 
> *sample,
>                        const char *name)
>  {
> diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
> index 1ea7c92e6e33..3d50dc01bb1d 100644
> --- a/tools/perf/util/evsel.h
> +++ b/tools/perf/util/evsel.h
> @@ -193,6 +193,7 @@ static inline char *perf_evsel__strval(struct perf_evsel 
> *evsel,
>  struct format_field;
>  
>  struct format_field *perf_evsel__field(struct perf_evsel *evsel, const char 
> *name);
> +struct format_field *perf_evsel__fields(struct perf_evsel *evsel);
>  
>  #define perf_evsel__match(evsel, t, c)               \
>       (evsel->attr.type == PERF_TYPE_##t &&   \
> -- 
> 1.8.3.2
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to