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

Commit 2b9240ca authored by Namhyung Kim's avatar Namhyung Kim Committed by Arnaldo Carvalho de Melo
Browse files

perf tools: Introduce perf_callchain_config()



This patch adds support for following config options to ~/.perfconfig file.

  [call-graph]
    record-mode = dwarf
    dump-size = 8192
    print-type = fractal
    order = callee
    threshold = 0.5
    print-limit = 128
    sort-key = function

Reviewed-by: default avatarDavid Ahern <dsahern@gmail.com>
Signed-off-by: default avatarNamhyung Kim <namhyung@kernel.org>
Acked-by: default avatarJiri Olsa <jolsa@redhat.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Milian Wolff <mail@milianw.de>
Cc: Namhyung Kim <namhyung.kim@lge.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1411434104-5307-5-git-send-email-namhyung@kernel.org


Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent f7f084f4
Loading
Loading
Loading
Loading
+90 −19
Original line number Diff line number Diff line
@@ -109,6 +109,49 @@ int parse_callchain_record_opt(const char *arg)
	return ret;
}

static int parse_callchain_mode(const char *value)
{
	if (!strncmp(value, "graph", strlen(value))) {
		callchain_param.mode = CHAIN_GRAPH_ABS;
		return 0;
	}
	if (!strncmp(value, "flat", strlen(value))) {
		callchain_param.mode = CHAIN_FLAT;
		return 0;
	}
	if (!strncmp(value, "fractal", strlen(value))) {
		callchain_param.mode = CHAIN_GRAPH_REL;
		return 0;
	}
	return -1;
}

static int parse_callchain_order(const char *value)
{
	if (!strncmp(value, "caller", strlen(value))) {
		callchain_param.order = ORDER_CALLER;
		return 0;
	}
	if (!strncmp(value, "callee", strlen(value))) {
		callchain_param.order = ORDER_CALLEE;
		return 0;
	}
	return -1;
}

static int parse_callchain_sort_key(const char *value)
{
	if (!strncmp(value, "function", strlen(value))) {
		callchain_param.key = CCKEY_FUNCTION;
		return 0;
	}
	if (!strncmp(value, "address", strlen(value))) {
		callchain_param.key = CCKEY_ADDRESS;
		return 0;
	}
	return -1;
}

int
parse_callchain_report_opt(const char *arg)
{
@@ -128,25 +171,12 @@ parse_callchain_report_opt(const char *arg)
			return 0;
		}

		/* try to get the output mode */
		if (!strncmp(tok, "graph", strlen(tok)))
			callchain_param.mode = CHAIN_GRAPH_ABS;
		else if (!strncmp(tok, "flat", strlen(tok)))
			callchain_param.mode = CHAIN_FLAT;
		else if (!strncmp(tok, "fractal", strlen(tok)))
			callchain_param.mode = CHAIN_GRAPH_REL;
		/* try to get the call chain order */
		else if (!strncmp(tok, "caller", strlen(tok)))
			callchain_param.order = ORDER_CALLER;
		else if (!strncmp(tok, "callee", strlen(tok)))
			callchain_param.order = ORDER_CALLEE;
		/* try to get the sort key */
		else if (!strncmp(tok, "function", strlen(tok)))
			callchain_param.key = CCKEY_FUNCTION;
		else if (!strncmp(tok, "address", strlen(tok)))
			callchain_param.key = CCKEY_ADDRESS;
		if (!parse_callchain_mode(tok) ||
		    !parse_callchain_order(tok) ||
		    !parse_callchain_sort_key(tok)) {
			/* parsing ok - move on to the next */
		} else if (!minpcnt_set) {
			/* try to get the min percent */
		else if (!minpcnt_set) {
			callchain_param.min_percent = strtod(tok, &endptr);
			if (tok == endptr)
				return -1;
@@ -168,6 +198,47 @@ parse_callchain_report_opt(const char *arg)
	return 0;
}

int perf_callchain_config(const char *var, const char *value)
{
	char *endptr;

	if (prefixcmp(var, "call-graph."))
		return 0;
	var += sizeof("call-graph.") - 1;

	if (!strcmp(var, "record-mode"))
		return parse_callchain_record_opt(value);
#ifdef HAVE_DWARF_UNWIND_SUPPORT
	if (!strcmp(var, "dump-size")) {
		unsigned long size = 0;
		int ret;

		ret = get_stack_size(value, &size);
		callchain_param.dump_size = size;

		return ret;
	}
#endif
	if (!strcmp(var, "print-type"))
		return parse_callchain_mode(value);
	if (!strcmp(var, "order"))
		return parse_callchain_order(value);
	if (!strcmp(var, "sort-key"))
		return parse_callchain_sort_key(value);
	if (!strcmp(var, "threshold")) {
		callchain_param.min_percent = strtod(value, &endptr);
		if (value == endptr)
			return -1;
	}
	if (!strcmp(var, "print-limit")) {
		callchain_param.print_limit = strtod(value, &endptr);
		if (value == endptr)
			return -1;
	}

	return 0;
}

static void
rb_insert_callchain(struct rb_root *root, struct callchain_node *chain,
		    enum chain_mode mode)
+1 −0
Original line number Diff line number Diff line
@@ -170,6 +170,7 @@ int fill_callchain_info(struct addr_location *al, struct callchain_cursor_node *
extern const char record_callchain_help[];
int parse_callchain_record_opt(const char *arg);
int parse_callchain_report_opt(const char *arg);
int perf_callchain_config(const char *var, const char *value);

static inline void callchain_cursor_snapshot(struct callchain_cursor *dest,
					     struct callchain_cursor *src)
+3 −0
Original line number Diff line number Diff line
@@ -396,6 +396,9 @@ int perf_default_config(const char *var, const char *value,
	if (!prefixcmp(var, "ui."))
		return perf_ui_config(var, value);

	if (!prefixcmp(var, "call-graph."))
		return perf_callchain_config(var, value);

	/* Add other config variables here. */
	return 0;
}