Skip to content

Commit

Permalink
Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux…
Browse files Browse the repository at this point in the history
…/kernel/git/acme/linux into perf/core

Pull perf/core improvements and fixes from  Arnaldo Carvalho de Melo:

 * Fix handling of unresolved samples when --symbols is used in 'report',
   from Feng Tang.

 * Add --symbols to 'script', similar to the one in 'report', from Feng Tang.

 * Add union member access support to 'probe', from Hyeoncheol Lee.

 * Make 'archive' work on Android, tweaking some of the utility parameters
   used (tar, rm), from Irina Tirdea.

 * Fixups to die() removal, from Namhyung Kim.

 * Render fixes for the TUI, from Namhyung Kim.

 * Don't enable annotation in non symbolic view, from Namhyung Kim.

 * Fix pipe mode in 'report', from Namhyung Kim.

 * Move related stats code from stat to util/, will be used by the 'stat'
   kvm tool, from Xiao Guangrong.

 * Add cpumask for uncore pmu, use it in 'stat', from Yan, Zheng.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
  • Loading branch information
Ingo Molnar committed Sep 19, 2012
2 parents 26f4527 + 7ae92e7 commit bea8f35
Show file tree
Hide file tree
Showing 29 changed files with 318 additions and 126 deletions.
28 changes: 25 additions & 3 deletions arch/x86/kernel/cpu/perf_event_intel_uncore.c
Original file line number Diff line number Diff line change
Expand Up @@ -2341,6 +2341,27 @@ int uncore_pmu_event_init(struct perf_event *event)
return ret;
}

static ssize_t uncore_get_attr_cpumask(struct device *dev,
struct device_attribute *attr, char *buf)
{
int n = cpulist_scnprintf(buf, PAGE_SIZE - 2, &uncore_cpu_mask);

buf[n++] = '\n';
buf[n] = '\0';
return n;
}

static DEVICE_ATTR(cpumask, S_IRUGO, uncore_get_attr_cpumask, NULL);

static struct attribute *uncore_pmu_attrs[] = {
&dev_attr_cpumask.attr,
NULL,
};

static struct attribute_group uncore_pmu_attr_group = {
.attrs = uncore_pmu_attrs,
};

static int __init uncore_pmu_register(struct intel_uncore_pmu *pmu)
{
int ret;
Expand Down Expand Up @@ -2378,8 +2399,8 @@ static void __init uncore_type_exit(struct intel_uncore_type *type)
free_percpu(type->pmus[i].box);
kfree(type->pmus);
type->pmus = NULL;
kfree(type->attr_groups[1]);
type->attr_groups[1] = NULL;
kfree(type->events_group);
type->events_group = NULL;
}

static void __init uncore_types_exit(struct intel_uncore_type **types)
Expand Down Expand Up @@ -2431,9 +2452,10 @@ static int __init uncore_type_init(struct intel_uncore_type *type)
for (j = 0; j < i; j++)
attrs[j] = &type->event_descs[j].attr.attr;

type->attr_groups[1] = events_group;
type->events_group = events_group;
}

type->pmu_group = &uncore_pmu_attr_group;
type->pmus = pmus;
return 0;
fail:
Expand Down
6 changes: 4 additions & 2 deletions arch/x86/kernel/cpu/perf_event_intel_uncore.h
Original file line number Diff line number Diff line change
Expand Up @@ -369,10 +369,12 @@ struct intel_uncore_type {
struct intel_uncore_pmu *pmus;
struct intel_uncore_ops *ops;
struct uncore_event_desc *event_descs;
const struct attribute_group *attr_groups[3];
const struct attribute_group *attr_groups[4];
};

#define format_group attr_groups[0]
#define pmu_group attr_groups[0]
#define format_group attr_groups[1]
#define events_group attr_groups[2]

