]> Git Repo - linux.git/commitdiff
Merge tag 'v3.12-rc5' into perf/core
authorIngo Molnar <[email protected]>
Tue, 15 Oct 2013 05:05:06 +0000 (07:05 +0200)
committerIngo Molnar <[email protected]>
Tue, 15 Oct 2013 05:05:18 +0000 (07:05 +0200)
Merge Linux v3.12-rc5, to pick up the latest fixes.

Signed-off-by: Ingo Molnar <[email protected]>
1  2 
tools/perf/builtin-stat.c
tools/perf/util/session.c

index cc7efee9d301c5dfec1f777b18df99d91d706476,5098f144b92defd53e94f9f24184e3ade0672928..700b478491015b6bcfff40f3f299316cc1d4f492
@@@ -46,7 -46,6 +46,7 @@@
  #include "util/util.h"
  #include "util/parse-options.h"
  #include "util/parse-events.h"
 +#include "util/pmu.h"
  #include "util/event.h"
  #include "util/evlist.h"
  #include "util/evsel.h"
@@@ -71,41 -70,6 +71,41 @@@ static void print_counter_aggr(struct p
  static void print_counter(struct perf_evsel *counter, char *prefix);
  static void print_aggr(char *prefix);
  
 +/* Default events used for perf stat -T */
 +static const char * const transaction_attrs[] = {
 +      "task-clock",
 +      "{"
 +      "instructions,"
 +      "cycles,"
 +      "cpu/cycles-t/,"
 +      "cpu/tx-start/,"
 +      "cpu/el-start/,"
 +      "cpu/cycles-ct/"
 +      "}"
 +};
 +
 +/* More limited version when the CPU does not have all events. */
 +static const char * const transaction_limited_attrs[] = {
 +      "task-clock",
 +      "{"
 +      "instructions,"
 +      "cycles,"
 +      "cpu/cycles-t/,"
 +      "cpu/tx-start/"
 +      "}"
 +};
 +
 +/* must match transaction_attrs and the beginning limited_attrs */
 +enum {
 +      T_TASK_CLOCK,
 +      T_INSTRUCTIONS,
 +      T_CYCLES,
 +      T_CYCLES_IN_TX,
 +      T_TRANSACTION_START,
 +      T_ELISION_START,
 +      T_CYCLES_IN_TX_CP,
 +};
 +
  static struct perf_evlist     *evsel_list;
  
  static struct perf_target     target = {
@@@ -126,7 -90,6 +126,7 @@@ static enum aggr_mode               aggr_mode                       = AG
  static volatile pid_t         child_pid                       = -1;
  static bool                   null_run                        =  false;
  static int                    detailed_run                    =  0;
 +static bool                   transaction_run;
  static bool                   big_num                         =  true;
  static int                    big_num_opt                     =  -1;
  static const char             *csv_sep                        = NULL;
@@@ -251,10 -214,7 +251,10 @@@ static struct stats runtime_l1_icache_s
  static struct stats runtime_ll_cache_stats[MAX_NR_CPUS];
  static struct stats runtime_itlb_cache_stats[MAX_NR_CPUS];
  static struct stats runtime_dtlb_cache_stats[MAX_NR_CPUS];
 +static struct stats runtime_cycles_in_tx_stats[MAX_NR_CPUS];
  static struct stats walltime_nsecs_stats;
 +static struct stats runtime_transaction_stats[MAX_NR_CPUS];
 +static struct stats runtime_elision_stats[MAX_NR_CPUS];
  
  static void perf_stat__reset_stats(struct perf_evlist *evlist)
  {
        memset(runtime_ll_cache_stats, 0, sizeof(runtime_ll_cache_stats));
        memset(runtime_itlb_cache_stats, 0, sizeof(runtime_itlb_cache_stats));
        memset(runtime_dtlb_cache_stats, 0, sizeof(runtime_dtlb_cache_stats));
 +      memset(runtime_cycles_in_tx_stats, 0,
 +                      sizeof(runtime_cycles_in_tx_stats));
 +      memset(runtime_transaction_stats, 0,
 +              sizeof(runtime_transaction_stats));
 +      memset(runtime_elision_stats, 0, sizeof(runtime_elision_stats));
        memset(&walltime_nsecs_stats, 0, sizeof(walltime_nsecs_stats));
  }
  
@@@ -319,29 -274,6 +319,29 @@@ static inline int nsec_counter(struct p
        return 0;
  }
  
 +static struct perf_evsel *nth_evsel(int n)
 +{
 +      static struct perf_evsel **array;
 +      static int array_len;
 +      struct perf_evsel *ev;
 +      int j;
 +
 +      /* Assumes this only called when evsel_list does not change anymore. */
 +      if (!array) {
 +              list_for_each_entry(ev, &evsel_list->entries, node)
 +                      array_len++;
 +              array = malloc(array_len * sizeof(void *));
 +              if (!array)
 +                      exit(ENOMEM);
 +              j = 0;
 +              list_for_each_entry(ev, &evsel_list->entries, node)
 +                      array[j++] = ev;
 +      }
 +      if (n < array_len)
 +              return array[n];
 +      return NULL;
 +}
 +
  /*
   * Update various tracking values we maintain to print
   * more semantic information such as miss/hit ratios,
@@@ -353,15 -285,6 +353,15 @@@ static void update_shadow_stats(struct 
                update_stats(&runtime_nsecs_stats[0], count[0]);
        else if (perf_evsel__match(counter, HARDWARE, HW_CPU_CYCLES))
                update_stats(&runtime_cycles_stats[0], count[0]);
 +      else if (transaction_run &&
 +               perf_evsel__cmp(counter, nth_evsel(T_CYCLES_IN_TX)))
 +              update_stats(&runtime_cycles_in_tx_stats[0], count[0]);
 +      else if (transaction_run &&
 +               perf_evsel__cmp(counter, nth_evsel(T_TRANSACTION_START)))
 +              update_stats(&runtime_transaction_stats[0], count[0]);
 +      else if (transaction_run &&
 +               perf_evsel__cmp(counter, nth_evsel(T_ELISION_START)))
 +              update_stats(&runtime_elision_stats[0], count[0]);
        else if (perf_evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_FRONTEND))
                update_stats(&runtime_stalled_cycles_front_stats[0], count[0]);
        else if (perf_evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_BACKEND))
@@@ -534,6 -457,7 +534,7 @@@ static int __run_perf_stat(int argc, co
                        perror("failed to prepare workload");
                        return -1;
                }
+               child_pid = evsel_list->workload.pid;
        }
  
        if (group)
@@@ -904,7 -828,7 +905,7 @@@ static void print_ll_cache_misses(int c
  
  static void abs_printout(int cpu, int nr, struct perf_evsel *evsel, double avg)
  {
 -      double total, ratio = 0.0;
 +      double total, ratio = 0.0, total2;
        const char *fmt;
  
        if (csv_output)
                        ratio = 1.0 * avg / total;
  
                fprintf(output, " # %8.3f GHz                    ", ratio);
 +      } else if (transaction_run &&
 +                 perf_evsel__cmp(evsel, nth_evsel(T_CYCLES_IN_TX))) {
 +              total = avg_stats(&runtime_cycles_stats[cpu]);
 +              if (total)
 +                      fprintf(output,
 +                              " #   %5.2f%% transactional cycles   ",
 +                              100.0 * (avg / total));
 +      } else if (transaction_run &&
 +                 perf_evsel__cmp(evsel, nth_evsel(T_CYCLES_IN_TX_CP))) {
 +              total = avg_stats(&runtime_cycles_stats[cpu]);
 +              total2 = avg_stats(&runtime_cycles_in_tx_stats[cpu]);
 +              if (total2 < avg)
 +                      total2 = avg;
 +              if (total)
 +                      fprintf(output,
 +                              " #   %5.2f%% aborted cycles         ",
 +                              100.0 * ((total2-avg) / total));
 +      } else if (transaction_run &&
 +                 perf_evsel__cmp(evsel, nth_evsel(T_TRANSACTION_START)) &&
 +                 avg > 0 &&
 +                 runtime_cycles_in_tx_stats[cpu].n != 0) {
 +              total = avg_stats(&runtime_cycles_in_tx_stats[cpu]);
 +
 +              if (total)
 +                      ratio = total / avg;
 +
 +              fprintf(output, " # %8.0f cycles / transaction   ", ratio);
 +      } else if (transaction_run &&
 +                 perf_evsel__cmp(evsel, nth_evsel(T_ELISION_START)) &&
 +                 avg > 0 &&
 +                 runtime_cycles_in_tx_stats[cpu].n != 0) {
 +              total = avg_stats(&runtime_cycles_in_tx_stats[cpu]);
 +
 +              if (total)
 +                      ratio = total / avg;
 +
 +              fprintf(output, " # %8.0f cycles / elision       ", ratio);
        } else if (runtime_nsecs_stats[cpu].n != 0) {
                char unit = 'M';
  
@@@ -1350,16 -1237,6 +1351,16 @@@ static int perf_stat_init_aggr_mode(voi
        return 0;
  }
  
 +static int setup_events(const char * const *attrs, unsigned len)
 +{
 +      unsigned i;
 +
 +      for (i = 0; i < len; i++) {
 +              if (parse_events(evsel_list, attrs[i]))
 +                      return -1;
 +      }
 +      return 0;
 +}
  
  /*
   * Add default attributes, if there were no attributes specified or
@@@ -1478,22 -1355,6 +1479,22 @@@ static int add_default_attributes(void
        if (null_run)
                return 0;
  
 +      if (transaction_run) {
 +              int err;
 +              if (pmu_have_event("cpu", "cycles-ct") &&
 +                  pmu_have_event("cpu", "el-start"))
 +                      err = setup_events(transaction_attrs,
 +                                      ARRAY_SIZE(transaction_attrs));
 +              else
 +                      err = setup_events(transaction_limited_attrs,
 +                               ARRAY_SIZE(transaction_limited_attrs));
 +              if (err < 0) {
 +                      fprintf(stderr, "Cannot set up transaction events\n");
 +                      return -1;
 +              }
 +              return 0;
 +      }
 +
        if (!evsel_list->nr_entries) {
                if (perf_evlist__add_default_attrs(evsel_list, default_attrs) < 0)
                        return -1;
@@@ -1528,8 -1389,6 +1529,8 @@@ int cmd_stat(int argc, const char **arg
        int output_fd = 0;
        const char *output_name = NULL;
        const struct option options[] = {
 +      OPT_BOOLEAN('T', "transaction", &transaction_run,
 +                  "hardware transaction statistics"),
        OPT_CALLBACK('e', "event", &evsel_list, "event",
                     "event selector. use 'perf list' to list available events",
                     parse_events_option),
index 211b325791ad4e53bdd944eda7344461f19f5310,568b750c01f60b3d81cda29966ed40534a7bc8e1..b97f468af955df09e888bf12c2af02551beab08d
@@@ -256,6 -256,8 +256,8 @@@ void perf_tool__fill_defaults(struct pe
                tool->sample = process_event_sample_stub;
        if (tool->mmap == NULL)
                tool->mmap = process_event_stub;
+       if (tool->mmap2 == NULL)
+               tool->mmap2 = process_event_stub;
        if (tool->comm == NULL)
                tool->comm = process_event_stub;
        if (tool->fork == NULL)
@@@ -858,9 -860,6 +860,9 @@@ static void dump_sample(struct perf_evs
        if (sample_type & PERF_SAMPLE_DATA_SRC)
                printf(" . data_src: 0x%"PRIx64"\n", sample->data_src);
  
 +      if (sample_type & PERF_SAMPLE_TRANSACTION)
 +              printf("... transaction: %" PRIx64 "\n", sample->transaction);
 +
        if (sample_type & PERF_SAMPLE_READ)
                sample_read__printf(sample, evsel->attr.read_format);
  }
@@@ -1313,7 -1312,7 +1315,7 @@@ int __perf_session__process_events(stru
        file_offset = page_offset;
        head = data_offset - page_offset;
  
-       if (data_offset + data_size < file_size)
+       if (data_size && (data_offset + data_size < file_size))
                file_size = data_offset + data_size;
  
        progress_next = file_size / 16;
This page took 0.099333 seconds and 4 git commands to generate.