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

Commit 2737fce8 authored by Ingo Molnar's avatar Ingo Molnar
Browse files

Merge tag 'perf-urgent-for-mingo' of...

Merge tag 'perf-urgent-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux

 into perf/urgent

Pull perf/urgent fixes from Arnaldo Carvalho de Melo:

  * Fix annotation for relocated kernel (Adrian Hunter)

  * Fix demangling of symbols in kernel and kernel modules (Avi Kivity)

  * Fix include for non x86 architectures (Francesco Fusco)

  * Fix ARM64 memory barriers (Peter Zijlstra)

Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parents 0d4dd797 d3b70220
Loading
Loading
Loading
Loading
+29 −4
Original line number Original line Diff line number Diff line
@@ -63,11 +63,35 @@ static int build_id_cache__kcore_dir(char *dir, size_t sz)
	return 0;
	return 0;
}
}


static bool same_kallsyms_reloc(const char *from_dir, char *to_dir)
{
	char from[PATH_MAX];
	char to[PATH_MAX];
	const char *name;
	u64 addr1 = 0, addr2 = 0;
	int i;

	scnprintf(from, sizeof(from), "%s/kallsyms", from_dir);
	scnprintf(to, sizeof(to), "%s/kallsyms", to_dir);

	for (i = 0; (name = ref_reloc_sym_names[i]) != NULL; i++) {
		addr1 = kallsyms__get_function_start(from, name);
		if (addr1)
			break;
	}

	if (name)
		addr2 = kallsyms__get_function_start(to, name);

	return addr1 == addr2;
}

static int build_id_cache__kcore_existing(const char *from_dir, char *to_dir,
static int build_id_cache__kcore_existing(const char *from_dir, char *to_dir,
					  size_t to_dir_sz)
					  size_t to_dir_sz)
{
{
	char from[PATH_MAX];
	char from[PATH_MAX];
	char to[PATH_MAX];
	char to[PATH_MAX];
	char to_subdir[PATH_MAX];
	struct dirent *dent;
	struct dirent *dent;
	int ret = -1;
	int ret = -1;
	DIR *d;
	DIR *d;
@@ -86,10 +110,11 @@ static int build_id_cache__kcore_existing(const char *from_dir, char *to_dir,
			continue;
			continue;
		scnprintf(to, sizeof(to), "%s/%s/modules", to_dir,
		scnprintf(to, sizeof(to), "%s/%s/modules", to_dir,
			  dent->d_name);
			  dent->d_name);
		if (!compare_proc_modules(from, to)) {
		scnprintf(to_subdir, sizeof(to_subdir), "%s/%s",
			scnprintf(to, sizeof(to), "%s/%s", to_dir,
			  to_dir, dent->d_name);
				  dent->d_name);
		if (!compare_proc_modules(from, to) &&
			strlcpy(to_dir, to, to_dir_sz);
		    same_kallsyms_reloc(from_dir, to_subdir)) {
			strlcpy(to_dir, to_subdir, to_dir_sz);
			ret = 0;
			ret = 0;
			break;
			break;
		}
		}
+2 −8
Original line number Original line Diff line number Diff line
@@ -287,10 +287,7 @@ static void perf_event__synthesize_guest_os(struct machine *machine, void *data)
	 * have no _text sometimes.
	 * have no _text sometimes.
	 */
	 */
	err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event,
	err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event,
						 machine, "_text");
						 machine);
	if (err < 0)
		err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event,
							 machine, "_stext");
	if (err < 0)
	if (err < 0)
		pr_err("Couldn't record guest kernel [%d]'s reference"
		pr_err("Couldn't record guest kernel [%d]'s reference"
		       " relocation symbol.\n", machine->pid);
		       " relocation symbol.\n", machine->pid);