struct intel_uncore_ops {
void (*init_box)(struct intel_uncore_box *);
Expand Down
2 changes: 1 addition & 1 deletion tools/lib/traceevent/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ CFLAGS ?= -g -Wall

# Append required CFLAGS
override CFLAGS += $(CONFIG_FLAGS) $(INCLUDES) $(PLUGIN_DIR_SQ)
override CFLAGS += $(udis86-flags)
override CFLAGS += $(udis86-flags) -D_GNU_SOURCE

ifeq ($(VERBOSE),1)
Q =
Expand Down
1 change: 0 additions & 1 deletion tools/lib/traceevent/event-parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
* Frederic Weisbecker gave his permission to relicense the code to
* the Lesser General Public License.
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Expand Down
1 change: 1 addition & 0 deletions tools/perf/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,7 @@ LIB_OBJS += $(OUTPUT)util/target.o
LIB_OBJS += $(OUTPUT)util/rblist.o
LIB_OBJS += $(OUTPUT)util/intlist.o
LIB_OBJS += $(OUTPUT)util/vdso.o
LIB_OBJS += $(OUTPUT)util/stat.o

LIB_OBJS += $(OUTPUT)ui/helpline.o
LIB_OBJS += $(OUTPUT)ui/hist.o
Expand Down
16 changes: 9 additions & 7 deletions tools/perf/builtin-report.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ static int perf_report__add_branch_hist_entry(struct perf_tool *tool,
struct annotation *notes;
err = -ENOMEM;
bx = he->branch_info;
if (bx->from.sym && use_browser > 0) {
if (bx->from.sym && use_browser == 1 && sort__has_sym) {
notes = symbol__annotation(bx->from.sym);
if (!notes->src
&& symbol__alloc_hist(bx->from.sym) < 0)
Expand All @@ -107,7 +107,7 @@ static int perf_report__add_branch_hist_entry(struct perf_tool *tool,
goto out;
}

if (bx->to.sym && use_browser > 0) {
if (bx->to.sym && use_browser == 1 && sort__has_sym) {
notes = symbol__annotation(bx->to.sym);
if (!notes->src
&& symbol__alloc_hist(bx->to.sym) < 0)
Expand Down Expand Up @@ -162,7 +162,7 @@ static int perf_evsel__add_hist_entry(struct perf_evsel *evsel,
* so we don't allocated the extra space needed because the stdio
* code will not use it.
*/
if (he->ms.sym != NULL && use_browser > 0) {
if (he->ms.sym != NULL && use_browser == 1 && sort__has_sym) {
struct annotation *notes = symbol__annotation(he->ms.sym);

assert(evsel != NULL);
Expand Down Expand Up @@ -689,15 +689,19 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)

if (strcmp(report.input_name, "-") != 0)
setup_browser(true);
else
else {
use_browser = 0;
perf_hpp__init(false, false);
}

setup_sorting(report_usage, options);

/*
* Only in the newt browser we are doing integrated annotation,
* so don't allocate extra space that won't be used in the stdio
* implementation.
*/
if (use_browser > 0) {
if (use_browser == 1 && sort__has_sym) {
symbol_conf.priv_size = sizeof(struct annotation);
report.annotate_init = symbol__annotate_init;
/*
Expand All @@ -720,8 +724,6 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
if (symbol__init() < 0)
goto error;

setup_sorting(report_usage, options);

if (parent_pattern != default_parent_pattern) {
if (sort_dimension__add("parent") < 0)
goto error;
Expand Down
14 changes: 7 additions & 7 deletions tools/perf/builtin-sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -438,8 +438,8 @@ static int self_open_counters(void)
fd = sys_perf_event_open(&attr, 0, -1, -1, 0);

if (fd < 0)
pr_debug("Error: sys_perf_event_open() syscall returned"
"with %d (%s)\n", fd, strerror(errno));
pr_err("Error: sys_perf_event_open() syscall returned "
"with %d (%s)\n", fd, strerror(errno));
return fd;
}

Expand Down Expand Up @@ -700,7 +700,7 @@ static int replay_switch_event(struct perf_sched *sched,
delta = 0;

if (delta < 0) {
pr_debug("hm, delta: %" PRIu64 " < 0 ?\n", delta);
pr_err("hm, delta: %" PRIu64 " < 0 ?\n", delta);
return -1;
}

Expand Down Expand Up @@ -990,7 +990,7 @@ static int latency_runtime_event(struct perf_sched *sched,
return -1;
atoms = thread_atoms_search(&sched->atom_root, thread, &sched->cmp_pid);
if (!atoms) {
pr_debug("in-event: Internal tree error");
pr_err("in-event: Internal tree error");
return -1;
}
if (add_sched_out_event(atoms, 'R', timestamp))
Expand Down Expand Up @@ -1024,7 +1024,7 @@ static int latency_wakeup_event(struct perf_sched *sched,
return -1;
atoms = thread_atoms_search(&sched->atom_root, wakee, &sched->cmp_pid);
if (!atoms) {
pr_debug("wakeup-event: Internal tree error");
pr_err("wakeup-event: Internal tree error");
return -1;
}
if (add_sched_out_event(atoms, 'S', timestamp))
Expand Down Expand Up @@ -1079,7 +1079,7 @@ static int latency_migrate_task_event(struct perf_sched *sched,
register_pid(sched, migrant->pid, migrant->comm);
atoms = thread_atoms_search(&sched->atom_root, migrant, &sched->cmp_pid);
if (!atoms) {
pr_debug("migration-event: Internal tree error");
pr_err("migration-event: Internal tree error");
return -1;
}
if (add_sched_out_event(atoms, 'R', timestamp))
Expand Down Expand Up @@ -1286,7 +1286,7 @@ static int map_switch_event(struct perf_sched *sched, struct perf_evsel *evsel,
delta = 0;

if (delta < 0) {
pr_debug("hm, delta: %" PRIu64 " < 0 ?\n", delta);
pr_err("hm, delta: %" PRIu64 " < 0 ?\n", delta);
return -1;
}

Expand Down
58 changes: 58 additions & 0 deletions tools/perf/builtin-script.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "util/util.h"
#include "util/evlist.h"
#include "util/evsel.h"
#include "util/sort.h"
#include <linux/bitmap.h>

static char const *script_name;
Expand Down Expand Up @@ -1031,6 +1032,61 @@ static int list_available_scripts(const struct option *opt __maybe_unused,
exit(0);
}

/*
* Return -1 if none is found, otherwise the actual scripts number.
*
* Currently the only user of this function is the script browser, which
* will list all statically runnable scripts, select one, execute it and
* show the output in a perf browser.
*/
int find_scripts(char **scripts_array, char **scripts_path_array)
{
struct dirent *script_next, *lang_next, script_dirent, lang_dirent;
char scripts_path[MAXPATHLEN];
DIR *scripts_dir, *lang_dir;
char lang_path[MAXPATHLEN];
char *temp;
int i = 0;

snprintf(scripts_path, MAXPATHLEN, "%s/scripts", perf_exec_path());

scripts_dir = opendir(scripts_path);
if (!scripts_dir)
return -1;

for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) {
snprintf(lang_path, MAXPATHLEN, "%s/%s", scripts_path,
lang_dirent.d_name);
#ifdef NO_LIBPERL
if (strstr(lang_path, "perl"))
continue;
#endif
#ifdef NO_LIBPYTHON
if (strstr(lang_path, "python"))
continue;
#endif

lang_dir = opendir(lang_path);
if (!lang_dir)
continue;

for_each_script(lang_path, lang_dir, script_dirent, script_next) {
/* Skip those real time scripts: xxxtop.p[yl] */
if (strstr(script_dirent.d_name, "top."))
continue;
sprintf(scripts_path_array[i], "%s/%s", lang_path,
script_dirent.d_name);
temp = strchr(script_dirent.d_name, '.');
snprintf(scripts_array[i],
(temp - script_dirent.d_name) + 1,
"%s", script_dirent.d_name);
i++;
}
}

return i;
}

static char *get_script_path(const char *script_root, const char *suffix)
{
struct dirent *script_next, *lang_next, script_dirent, lang_dirent;
Expand Down Expand Up @@ -1143,6 +1199,8 @@ static const struct option options[] = {
parse_output_fields),
OPT_BOOLEAN('a', "all-cpus", &system_wide,
"system-wide collection from all CPUs"),
OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]",
"only consider these symbols"),
OPT_STRING('C', "cpu", &cpu_list, "cpu", "list of cpus to profile"),
OPT_STRING('c', "comms", &symbol_conf.comm_list_str, "comm[,comm...]",
"only display events for these comms"),
Expand Down
Loading

0 comments on commit bea8f35

Please sign in to comment.