perf session: Use evlist/evsel for managing perf.data attributes
Commit-ID: a91e5431d54f5359fccb5ec2512f252eb217707e Gitweb: http://git.kernel.org/tip/a91e5431d54f5359fccb5ec2512f252eb217707e Author: Arnaldo Carvalho de Melo <[email protected]> AuthorDate: Thu, 10 Mar 2011 11:15:54 -0300 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 10 Mar 2011 11:15:54 -0300
perf session: Use evlist/evsel for managing perf.data attributes
So that we can reuse things like the id to attr lookup routine (perf_evlist__id2evsel) that uses a hash table instead of the linear lookup done in the older perf_header_attr routines, etc.
Also to make evsels/evlist more pervasive an API, simplyfing using the emerging perf lib.
cc: Arun Sharma <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Mike Galbraith <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Stephane Eranian <[email protected]>
Cc: Tom Zanussi <[email protected]>
LKML-Reference: <new-submission>
--- tools/perf/builtin-record.c | 101 +++++++------------- tools/perf/builtin-report.c | 4 +- tools/perf/builtin-top.c | 5 +- tools/perf/util/evlist.c | 26 ++++-- tools/perf/util/evlist.h | 4 +- tools/perf/util/evsel.c | 21 ++++- tools/perf/util/evsel.h | 9 ++- tools/perf/util/header.c | 225 ++++++++++++++++--------------------------- tools/perf/util/header.h | 36 ++------ tools/perf/util/session.c | 74 +------------- tools/perf/util/session.h | 2 - 11 files changed, 179 insertions(+), 328 deletions(-)
tools/perf/builtin-record.c +35 -66
@@ -31,7 +31,6 @@#include <sys/mman.h> #define FD (e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) -#define SID (e, x, y) xyarray__entry(e->id, x, y)enum write_mode_t {WRITE_FORCE ,
@@ -40,7 +39,6 @@ enum write_mode_t {static u64 user_interval =ULLONG_MAX ;static u64 default_interval =0 ; -static u64 sample_type;static unsigned int page_size;static unsigned int mmap_pages =128 ;
@@ -160,54 +158,6 @@ static void sig_atexit(void)kill (getpid (), signr); } -static struct perf_header_attr *get_header_attr (struct perf_event_attr *a,int nr) -{ -struct perf_header_attr *h_attr; - -if (nr < session->header.attrs) { - h_attr = session->header.attr[nr]; - }else { - h_attr =perf_header_attr__new (a); -if (h_attr !=NULL ) -if (perf_header__add_attr (&session->header, h_attr) <0 ) { -perf_header_attr__delete (h_attr); - h_attr =NULL ; - } - } - -return h_attr; -} - -static void create_counter (struct perf_evsel *evsel,int cpu) -{ -struct perf_event_attr *attr = &evsel->attr; -struct perf_header_attr *h_attr; -struct perf_sample_id *sid; -int thread_index; - -for (thread_index =0 ; thread_index < evsel_list->threads->nr; thread_index++) { - h_attr =get_header_attr (attr, evsel->idx); -if (h_attr ==NULL ) -die ("nomem\n" ); - -if (!file_new) { -if (memcmp (&h_attr->attr, attr,sizeof (*attr))) { -fprintf (stderr,"incompatible append\n" ); -exit (-1 ); - } - } - - sid =SID (evsel, cpu, thread_index); -if (perf_header_attr__add_id (h_attr, sid->id) <0 ) { -pr_warning ("Not enough memory to add id\n" ); -exit (-1 ); - } - } - -if (!sample_type) - sample_type = attr->sample_type; -} -static void config_attr (struct perf_evsel *evsel,struct perf_evlist *evlist) {struct perf_event_attr *attr = &evsel->attr;
@@ -278,10 +228,28 @@ static void config_attr(struct perf_evsel *evsel, struct perf_evlist *evlist) } } +static bool perf_evlist__equal (struct perf_evlist *evlist, +struct perf_evlist *other) +{ +struct perf_evsel *pos, *pair; + +if (evlist->nr_entries != other->nr_entries) +return false; + + pair = list_entry(other->entries.next, struct perf_evsel, node); + +list_for_each_entry (pos, &evlist->entries, node) { +if (memcmp (&pos->attr, &pair->attr,sizeof (pos->attr) !=0 )) +return false; + pair = list_entry(pair->node.next, struct perf_evsel, node); + } + +return true; +} +static void open_counters (struct perf_evlist *evlist) {struct perf_evsel *pos; -int cpu;list_for_each_entry (pos, &evlist->entries, node) {struct perf_event_attr *attr = &pos->attr;
@@ -364,10 +332,16 @@ try_again:if (perf_evlist__mmap (evlist, mmap_pages, false) <0 )die ("failed to mmap with %d (%s)\n" , errno,strerror (errno)); -for (cpu =0 ; cpu < evsel_list->cpus->nr; ++cpu) { -list_for_each_entry (pos, &evlist->entries, node) -create_counter (pos, cpu); - } +if (file_new) + session->evlist = evlist; +else { +if (!perf_evlist__equal (session->evlist, evlist)) { +fprintf (stderr,"incompatible append\n" ); +exit (-1 ); + } + } + +perf_session__update_sample_type (session); }static int process_buildids (void )
@@ -390,7 +364,7 @@ static void atexit_header(void)if (!no_buildid)process_buildids (); -perf_header__write (&session->header, evsel_list, output, true); +perf_session__write_header (session, evsel_list, output, true);perf_session__delete (session);perf_evlist__delete (evsel_list);symbol__exit ();
@@ -524,7 +498,7 @@ static int __cmd_record(int argc, const char **argv)perf_header__set_feat (&session->header,HEADER_BUILD_ID );if (!file_new) { - err =perf_header__read (session, output); + err =perf_session__read_header (session, output);if (err <0 ) goto out_delete_session; }
@@ -588,8 +562,6 @@ static int __cmd_record(int argc, const char **argv)open_counters (evsel_list); -perf_session__set_sample_type (session, sample_type); -/* * perf_session__delete(session) will be called at atexit_header() */
@@ -600,20 +572,17 @@ static int __cmd_record(int argc, const char **argv)if (err <0 )return err; }else if (file_new) { - err =perf_header__write (&session->header, evsel_list, - output, false); + err =perf_session__write_header (session, evsel_list, + output, false);if (err <0 )return err; } post_processing_offset =lseek (output,0 ,SEEK_CUR ); -perf_session__set_sample_id_all (session, sample_id_all_avail); -if (pipe_output) { - err =perf_event__synthesize_attrs (&session->header, - process_synthesized_event, - session); + err =perf_session__synthesize_attrs (session, + process_synthesized_event);if (err <0 ) {pr_err ("Couldn't synthesize attrs.\n" );return err;
tools/perf/builtin-report.c +2 -2
@@ -70,8 +70,8 @@ static int perf_session__add_hist_entry(struct perf_session *session,* FIXME: Propagate this back, but at least we're in a builtin, * where exit() is allowed. ;-) */ -ui__warning ("Invalid %s file, contains samples with id not in " -"its header!\n" , input_name); +ui__warning ("Invalid %s file, contains samples with id %" PRIu64" not in " +"its header!\n" , input_name, sample->id);exit_browser (0 );exit (1 ); }
tools/perf/builtin-top.c +2 -3
@@ -883,7 +883,6 @@ try_again:static int __cmd_top (void ) {pthread_t thread; -struct perf_evsel *first;int ret__used ;/* * FIXME: perf_session__new should allow passing a O_MMAP, so that all this
@@ -900,8 +899,8 @@ static int __cmd_top(void)perf_event__synthesize_threads (perf_event__process, session);start_counters (top.evlist); - first = list_entry(top.evlist->entries.next, struct perf_evsel, node); -perf_session__set_sample_type (session, first->attr.sample_type); + session->evlist = top.evlist; +perf_session__update_sample_type (session);/* Wait for a minimal set of events before starting the snapshot */ poll (top.evlist->pollfd, top.evlist->nr_fds,100 );
tools/perf/util/evlist.c +17 -9
@@ -19,7 +19,7 @@#include <linux/hash.h> #define FD (e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) -#define SID (e, x, y) xyarray__entry(e->id, x, y) +#define SID (e, x, y) xyarray__entry(e->sample_id, x, y)void perf_evlist__init (struct perf_evlist *evlist,struct cpu_map *cpus,struct thread_map *threads)
@@ -106,8 +106,9 @@ void perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd) evlist->nr_fds++; } -void perf_evlist__id_hash (struct perf_evlist *evlist,struct perf_evsel *evsel, -int cpu,int thread,u64 id) +static void perf_evlist__id_hash (struct perf_evlist *evlist, +struct perf_evsel *evsel, +int cpu,int thread,u64 id) {int hash;struct perf_sample_id *sid =SID (evsel, cpu, thread);
@@ -118,9 +119,16 @@ void perf_evlist__id_hash(struct perf_evlist *evlist, struct perf_evsel *evsel,hlist_add_head (&sid->node, &evlist->heads[hash]); } -static int perf_evlist__id_hash_fd (struct perf_evlist *evlist, -struct perf_evsel *evsel, -int cpu,int thread,int fd) +void perf_evlist__id_add (struct perf_evlist *evlist,struct perf_evsel *evsel, +int cpu,int thread,u64 id) +{ +perf_evlist__id_hash (evlist, evsel, cpu, thread, id); + evsel->id[evsel->ids++] = id; +} + +static int perf_evlist__id_add_fd (struct perf_evlist *evlist, +struct perf_evsel *evsel, +int cpu,int thread,int fd) {u64 read_data[4 ] = {0 , };int id_idx =1 ;/* The first entry is the counter value */
@@ -134,7 +142,7 @@ static int perf_evlist__id_hash_fd(struct perf_evlist *evlist,if (evsel->attr.read_format &PERF_FORMAT_TOTAL_TIME_RUNNING ) ++id_idx; -perf_evlist__id_hash (evlist, evsel, cpu, thread, read_data[id_idx]); +perf_evlist__id_add (evlist, evsel, cpu, thread, read_data[id_idx]);return 0 ; }
@@ -292,7 +300,7 @@ int perf_evlist__mmap(struct perf_evlist *evlist, int pages, bool overwrite)list_for_each_entry (evsel, &evlist->entries, node) {if ((evsel->attr.read_format &PERF_FORMAT_ID ) && - evsel->id ==NULL && + evsel->sample_id ==NULL &&perf_evsel__alloc_id (evsel, cpus->nr, threads->nr) <0 )return -ENOMEM ;
@@ -308,7 +316,7 @@ int perf_evlist__mmap(struct perf_evlist *evlist, int pages, bool overwrite) goto out_unmap;if ((evsel->attr.read_format &PERF_FORMAT_ID ) && -perf_evlist__id_hash_fd (evlist, evsel, cpu, thread, fd) <0 ) +perf_evlist__id_add_fd (evlist, evsel, cpu, thread, fd) <0 ) goto out_unmap; } }
tools/perf/util/evlist.h +2 -2
@@ -38,8 +38,8 @@ void perf_evlist__delete(struct perf_evlist *evlist);void perf_evlist__add (struct perf_evlist *evlist,struct perf_evsel *entry);int perf_evlist__add_default (struct perf_evlist *evlist); -void perf_evlist__id_hash (struct perf_evlist *evlist,struct perf_evsel *evsel, -int cpu,int thread,u64 id); +void perf_evlist__id_add (struct perf_evlist *evlist,struct perf_evsel *evsel, +int cpu,int thread,u64 id);int perf_evlist__alloc_pollfd (struct perf_evlist *evlist);void perf_evlist__add_pollfd (struct perf_evlist *evlist,int fd);
tools/perf/util/evsel.c +17 -4
@@ -41,8 +41,18 @@ int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads)int perf_evsel__alloc_id (struct perf_evsel *evsel,int ncpus,int nthreads) { - evsel->id =xyarray__new (ncpus, nthreads,sizeof (struct perf_sample_id )); -return evsel->id !=NULL ?0 : -ENOMEM ; + evsel->sample_id =xyarray__new (ncpus, nthreads,sizeof (struct perf_sample_id )); +if (evsel->sample_id ==NULL ) +return -ENOMEM ; + + evsel->id =zalloc (ncpus * nthreads *sizeof (u64)); +if (evsel->id ==NULL ) { +xyarray__delete (evsel->sample_id); + evsel->sample_id =NULL ; +return -ENOMEM ; + } + +return 0 ; }int perf_evsel__alloc_counts (struct perf_evsel *evsel,int ncpus)
@@ -60,7 +70,9 @@ void perf_evsel__free_fd(struct perf_evsel *evsel)void perf_evsel__free_id (struct perf_evsel *evsel) { -xyarray__delete (evsel->id); +xyarray__delete (evsel->sample_id); + evsel->sample_id =NULL ; +free (evsel->id); evsel->id =NULL ; }
@@ -79,7 +91,8 @@ void perf_evsel__exit(struct perf_evsel *evsel) {assert (list_empty (&evsel->node));xyarray__delete (evsel->fd); -xyarray__delete (evsel->id); +xyarray__delete (evsel->sample_id); +free (evsel->id); }void perf_evsel__delete (struct perf_evsel *evsel)
tools/perf/util/evsel.h +7 -2
@@ -49,12 +49,17 @@ struct perf_evsel {struct perf_event_attr attr;char *filter;struct xyarray *fd; -struct xyarray *id; +struct xyarray *sample_id; +u64 *id;struct perf_counts *counts;int idx; +int ids;struct hists hists;char *name; -void *priv; +union { +void *priv; +off_t id_offset; + };struct cgroup_sel *cgrp; };
tools/perf/util/header.c +84 -141
345 lines not on this page · raw message
tools/perf/util/header.h +8 -28
@@ -9,13 +9,6 @@#include <linux/bitmap.h> -struct perf_header_attr { -struct perf_event_attr attr; -int ids, size; -u64 *id; -off_t id_offset; -}; -enum {HEADER_TRACE_INFO =1 ,HEADER_BUILD_ID ,
@@ -51,9 +44,7 @@ int perf_file_header__read(struct perf_file_header *self,struct perf_header {int frozen; -int attrs, size;bool needs_swap; -struct perf_header_attr **attr;s64 attr_offset;u64 data_offset;u64 data_size;
@@ -62,29 +53,19 @@ struct perf_header {DECLARE_BITMAP (adds_features,HEADER_FEAT_BITS ); }; -int perf_header__init (struct perf_header *self); -void perf_header__exit (struct perf_header *self); -struct perf_evlist ; -int perf_header__read (struct perf_session *session,int fd); -int perf_header__write (struct perf_header *self,struct perf_evlist *evlist, -int fd,bool at_exit); +int perf_session__read_header (struct perf_session *session,int fd); +int perf_session__write_header (struct perf_session *session, +struct perf_evlist *evlist, +int fd,bool at_exit);int perf_header__write_pipe (int fd); -int perf_header__add_attr (struct perf_header *self, -struct perf_header_attr *attr); -int perf_header__push_event (u64 id,const char *name);char *perf_header__find_event (u64 id); -struct perf_header_attr *perf_header_attr__new (struct perf_event_attr *attr); -void perf_header_attr__delete (struct perf_header_attr *self); - -int perf_header_attr__add_id (struct perf_header_attr *self,u64 id); - -u64 perf_header__sample_type (struct perf_header *header); -bool perf_header__sample_id_all (const struct perf_header *header); +u64 perf_evlist__sample_type (struct perf_evlist *evlist); +bool perf_evlist__sample_id_all (const struct perf_evlist *evlist);void perf_header__set_feat (struct perf_header *self,int feat);void perf_header__clear_feat (struct perf_header *self,int feat);bool perf_header__has_feat (const struct perf_header *self,int feat);
@@ -101,9 +82,8 @@ int build_id_cache__remove_s(const char *sbuild_id, const char *debugdir);int perf_event__synthesize_attr (struct perf_event_attr *attr,u16 ids,u64 *id,perf_event__handler_t process,struct perf_session *session); -int perf_event__synthesize_attrs (struct perf_header *self, -perf_event__handler_t process, -struct perf_session *session); +int perf_session__synthesize_attrs (struct perf_session *session, +perf_event__handler_t process);int perf_event__process_attr (union perf_event *event,struct perf_session *session); int perf_event__synthesize_event_type(u64 event_id, char *name,
tools/perf/util/session.c +5 -69
134 lines not on this page · raw message
tools/perf/util/session.h +0 -2
@@ -112,8 +112,6 @@ void mem_bswap_64(void *src, int byte_size);int perf_session__create_kernel_maps (struct perf_session *self);void perf_session__update_sample_type (struct perf_session *self); -void perf_session__set_sample_id_all (struct perf_session *session,bool value); -void perf_session__set_sample_type (struct perf_session *session,u64 type);void perf_session__remove_thread (struct perf_session *self,struct thread *th); static inline