@@ -457,10 +454,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
	}
	}


	err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event,
	err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event,
						 machine, "_text");
						 machine);
	if (err < 0)
		err = perf_event__synthesize_kernel_mmap(tool, process_synthesized_event,
							 machine, "_stext");
	if (err < 0)
	if (err < 0)
		pr_err("Couldn't record kernel reference relocation symbol\n"
		pr_err("Couldn't record kernel reference relocation symbol\n"
		       "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n"
		       "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n"
+2 −2
Original line number Original line Diff line number Diff line
@@ -100,8 +100,8 @@


#ifdef __aarch64__
#ifdef __aarch64__
#define mb()		asm volatile("dmb ish" ::: "memory")
#define mb()		asm volatile("dmb ish" ::: "memory")
#define wmb()		asm volatile("dmb ishld" ::: "memory")
#define wmb()		asm volatile("dmb ishst" ::: "memory")
#define rmb()		asm volatile("dmb ishst" ::: "memory")
#define rmb()		asm volatile("dmb ishld" ::: "memory")
#define cpu_relax()	asm volatile("yield" ::: "memory")
#define cpu_relax()	asm volatile("yield" ::: "memory")
#endif
#endif


+0 −10
Original line number Original line Diff line number Diff line
@@ -26,7 +26,6 @@ int test__vmlinux_matches_kallsyms(void)
	struct map *kallsyms_map, *vmlinux_map;
	struct map *kallsyms_map, *vmlinux_map;
	struct machine kallsyms, vmlinux;
	struct machine kallsyms, vmlinux;
	enum map_type type = MAP__FUNCTION;
	enum map_type type = MAP__FUNCTION;
	struct ref_reloc_sym ref_reloc_sym = { .name = "_stext", };
	u64 mem_start, mem_end;
	u64 mem_start, mem_end;


	/*
	/*
@@ -70,14 +69,6 @@ int test__vmlinux_matches_kallsyms(void)
	 */
	 */
	kallsyms_map = machine__kernel_map(&kallsyms, type);
	kallsyms_map = machine__kernel_map(&kallsyms, type);


	sym = map__find_symbol_by_name(kallsyms_map, ref_reloc_sym.name, NULL);
	if (sym == NULL) {
		pr_debug("dso__find_symbol_by_name ");
		goto out;
	}

	ref_reloc_sym.addr = UM(sym->start);

	/*
	/*
	 * Step 5:
	 * Step 5:
	 *
	 *
@@ -89,7 +80,6 @@ int test__vmlinux_matches_kallsyms(void)
	}
	}


	vmlinux_map = machine__kernel_map(&vmlinux, type);
	vmlinux_map = machine__kernel_map(&vmlinux, type);
	map__kmap(vmlinux_map)->ref_reloc_sym = &ref_reloc_sym;


	/*
	/*
	 * Step 6:
	 * Step 6:
+17 −19
Original line number Original line Diff line number Diff line
@@ -470,23 +470,32 @@ static int find_symbol_cb(void *arg, const char *name, char type,
	return 1;
	return 1;
}
}


u64 kallsyms__get_function_start(const char *kallsyms_filename,
				 const char *symbol_name)
{
	struct process_symbol_args args = { .name = symbol_name, };

	if (kallsyms__parse(kallsyms_filename, &args, find_symbol_cb) <= 0)
		return 0;

	return args.start;
}

int perf_event__synthesize_kernel_mmap(struct perf_tool *tool,
int perf_event__synthesize_kernel_mmap(struct perf_tool *tool,
				       perf_event__handler_t process,
				       perf_event__handler_t process,
				       struct machine *machine,
				       struct machine *machine)
				       const char *symbol_name)
{
{
	size_t size;
	size_t size;
	const char *filename, *mmap_name;
	const char *mmap_name;
	char path[PATH_MAX];
	char name_buff[PATH_MAX];
	char name_buff[PATH_MAX];
	struct map *map;
	struct map *map;
	struct kmap *kmap;
	int err;
	int err;
	/*
	/*
	 * We should get this from /sys/kernel/sections/.text, but till that is
	 * We should get this from /sys/kernel/sections/.text, but till that is
	 * available use this, and after it is use this as a fallback for older
	 * available use this, and after it is use this as a fallback for older
	 * kernels.
	 * kernels.
	 */
	 */
	struct process_symbol_args args = { .name = symbol_name, };
	union perf_event *event = zalloc((sizeof(event->mmap) +
	union perf_event *event = zalloc((sizeof(event->mmap) +
					  machine->id_hdr_size));
					  machine->id_hdr_size));
	if (event == NULL) {
	if (event == NULL) {
@@ -502,30 +511,19 @@ int perf_event__synthesize_kernel_mmap(struct perf_tool *tool,
		 * see kernel/perf_event.c __perf_event_mmap
		 * see kernel/perf_event.c __perf_event_mmap
		 */
		 */
		event->header.misc = PERF_RECORD_MISC_KERNEL;
		event->header.misc = PERF_RECORD_MISC_KERNEL;
		filename = "/proc/kallsyms";
	} else {
	} else {
		event->header.misc = PERF_RECORD_MISC_GUEST_KERNEL;
		event->header.misc = PERF_RECORD_MISC_GUEST_KERNEL;
		if (machine__is_default_guest(machine))
			filename = (char *) symbol_conf.default_guest_kallsyms;
		else {
			sprintf(path, "%s/proc/kallsyms", machine->root_dir);
			filename = path;
		}
	}

	if (kallsyms__parse(filename, &args, find_symbol_cb) <= 0) {
		free(event);
		return -ENOENT;
	}
	}


	map = machine->vmlinux_maps[MAP__FUNCTION];
	map = machine->vmlinux_maps[MAP__FUNCTION];
	kmap = map__kmap(map);
	size = snprintf(event->mmap.filename, sizeof(event->mmap.filename),
	size = snprintf(event->mmap.filename, sizeof(event->mmap.filename),
			"%s%s", mmap_name, symbol_name) + 1;
			"%s%s", mmap_name, kmap->ref_reloc_sym->name) + 1;
	size = PERF_ALIGN(size, sizeof(u64));
	size = PERF_ALIGN(size, sizeof(u64));
	event->mmap.header.type = PERF_RECORD_MMAP;
	event->mmap.header.type = PERF_RECORD_MMAP;
	event->mmap.header.size = (sizeof(event->mmap) -
	event->mmap.header.size = (sizeof(event->mmap) -
			(sizeof(event->mmap.filename) - size) + machine->id_hdr_size);
			(sizeof(event->mmap.filename) - size) + machine->id_hdr_size);
	event->mmap.pgoff = args.start;
	event->mmap.pgoff = kmap->ref_reloc_sym->addr;
	event->mmap.start = map->start;
	event->mmap.start = map->start;
	event->mmap.len   = map->end - event->mmap.start;
	event->mmap.len   = map->end - event->mmap.start;
	event->mmap.pid   = machine->pid;
	event->mmap.pid   = machine->pid;
Loading