Commit 82c47766 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

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
parents f6d13daa 993e5ee6
...@@ -63,7 +63,7 @@ endif ...@@ -63,7 +63,7 @@ endif
endif endif
ifeq ($(set_plugin_dir),1) ifeq ($(set_plugin_dir),1)
PLUGIN_DIR = -DPLUGIN_DIR="$(DESTDIR)/$(plugin_dir)" PLUGIN_DIR = -DPLUGIN_DIR="$(plugin_dir)"
PLUGIN_DIR_SQ = '$(subst ','\'',$(PLUGIN_DIR))' PLUGIN_DIR_SQ = '$(subst ','\'',$(PLUGIN_DIR))'
endif endif
......
...@@ -1045,6 +1045,9 @@ static void write_svg_file(struct timechart *tchart, const char *filename) ...@@ -1045,6 +1045,9 @@ static void write_svg_file(struct timechart *tchart, const char *filename)
thresh /= 10; thresh /= 10;
} while (!process_filter && thresh && count < tchart->proc_num); } 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); open_svg(filename, tchart->numcpus, count, tchart->first_time, tchart->last_time);
svg_time_grid(); svg_time_grid();
......
...@@ -600,5 +600,5 @@ perfexec_instdir_SQ = $(subst ','\'',$(perfexec_instdir)) ...@@ -600,5 +600,5 @@ perfexec_instdir_SQ = $(subst ','\'',$(perfexec_instdir))
# Otherwise we install plugins into the global $(libdir). # Otherwise we install plugins into the global $(libdir).
ifdef DESTDIR ifdef DESTDIR
plugindir=$(libdir)/traceevent/plugins plugindir=$(libdir)/traceevent/plugins
plugindir_SQ= $(subst ','\'',$(prefix)/$(plugindir)) plugindir_SQ= $(subst ','\'',$(plugindir))
endif endif
...@@ -132,6 +132,13 @@ ...@@ -132,6 +132,13 @@
#define CPUINFO_PROC "CPU" #define CPUINFO_PROC "CPU"
#endif #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") #define barrier() asm volatile ("" ::: "memory")
#ifndef cpu_relax #ifndef cpu_relax
......
...@@ -1003,9 +1003,12 @@ void perf_evlist__close(struct perf_evlist *evlist) ...@@ -1003,9 +1003,12 @@ void perf_evlist__close(struct perf_evlist *evlist)
struct perf_evsel *evsel; struct perf_evsel *evsel;
int ncpus = cpu_map__nr(evlist->cpus); int ncpus = cpu_map__nr(evlist->cpus);
int nthreads = thread_map__nr(evlist->threads); int nthreads = thread_map__nr(evlist->threads);
int n;
evlist__for_each_reverse(evlist, evsel) evlist__for_each_reverse(evlist, evsel) {
perf_evsel__close(evsel, ncpus, nthreads); n = evsel->cpus ? evsel->cpus->nr : ncpus;
perf_evsel__close(evsel, n, nthreads);
}
} }
int perf_evlist__open(struct perf_evlist *evlist) int perf_evlist__open(struct perf_evlist *evlist)
......
...@@ -1081,7 +1081,6 @@ void perf_evsel__close(struct perf_evsel *evsel, int ncpus, int nthreads) ...@@ -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__close_fd(evsel, ncpus, nthreads);
perf_evsel__free_fd(evsel); perf_evsel__free_fd(evsel);
evsel->fd = NULL;
} }
static struct { static struct {
......
...@@ -930,7 +930,7 @@ static int write_topo_node(int fd, int node) ...@@ -930,7 +930,7 @@ static int write_topo_node(int fd, int node)
/* skip over invalid lines */ /* skip over invalid lines */
if (!strchr(buf, ':')) if (!strchr(buf, ':'))
continue; continue;
if (sscanf(buf, "%*s %*d %s %"PRIu64, field, &mem) != 2) if (sscanf(buf, "%*s %*d %31s %"PRIu64, field, &mem) != 2)
goto done; goto done;
if (!strcmp(field, "MemTotal:")) if (!strcmp(field, "MemTotal:"))
mem_total = mem; mem_total = mem;
......
...@@ -69,7 +69,7 @@ struct map *map__new(struct list_head *dsos__list, u64 start, u64 len, ...@@ -69,7 +69,7 @@ struct map *map__new(struct list_head *dsos__list, u64 start, u64 len,
map->ino = ino; map->ino = ino;
map->ino_generation = ino_gen; map->ino_generation = ino_gen;
if (anon) { if ((anon || no_dso) && type == MAP__FUNCTION) {
snprintf(newfilename, sizeof(newfilename), "/tmp/perf-%d.map", pid); snprintf(newfilename, sizeof(newfilename), "/tmp/perf-%d.map", pid);
filename = newfilename; filename = newfilename;
} }
...@@ -93,7 +93,7 @@ struct map *map__new(struct list_head *dsos__list, u64 start, u64 len, ...@@ -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 * functions still return NULL, and we avoid the
* unnecessary map__load warning. * unnecessary map__load warning.
*/ */
if (no_dso) if (type != MAP__FUNCTION)
dso__set_loaded(dso, map->type); dso__set_loaded(dso, map->type);
} }
} }
...@@ -386,7 +386,8 @@ struct symbol *map_groups__find_symbol(struct map_groups *mg, ...@@ -386,7 +386,8 @@ struct symbol *map_groups__find_symbol(struct map_groups *mg,
{ {
struct map *map = map_groups__find(mg, type, addr); 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) if (mapp != NULL)
*mapp = map; *mapp = map;
return map__find_symbol(map, map->map_ip(map, addr), filter); return map__find_symbol(map, map->map_ip(map, addr), filter);
......
...@@ -635,7 +635,7 @@ int parse_events_add_pmu(struct list_head *list, int *idx, ...@@ -635,7 +635,7 @@ int parse_events_add_pmu(struct list_head *list, int *idx,
struct perf_event_attr attr; struct perf_event_attr attr;
struct perf_pmu *pmu; struct perf_pmu *pmu;
struct perf_evsel *evsel; struct perf_evsel *evsel;
char *unit; const char *unit;
double scale; double scale;
pmu = perf_pmu__find(name); pmu = perf_pmu__find(name);
......
...@@ -105,7 +105,7 @@ static int perf_pmu__parse_scale(struct perf_pmu_alias *alias, char *dir, char * ...@@ -105,7 +105,7 @@ static int perf_pmu__parse_scale(struct perf_pmu_alias *alias, char *dir, char *
char scale[128]; char scale[128];
int fd, ret = -1; int fd, ret = -1;
char path[PATH_MAX]; char path[PATH_MAX];
char *lc; const char *lc;
snprintf(path, PATH_MAX, "%s/%s.scale", dir, name); 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, ...@@ -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, 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 * Only one term in event definition can
...@@ -634,14 +634,18 @@ static int check_unit_scale(struct perf_pmu_alias *alias, ...@@ -634,14 +634,18 @@ static int check_unit_scale(struct perf_pmu_alias *alias,
* defined for the alias * defined for the alias
*/ */
int perf_pmu__check_alias(struct perf_pmu *pmu, 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 parse_events_term *term, *h; struct parse_events_term *term, *h;
struct perf_pmu_alias *alias; struct perf_pmu_alias *alias;
int ret; int ret;
/*
* Mark unit and scale as not set
* (different from default values, see below)
*/
*unit = NULL; *unit = NULL;
*scale = 0; *scale = 0.0;
list_for_each_entry_safe(term, h, head_terms, list) { list_for_each_entry_safe(term, h, head_terms, list) {
alias = pmu_find_alias(pmu, term); alias = pmu_find_alias(pmu, term);
...@@ -658,6 +662,18 @@ int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms, ...@@ -658,6 +662,18 @@ int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms,
list_del(&term->list); list_del(&term->list);
free(term); 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; return 0;
} }
......
...@@ -29,7 +29,7 @@ int perf_pmu__config_terms(struct list_head *formats, ...@@ -29,7 +29,7 @@ int perf_pmu__config_terms(struct list_head *formats,
struct perf_event_attr *attr, struct perf_event_attr *attr,
struct list_head *head_terms); struct list_head *head_terms);
int perf_pmu__check_alias(struct perf_pmu *pmu, 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 *perf_pmu__alias(struct perf_pmu *pmu,
struct list_head *head_terms); struct list_head *head_terms);
int perf_pmu_wrap(void); int perf_pmu_wrap(void);
......
...@@ -1573,7 +1573,7 @@ void perf_evsel__print_ip(struct perf_evsel *evsel, struct perf_sample *sample, ...@@ -1573,7 +1573,7 @@ void perf_evsel__print_ip(struct perf_evsel *evsel, struct perf_sample *sample,
int perf_session__cpu_bitmap(struct perf_session *session, int perf_session__cpu_bitmap(struct perf_session *session,
const char *cpu_list, unsigned long *cpu_bitmap) const char *cpu_list, unsigned long *cpu_bitmap)
{ {
int i; int i, err = -1;
struct cpu_map *map; struct cpu_map *map;
for (i = 0; i < PERF_TYPE_MAX; ++i) { for (i = 0; i < PERF_TYPE_MAX; ++i) {
...@@ -1602,13 +1602,17 @@ int perf_session__cpu_bitmap(struct perf_session *session, ...@@ -1602,13 +1602,17 @@ int perf_session__cpu_bitmap(struct perf_session *session,
if (cpu >= MAX_NR_CPUS) { if (cpu >= MAX_NR_CPUS) {
pr_err("Requested CPU %d too large. " pr_err("Requested CPU %d too large. "
"Consider raising MAX_NR_CPUS\n", cpu); "Consider raising MAX_NR_CPUS\n", cpu);
return -1; goto out_delete_map;
} }
set_bit(cpu, cpu_bitmap); 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, void perf_session__fprintf_info(struct perf_session *session, FILE *fp,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment