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

Commit abd54f68 authored by Arnaldo Carvalho de Melo's avatar Arnaldo Carvalho de Melo Committed by Ingo Molnar
Browse files

perf: Don't assume /proc/kallsyms is ordered



perf: Don't assume /proc/kallsyms is ordered

Since we _are_ ordering it by the symbol start, just traverse the
freshly built rbtree setting the prev->end members to curr->start - 1.

Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: John Kacur <jkacur@redhat.com>
LKML-Reference: <20090526152134.GF4424@ghostprotocols.net>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 59d81029
Loading
Loading
Loading
Loading
+25 −19
Original line number Original line Diff line number Diff line
@@ -360,17 +360,9 @@ static int load_kallsyms(void)
	char *line = NULL;
	char *line = NULL;
	size_t n;
	size_t n;


	if (getline(&line, &n, file) < 0 || !line)
		goto out_delete_dso;

	unsigned long long previous_start;
	char c, previous_symbf[4096];
	if (sscanf(line, "%llx %c %s", &previous_start, &c, previous_symbf) != 3)
		goto out_delete_line;

	while (!feof(file)) {
	while (!feof(file)) {
		unsigned long long start;
		unsigned long long start;
		char symbf[4096];
		char c, symbf[4096];


		if (getline(&line, &n, file) < 0)
		if (getline(&line, &n, file) < 0)
			break;
			break;
@@ -379,19 +371,33 @@ static int load_kallsyms(void)
			goto out_delete_dso;
			goto out_delete_dso;


		if (sscanf(line, "%llx %c %s", &start, &c, symbf) == 3) {
		if (sscanf(line, "%llx %c %s", &start, &c, symbf) == 3) {
			if (start > previous_start) {
			/*
				struct symbol *sym = symbol__new(previous_start,
			 * Well fix up the end later, when we have all sorted.
								 start - previous_start,
			 */
								 previous_symbf);
			struct symbol *sym = symbol__new(start, 0xdead, symbf);


			if (sym == NULL)
			if (sym == NULL)
				goto out_delete_dso;
				goto out_delete_dso;


			dso__insert_symbol(kernel_dso, sym);
			dso__insert_symbol(kernel_dso, sym);
				previous_start = start;
				strcpy(previous_symbf, symbf);
		}
		}
	}
	}

	/*
	 * Now that we have all sorted out, just set the ->end of all
	 * symbols
	 */
	struct rb_node *nd, *prevnd = rb_first(&kernel_dso->syms);

	if (prevnd == NULL)
		goto out_delete_line;

	for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) {
		struct symbol *prev = rb_entry(prevnd, struct symbol, rb_node),
			      *curr = rb_entry(nd, struct symbol, rb_node);

		prev->end = curr->start - 1;
		prevnd = nd;
	}
	}


	dsos__add(kernel_dso);
	dsos__add(kernel_dso);