Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d14aef38 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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

Pull perf fixes from Ingo Molnar:
 "Tooling fixes and an Intel PMU driver fixlet"

* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  perf: Do not allow optimized switch for non-cloned events
  perf/x86/intel: ignore CondChgd bit to avoid false NMI handling
  perf symbols: Get kernel start address by symbol name
  perf tools: Fix segfault in cumulative.callchain report
parents 2da29447 1f9a7268
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -1381,6 +1381,15 @@ static int intel_pmu_handle_irq(struct pt_regs *regs)

	intel_pmu_lbr_read();

	/*
	 * CondChgd bit 63 doesn't mean any overflow status. Ignore
	 * and clear the bit.
	 */
	if (__test_and_clear_bit(63, (unsigned long *)&status)) {
		if (!status)
			goto done;
	}

	/*
	 * PEBS overflow sets bit 62 in the global status register
	 */
+1 −1
Original line number Diff line number Diff line
@@ -2320,7 +2320,7 @@ static void perf_event_context_sched_out(struct task_struct *task, int ctxn,
	next_parent = rcu_dereference(next_ctx->parent_ctx);

	/* If neither context have a parent context; they cannot be clones. */
	if (!parent && !next_parent)
	if (!parent || !next_parent)
		goto unlock;

	if (next_parent == ctx || next_ctx == parent || next_parent == parent) {
+16 −5
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include "../util.h"
#include "../ui.h"
#include "map.h"
#include "annotate.h"

struct hist_browser {
	struct ui_browser   b;
@@ -1593,14 +1594,19 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
					 bi->to.sym->name) > 0)
				annotate_t = nr_options++;
		} else {

			if (browser->selection != NULL &&
			    browser->selection->sym != NULL &&
			    !browser->selection->map->dso->annotate_warned &&
			    !browser->selection->map->dso->annotate_warned) {
				struct annotation *notes;

				notes = symbol__annotation(browser->selection->sym);

				if (notes->src &&
				    asprintf(&options[nr_options], "Annotate %s",
						 browser->selection->sym->name) > 0)
					annotate = nr_options++;
			}
		}

		if (thread != NULL &&
		    asprintf(&options[nr_options], "Zoom %s %s(%d) thread",
@@ -1656,6 +1662,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,

		if (choice == annotate || choice == annotate_t || choice == annotate_f) {
			struct hist_entry *he;
			struct annotation *notes;
			int err;
do_annotate:
			if (!objdump_path && perf_session_env__lookup_objdump(env))
@@ -1679,6 +1686,10 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
				he->ms.map = he->branch_info->to.map;
			}

			notes = symbol__annotation(he->ms.sym);
			if (!notes->src)
				continue;

			/*
			 * Don't let this be freed, say, by hists__decay_entry.
			 */
+22 −32
Original line number Diff line number Diff line
@@ -496,18 +496,6 @@ struct process_args {
	u64 start;
};

static int symbol__in_kernel(void *arg, const char *name,
			     char type __maybe_unused, u64 start)
{
	struct process_args *args = arg;

	if (strchr(name, '['))
		return 0;

	args->start = start;
	return 1;
}

static void machine__get_kallsyms_filename(struct machine *machine, char *buf,
					   size_t bufsz)
{
@@ -517,27 +505,41 @@ static void machine__get_kallsyms_filename(struct machine *machine, char *buf,
		scnprintf(buf, bufsz, "%s/proc/kallsyms", machine->root_dir);
}

/* Figure out the start address of kernel map from /proc/kallsyms */
static u64 machine__get_kernel_start_addr(struct machine *machine)
const char *ref_reloc_sym_names[] = {"_text", "_stext", NULL};

/* Figure out the start address of kernel map from /proc/kallsyms.
 * Returns the name of the start symbol in *symbol_name. Pass in NULL as
 * symbol_name if it's not that important.
 */
static u64 machine__get_kernel_start_addr(struct machine *machine,
					  const char **symbol_name)
{
	char filename[PATH_MAX];
	struct process_args args;
	int i;
	const char *name;
	u64 addr = 0;

	machine__get_kallsyms_filename(machine, filename, PATH_MAX);

	if (symbol__restricted_filename(filename, "/proc/kallsyms"))
		return 0;

	if (kallsyms__parse(filename, &args, symbol__in_kernel) <= 0)
		return 0;
	for (i = 0; (name = ref_reloc_sym_names[i]) != NULL; i++) {
		addr = kallsyms__get_function_start(filename, name);
		if (addr)
			break;
	}

	return args.start;
	if (symbol_name)
		*symbol_name = name;

	return addr;
}

int __machine__create_kernel_maps(struct machine *machine, struct dso *kernel)
{
	enum map_type type;
	u64 start = machine__get_kernel_start_addr(machine);
	u64 start = machine__get_kernel_start_addr(machine, NULL);

	for (type = 0; type < MAP__NR_TYPES; ++type) {
		struct kmap *kmap;
@@ -852,23 +854,11 @@ static int machine__create_modules(struct machine *machine)
	return 0;
}

const char *ref_reloc_sym_names[] = {"_text", "_stext", NULL};

int machine__create_kernel_maps(struct machine *machine)
{
	struct dso *kernel = machine__get_kernel(machine);
	char filename[PATH_MAX];
	const char *name;
	u64 addr = 0;
	int i;

	machine__get_kallsyms_filename(machine, filename, PATH_MAX);

	for (i = 0; (name = ref_reloc_sym_names[i]) != NULL; i++) {
		addr = kallsyms__get_function_start(filename, name);
		if (addr)
			break;
	}
	u64 addr = machine__get_kernel_start_addr(machine, &name);
	if (!addr)
		return -1;