Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 25 Jan 2014 19:12:23 +0000 (11:12 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 25 Jan 2014 19:12:23 +0000 (11:12 -0800)
Pull perf fixes from Ingo Molnar:
 "A handful of tooling fixes"

* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  perf symbols: Load map before using map->map_ip()
  perf tools: Fix traceevent plugin path definitions
  perf symbols: Fix JIT symbol resolution on heap
  perf stat: Fix memory corruption of xyarray when cpumask is used
  perf evsel: Remove duplicate member zeroing after free
  perf tools: Ensure sscanf does not overrun the "mem" field
  perf stat: fix NULL pointer reference bug with event unit
  perf tools: Add support for the xtensa architecture
  perf session: Free cpu_map in perf_session__cpu_bitmap
  perf timechart: Fix wrong SVG height

12 files changed:
tools/lib/traceevent/Makefile
tools/perf/builtin-timechart.c
tools/perf/config/Makefile
tools/perf/perf.h
tools/perf/util/evlist.c
tools/perf/util/evsel.c
tools/perf/util/header.c
tools/perf/util/map.c
tools/perf/util/parse-events.c
tools/perf/util/pmu.c
tools/perf/util/pmu.h
tools/perf/util/session.c

index 56d52a33a3dfcff26838ddbf6ef1f5257bb9a331..005c9cc0693593bf4ca197e13784f59118e2c5c1 100644 (file)
@@ -63,7 +63,7 @@ endif
 endif
 
 ifeq ($(set_plugin_dir),1)
-PLUGIN_DIR = -DPLUGIN_DIR="$(DESTDIR)/$(plugin_dir)"
+PLUGIN_DIR = -DPLUGIN_DIR="$(plugin_dir)"
 PLUGIN_DIR_SQ = '$(subst ','\'',$(PLUGIN_DIR))'
 endif
 
index 652af0b66a625305deac34b0f18ec2e5ccf1d8f0..25526d6eae59f65a4a0405c9186d93b9cd5d3d59 100644 (file)
@@ -1045,6 +1045,9 @@ static void write_svg_file(struct timechart *tchart, const char *filename)
                thresh /= 10;
        } while (!process_filter && thresh && count < tchart->proc_num);
 
+       if (!tchart->proc_num)
+               count = 0;
+
        open_svg(filename, tchart->numcpus, count, tchart->first_time, tchart->last_time);
 
        svg_time_grid();
index d604e50fc167b232ad50c3c7cde967c9a0ccd0cf..c48d44958172b7dd8f75634ece4d909ae2d5b15b 100644 (file)
@@ -600,5 +600,5 @@ perfexec_instdir_SQ = $(subst ','\'',$(perfexec_instdir))
 # Otherwise we install plugins into the global $(libdir).
 ifdef DESTDIR
 plugindir=$(libdir)/traceevent/plugins
-plugindir_SQ= $(subst ','\'',$(prefix)/$(plugindir))
+plugindir_SQ= $(subst ','\'',$(plugindir))
 endif
index 3c2f213e979d45d5d1d2c701a6f2b8875e36e13a..7daa806d9050246c336a9121ca8cf7d00c828020 100644 (file)
 #define CPUINFO_PROC   "CPU"
 #endif
 
+#ifdef __xtensa__
+#define mb()           asm volatile("memw" ::: "memory")
+#define wmb()          asm volatile("memw" ::: "memory")
+#define rmb()          asm volatile("" ::: "memory")
+#define CPUINFO_PROC   "core ID"
+#endif
+
 #define barrier() asm volatile ("" ::: "memory")
 
 #ifndef cpu_relax
index 40bd2c04df8ad7cb02e713e4f02a832850b0a43f..59ef2802fcf631fa0e7d6f2f97e59e6881f675d4 100644 (file)
@@ -1003,9 +1003,12 @@ void perf_evlist__close(struct perf_evlist *evlist)
        struct perf_evsel *evsel;
        int ncpus = cpu_map__nr(evlist->cpus);
        int nthreads = thread_map__nr(evlist->threads);
+       int n;
 
-       evlist__for_each_reverse(evlist, evsel)
-               perf_evsel__close(evsel, ncpus, nthreads);
+       evlist__for_each_reverse(evlist, evsel) {
+               n = evsel->cpus ? evsel->cpus->nr : ncpus;
+               perf_evsel__close(evsel, n, nthreads);
+       }
 }
 
 int perf_evlist__open(struct perf_evlist *evlist)
index 22e18a26b7e6c778aefe5fb44c0cd518b5ff798d..55407c594b87f1657e8ff06f8e64ee27ba2662c2 100644 (file)
@@ -1081,7 +1081,6 @@ void perf_evsel__close(struct perf_evsel *evsel, int ncpus, int nthreads)
 
        perf_evsel__close_fd(evsel, ncpus, nthreads);
        perf_evsel__free_fd(evsel);
-       evsel->fd = NULL;
 }
 
 static struct {
index bb3e0ede61835ff249a6c5766daa279d2ab77f6a..893f8e2df9285237b26365922adf9b1eaa88a5ec 100644 (file)
@@ -930,7 +930,7 @@ static int write_topo_node(int fd, int node)
                /* skip over invalid lines */
                if (!strchr(buf, ':'))
                        continue;
-               if (sscanf(buf, "%*s %*d %s %"PRIu64, field, &mem) != 2)
+               if (sscanf(buf, "%*s %*d %31s %"PRIu64, field, &mem) != 2)
                        goto done;
                if (!strcmp(field, "MemTotal:"))
                        mem_total = mem;
index 9b9bd719aa197d0a240809834109581a57d810b2..3b97513f0e7714738e63479049e59f138b22871c 100644 (file)
@@ -69,7 +69,7 @@ struct map *map__new(struct list_head *dsos__list, u64 start, u64 len,
                map->ino = ino;
                map->ino_generation = ino_gen;
 
-               if (anon) {
+               if ((anon || no_dso) && type == MAP__FUNCTION) {
                        snprintf(newfilename, sizeof(newfilename), "/tmp/perf-%d.map", pid);
                        filename = newfilename;
                }
@@ -93,7 +93,7 @@ struct map *map__new(struct list_head *dsos__list, u64 start, u64 len,
                         * functions still return NULL, and we avoid the
                         * unnecessary map__load warning.
                         */
-                       if (no_dso)
+                       if (type != MAP__FUNCTION)
                                dso__set_loaded(dso, map->type);
                }
        }
@@ -386,7 +386,8 @@ struct symbol *map_groups__find_symbol(struct map_groups *mg,
 {
        struct map *map = map_groups__find(mg, type, addr);
 
-       if (map != NULL) {
+       /* Ensure map is loaded before using map->map_ip */
+       if (map != NULL && map__load(map, filter) >= 0) {
                if (mapp != NULL)
                        *mapp = map;
                return map__find_symbol(map, map->map_ip(map, addr), filter);
index a7f1b6a91fdd56b699fcac7f0b0adbaedd7e0a92..d248fca6d7ed7302c77d5500a79c853d3073ea07 100644 (file)
@@ -635,7 +635,7 @@ int parse_events_add_pmu(struct list_head *list, int *idx,
        struct perf_event_attr attr;
        struct perf_pmu *pmu;
        struct perf_evsel *evsel;
-       char *unit;
+       const char *unit;
        double scale;
 
        pmu = perf_pmu__find(name);
index d9cab4d271924a41e98658a3d28808b06546b80f..b752ecb40d86af6245b7f8646bb3607992bcd9f6 100644 (file)
@@ -105,7 +105,7 @@ static int perf_pmu__parse_scale(struct perf_pmu_alias *alias, char *dir, char *
        char scale[128];
        int fd, ret = -1;
        char path[PATH_MAX];
-       char *lc;
+       const char *lc;
 
        snprintf(path, PATH_MAX, "%s/%s.scale", dir, name);
 
@@ -609,7 +609,7 @@ static struct perf_pmu_alias *pmu_find_alias(struct perf_pmu *pmu,
 
 
 static int check_unit_scale(struct perf_pmu_alias *alias,
-                           char **unit, double *scale)
+                           const char **unit, double *scale)
 {
        /*
         * Only one term in event definition can
@@ -634,14 +634,18 @@ static int check_unit_scale(struct perf_pmu_alias *alias,
  * defined for the alias
  */
 int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms,
-                         char **unit, double *scale)
+                         const char **unit, double *scale)
 {
        struct parse_events_term *term, *h;
        struct perf_pmu_alias *alias;
        int ret;
 
+       /*
+        * Mark unit and scale as not set
+        * (different from default values, see below)
+        */
        *unit   = NULL;
-       *scale  = 0;
+       *scale  = 0.0;
 
        list_for_each_entry_safe(term, h, head_terms, list) {
                alias = pmu_find_alias(pmu, term);
@@ -658,6 +662,18 @@ int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms,
                list_del(&term->list);
                free(term);
        }
+
+       /*
+        * if no unit or scale foundin aliases, then
+        * set defaults as for evsel
+        * unit cannot left to NULL
+        */
+       if (*unit == NULL)
+               *unit   = "";
+
+       if (*scale == 0.0)
+               *scale  = 1.0;
+
        return 0;
 }
 
index 9183380e203851b8fb12f0bcee499b61dcda0f58..8b64125a92811885984912b5c8c3fac719a5c57c 100644 (file)
@@ -29,7 +29,7 @@ int perf_pmu__config_terms(struct list_head *formats,
                           struct perf_event_attr *attr,
                           struct list_head *head_terms);
 int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms,
-                         char **unit, double *scale);
+                         const char **unit, double *scale);
 struct list_head *perf_pmu__alias(struct perf_pmu *pmu,
                                  struct list_head *head_terms);
 int perf_pmu_wrap(void);
index 7acc03e8f3b2eabaf7bdb5620ea463ba6cacabb5..0b39a48e5110a00dde5fa0408c725730ba5fe8ff 100644 (file)
@@ -1573,7 +1573,7 @@ next:
 int perf_session__cpu_bitmap(struct perf_session *session,
                             const char *cpu_list, unsigned long *cpu_bitmap)
 {
-       int i;
+       int i, err = -1;
        struct cpu_map *map;
 
        for (i = 0; i < PERF_TYPE_MAX; ++i) {
@@ -1602,13 +1602,17 @@ int perf_session__cpu_bitmap(struct perf_session *session,
                if (cpu >= MAX_NR_CPUS) {
                        pr_err("Requested CPU %d too large. "
                               "Consider raising MAX_NR_CPUS\n", cpu);
-                       return -1;
+                       goto out_delete_map;
                }
 
                set_bit(cpu, cpu_bitmap);
        }
 
-       return 0;
+       err = 0;
+
+out_delete_map:
+       cpu_map__delete(map);
+       return err;
 }
 
 void perf_session__fprintf_info(struct perf_session *session, FILE *fp,