mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 0/4 v2] perf: Make some functions generic
@ 2014-04-07 18:55 Don Zickus
  2014-04-07 18:55 ` [PATCH 1/4 v2] perf: Allow ability to map cpus to nodes easily Don Zickus
                   ` (4 more replies)
  0 siblings, 5 replies; 14+ messages in thread
From: Don Zickus @ 2014-04-07 18:55 UTC (permalink / raw)
  To: acme; +Cc: LKML, jolsa, namhyung, Don Zickus

This patch just converts some private functions into global ones
that can be used by other tools like the c2c tool I am trying to merge.

Don Zickus (4):
  perf: Allow ability to map cpus to nodes easily
  perf: Use cpu/possible instead of cpu/kernel_max
  perf, kmem: Utilize the new generic cpunode_map
  perf, callchain: Add generic report parse callchain callback function

 tools/perf/builtin-kmem.c   |  78 +----------------------
 tools/perf/builtin-report.c |  81 +-----------------------
 tools/perf/util/callchain.c |  82 ++++++++++++++++++++++++
 tools/perf/util/callchain.h |   1 +
 tools/perf/util/cpumap.c    | 149 ++++++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/cpumap.h    |  35 +++++++++++
 6 files changed, 273 insertions(+), 153 deletions(-)

-- 
1.7.11.7


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 1/4 v2] perf: Allow ability to map cpus to nodes easily
  2014-04-07 18:55 [PATCH 0/4 v2] perf: Make some functions generic Don Zickus
@ 2014-04-07 18:55 ` Don Zickus
  2014-04-10  9:31   ` Jiri Olsa
  2014-04-22 18:34   ` [tip:perf/core] perf tools: " tip-bot for Don Zickus
  2014-04-07 18:55 ` [PATCH 2/4 v2] perf: Use cpu/possible instead of cpu/kernel_max Don Zickus
                   ` (3 subsequent siblings)
  4 siblings, 2 replies; 14+ messages in thread
From: Don Zickus @ 2014-04-07 18:55 UTC (permalink / raw)
  To: acme; +Cc: LKML, jolsa, namhyung, Don Zickus

This patch figures out the max number of cpus and nodes that are on the
system and creates a map of cpu to node.  This allows us to provide a cpu
and quickly get the node associated with it.

It was mostly copied from builtin-kmem.c and tweaked slightly to use less memory
(use possible cpus instead of max).  It also calculates the max number of nodes.

V6: use original kernel_max reference
V5: use sysfs_mountpoint and filename__read_str
V4: fix typos, rename get_max_num
V3: simplify function names

Signed-off-by: Don Zickus <dzickus@redhat.com>
---
 tools/perf/util/cpumap.c | 149 +++++++++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/cpumap.h |  35 +++++++++++
 2 files changed, 184 insertions(+)

diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
index 7fe4994..1b75434 100644
--- a/tools/perf/util/cpumap.c
+++ b/tools/perf/util/cpumap.c
@@ -317,3 +317,152 @@ int cpu_map__build_core_map(struct cpu_map *cpus, struct cpu_map **corep)
 {
 	return cpu_map__build_map(cpus, corep, cpu_map__get_core);
 }
+
+/* setup simple routines to easily access node numbers given a cpu number */
+static int get_max_num(char *path, int *max)
+{
+	size_t num;
+	char *buf;
+	int err = 0;
+
+	if (filename__read_str(path, &buf, &num))
+		return -1;
+
+	buf[num] = '\0';
+
+	/* start on the right, to find highest node num */
+	while (--num) {
+		if ((buf[num] == ',') || (buf[num] == '-')) {
+			num++;
+			break;
+		}
+	}
+	if (sscanf(&buf[num], "%d", max) < 1) {
+		err = -1;
+		goto out;
+	}
+
+	/* convert from 0-based to 1-based */
+	(*max)++;
+
+out:
+	free(buf);
+	return err;
+}
+
+/* Determine highest possible cpu in the system for sparse allocation */
+static void set_max_cpu_num(void)
+{
+	const char *mnt;
+	char path[PATH_MAX];
+	int ret = -1;
+
+	/* set up default */
+	max_cpu_num = 4096;
+
+	mnt = sysfs__mountpoint();
+	if (!mnt)
+		goto out;
+
+	/* get the highest possible cpu number for a sparse allocation */
+	snprintf(path, PATH_MAX, "%s/devices/system/cpu/kernel_max", mnt);
+
+	ret = get_max_num(path, &max_cpu_num);
+
+out:
+	if (ret)
+		pr_err("Failed to read max cpus, using default of %d\n",
+			max_cpu_num);
+	return;
+}
+
+/* Determine highest possible node in the system for sparse allocation */
+static void set_max_node_num(void)
+{
+	const char *mnt;
+	char path[PATH_MAX];
+	int ret = -1;
+
+	/* set up default */
+	max_node_num = 8;
+
+	mnt = sysfs__mountpoint();
+	if (!mnt)
+		goto out;
+
+	/* get the highest possible cpu number for a sparse allocation */
+	snprintf(path, PATH_MAX, "%s/devices/system/node/possible", mnt);
+
+	ret = get_max_num(path, &max_node_num);
+
+out:
+	if (ret)
+		pr_err("Failed to read max nodes, using default of %d\n",
+			max_node_num);
+	return;
+}
+
+static int init_cpunode_map(void)
+{
+	int i;
+
+	set_max_cpu_num();
+	set_max_node_num();
+
+	cpunode_map = calloc(max_cpu_num, sizeof(int));
+	if (!cpunode_map) {
+		pr_err("%s: calloc failed\n", __func__);
+		goto out;
+	}
+
+	for (i = 0; i < max_cpu_num; i++)
+		cpunode_map[i] = -1;
+
+	return 0;
+out:
+	return -1;
+}
+
+int cpu__setup_cpunode_map(void)
+{
+	struct dirent *dent1, *dent2;
+	DIR *dir1, *dir2;
+	unsigned int cpu, mem;
+	char buf[PATH_MAX];
+	char path[PATH_MAX];
+	const char *mnt;
+
+	/* initialize globals */
+	if (init_cpunode_map())
+		return -1;
+
+	mnt = sysfs__mountpoint();
+	if (!mnt)
+		return 0;
+
+	snprintf(path, PATH_MAX, "%s/devices/system/node", mnt);
+	dir1 = opendir(path);
+	if (!dir1)
+		return 0;
+
+	/* walk tree and setup map */
+	while ((dent1 = readdir(dir1)) != NULL) {
+		if (dent1->d_type != DT_DIR ||
+		    sscanf(dent1->d_name, "node%u", &mem) < 1)
+			continue;
+
+		snprintf(buf, PATH_MAX, "%s/%s", path, dent1->d_name);
+		dir2 = opendir(buf);
+		if (!dir2)
+			continue;
+		while ((dent2 = readdir(dir2)) != NULL) {
+			if (dent2->d_type != DT_LNK ||
+			    sscanf(dent2->d_name, "cpu%u", &cpu) < 1)
+				continue;
+			cpunode_map[cpu] = mem;
+		}
+		closedir(dir2);
+	}
+	closedir(dir1);
+	return 0;
+}
diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h
index b123bb9..61a6548 100644
--- a/tools/perf/util/cpumap.h
+++ b/tools/perf/util/cpumap.h
@@ -4,6 +4,9 @@
 #include <stdio.h>
 #include <stdbool.h>
 
+#include "perf.h"
+#include "util/debug.h"
+
 struct cpu_map {
 	int nr;
 	int map[];
@@ -46,4 +49,36 @@ static inline bool cpu_map__empty(const struct cpu_map *map)
 	return map ? map->map[0] == -1 : true;
 }
 
+int max_cpu_num;
+int max_node_num;
+int *cpunode_map;
+
+int cpu__setup_cpunode_map(void);
+
+static inline int cpu__max_node(void)
+{
+	if (unlikely(!max_node_num))
+		pr_debug("cpu_map not initialized\n");
+
+	return max_node_num;
+}
+
+static inline int cpu__max_cpu(void)
+{
+	if (unlikely(!max_cpu_num))
+		pr_debug("cpu_map not initialized\n");
+
+	return max_cpu_num;
+}
+
+static inline int cpu__get_node(int cpu)
+{
+	if (unlikely(cpunode_map == NULL)) {
+		pr_debug("cpu_map not initialized\n");
+		return -1;
+	}
+
+	return cpunode_map[cpu];
+}
+
 #endif /* __PERF_CPUMAP_H */
-- 
1.7.11.7


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 2/4 v2] perf: Use cpu/possible instead of cpu/kernel_max
  2014-04-07 18:55 [PATCH 0/4 v2] perf: Make some functions generic Don Zickus
  2014-04-07 18:55 ` [PATCH 1/4 v2] perf: Allow ability to map cpus to nodes easily Don Zickus
@ 2014-04-07 18:55 ` Don Zickus
  2014-04-22 18:34   ` [tip:perf/core] perf tools: Use cpu/possible instead of cpu/ kernel_max tip-bot for Don Zickus
  2014-04-07 18:55 ` [PATCH 3/4 v2] perf, kmem: Utilize the new generic cpunode_map Don Zickus
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 14+ messages in thread
From: Don Zickus @ 2014-04-07 18:55 UTC (permalink / raw)
  To: acme; +Cc: LKML, jolsa, namhyung, Don Zickus

The system's max configuration is represented by cpu/possible and
cpu/kernel_max can be huge (4096 vs. 128), so save space by keeping
smaller structures.

Signed-off-by: Don Zickus <dzickus@redhat.com>
---
 tools/perf/util/cpumap.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
index 1b75434..22adfd0 100644
--- a/tools/perf/util/cpumap.c
+++ b/tools/perf/util/cpumap.c
@@ -365,7 +365,7 @@ static void set_max_cpu_num(void)
 		goto out;
 
 	/* get the highest possible cpu number for a sparse allocation */
-	snprintf(path, PATH_MAX, "%s/devices/system/cpu/kernel_max", mnt);
+	snprintf(path, PATH_MAX, "%s/devices/system/cpu/possible", mnt);
 
 	ret = get_max_num(path, &max_cpu_num);
 
-- 
1.7.11.7


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 3/4 v2] perf, kmem: Utilize the new generic cpunode_map
  2014-04-07 18:55 [PATCH 0/4 v2] perf: Make some functions generic Don Zickus
  2014-04-07 18:55 ` [PATCH 1/4 v2] perf: Allow ability to map cpus to nodes easily Don Zickus
  2014-04-07 18:55 ` [PATCH 2/4 v2] perf: Use cpu/possible instead of cpu/kernel_max Don Zickus
@ 2014-04-07 18:55 ` Don Zickus
  2014-04-22 18:34   ` [tip:perf/core] perf " tip-bot for Don Zickus
  2014-04-07 18:55 ` [PATCH 4/4 v2] perf, callchain: Add generic report parse callchain callback function Don Zickus
  2014-04-09  0:31 ` [PATCH 0/4 v2] perf: Make some functions generic Namhyung Kim
  4 siblings, 1 reply; 14+ messages in thread
From: Don Zickus @ 2014-04-07 18:55 UTC (permalink / raw)
  To: acme; +Cc: LKML, jolsa, namhyung, Don Zickus, Li Zefan

Use the previous patch implementation of cpunode_map for builtin-kmem.c
Should not be any functional difference.

Cc: Li Zefan <lizf@cn.fujitsu.com>
Signed-off-by: Don Zickus <dzickus@redhat.com>
---
 tools/perf/builtin-kmem.c | 78 ++---------------------------------------------
 1 file changed, 3 insertions(+), 75 deletions(-)

diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c
index 929462a..a61783a 100644
--- a/tools/perf/builtin-kmem.c
+++ b/tools/perf/builtin-kmem.c
@@ -14,6 +14,7 @@
 #include "util/parse-options.h"
 #include "util/trace-event.h"
 #include "util/data.h"
+#include "util/cpumap.h"
 
 #include "util/debug.h"
 
@@ -31,9 +32,6 @@ static int			caller_lines = -1;
 
 static bool			raw_ip;
 
-static int			*cpunode_map;
-static int			max_cpu_num;
-
 struct alloc_stat {
 	u64	call_site;
 	u64	ptr;
@@ -55,76 +53,6 @@ static struct rb_root root_caller_sorted;
 static unsigned long total_requested, total_allocated;
 static unsigned long nr_allocs, nr_cross_allocs;
 
-#define PATH_SYS_NODE	"/sys/devices/system/node"
-
-static int init_cpunode_map(void)
-{
-	FILE *fp;
-	int i, err = -1;
-
-	fp = fopen("/sys/devices/system/cpu/kernel_max", "r");
-	if (!fp) {
-		max_cpu_num = 4096;
-		return 0;
-	}
-
-	if (fscanf(fp, "%d", &max_cpu_num) < 1) {
-		pr_err("Failed to read 'kernel_max' from sysfs");
-		goto out_close;
-	}
-
-	max_cpu_num++;
-
-	cpunode_map = calloc(max_cpu_num, sizeof(int));
-	if (!cpunode_map) {
-		pr_err("%s: calloc failed\n", __func__);
-		goto out_close;
-	}
-
-	for (i = 0; i < max_cpu_num; i++)
-		cpunode_map[i] = -1;
-
-	err = 0;
-out_close:
-	fclose(fp);
-	return err;
-}
-
-static int setup_cpunode_map(void)
-{
-	struct dirent *dent1, *dent2;
-	DIR *dir1, *dir2;
-	unsigned int cpu, mem;
-	char buf[PATH_MAX];
-
-	if (init_cpunode_map())
-		return -1;
-
-	dir1 = opendir(PATH_SYS_NODE);
-	if (!dir1)
-		return 0;
-
-	while ((dent1 = readdir(dir1)) != NULL) {
-		if (dent1->d_type != DT_DIR ||
-		    sscanf(dent1->d_name, "node%u", &mem) < 1)
-			continue;
-
-		snprintf(buf, PATH_MAX, "%s/%s", PATH_SYS_NODE, dent1->d_name);
-		dir2 = opendir(buf);
-		if (!dir2)
-			continue;
-		while ((dent2 = readdir(dir2)) != NULL) {
-			if (dent2->d_type != DT_LNK ||
-			    sscanf(dent2->d_name, "cpu%u", &cpu) < 1)
-				continue;
-			cpunode_map[cpu] = mem;
-		}
-		closedir(dir2);
-	}
-	closedir(dir1);
-	return 0;
-}
-
 static int insert_alloc_stat(unsigned long call_site, unsigned long ptr,
 			     int bytes_req, int bytes_alloc, int cpu)
 {
@@ -235,7 +163,7 @@ static int perf_evsel__process_alloc_node_event(struct perf_evsel *evsel,
 	int ret = perf_evsel__process_alloc_event(evsel, sample);
 
 	if (!ret) {
-		int node1 = cpunode_map[sample->cpu],
+		int node1 = cpu__get_node(sample->cpu),
 		    node2 = perf_evsel__intval(evsel, sample, "node");
 
 		if (node1 != node2)
@@ -770,7 +698,7 @@ int cmd_kmem(int argc, const char **argv, const char *prefix __maybe_unused)
 	if (!strncmp(argv[0], "rec", 3)) {
 		return __cmd_record(argc, argv);
 	} else if (!strcmp(argv[0], "stat")) {
-		if (setup_cpunode_map())
+		if (cpu__setup_cpunode_map())
 			return -1;
 
 		if (list_empty(&caller_sort))
-- 
1.7.11.7


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 4/4 v2] perf, callchain: Add generic report parse callchain callback function
  2014-04-07 18:55 [PATCH 0/4 v2] perf: Make some functions generic Don Zickus
                   ` (2 preceding siblings ...)
  2014-04-07 18:55 ` [PATCH 3/4 v2] perf, kmem: Utilize the new generic cpunode_map Don Zickus
@ 2014-04-07 18:55 ` Don Zickus
  2014-04-22 18:34   ` [tip:perf/core] perf " tip-bot for Don Zickus
  2014-04-09  0:31 ` [PATCH 0/4 v2] perf: Make some functions generic Namhyung Kim
  4 siblings, 1 reply; 14+ messages in thread
From: Don Zickus @ 2014-04-07 18:55 UTC (permalink / raw)
  To: acme; +Cc: LKML, jolsa, namhyung, Don Zickus

This takes the parse_callchain_opt function and copies it into the
callchain.c file.  Now the c2c tool can use it too without duplicating.

Update perf-report to use the new routine too.

V3: rename function
V2: remove commented code, combine with perf-report change

Signed-off-by: Don Zickus <dzickus@redhat.com>
---
 tools/perf/builtin-report.c | 81 ++------------------------------------------
 tools/perf/util/callchain.c | 82 +++++++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/callchain.h |  1 +
 3 files changed, 86 insertions(+), 78 deletions(-)

diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index c8f2113..189905b 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -573,11 +573,9 @@ static int __cmd_report(struct report *rep)
 }
 
 static int
-parse_callchain_opt(const struct option *opt, const char *arg, int unset)
+report_parse_callchain_opt(const struct option *opt, const char *arg, int unset)
 {
 	struct report *rep = (struct report *)opt->value;
-	char *tok, *tok2;
-	char *endptr;
 
 	/*
 	 * --no-call-graph
@@ -587,80 +585,7 @@ parse_callchain_opt(const struct option *opt, const char *arg, int unset)
 		return 0;
 	}
 
-	symbol_conf.use_callchain = true;
-
-	if (!arg)
-		return 0;
-
-	tok = strtok((char *)arg, ",");
-	if (!tok)
-		return -1;
-
-	/* get the output mode */
-	if (!strncmp(tok, "graph", strlen(arg)))
-		callchain_param.mode = CHAIN_GRAPH_ABS;
-
-	else if (!strncmp(tok, "flat", strlen(arg)))
-		callchain_param.mode = CHAIN_FLAT;
-
-	else if (!strncmp(tok, "fractal", strlen(arg)))
-		callchain_param.mode = CHAIN_GRAPH_REL;
-
-	else if (!strncmp(tok, "none", strlen(arg))) {
-		callchain_param.mode = CHAIN_NONE;
-		symbol_conf.use_callchain = false;
-
-		return 0;
-	}
-
-	else
-		return -1;
-
-	/* get the min percentage */
-	tok = strtok(NULL, ",");
-	if (!tok)
-		goto setup;
-
-	callchain_param.min_percent = strtod(tok, &endptr);
-	if (tok == endptr)
-		return -1;
-
-	/* get the print limit */
-	tok2 = strtok(NULL, ",");
-	if (!tok2)
-		goto setup;
-
-	if (tok2[0] != 'c') {
-		callchain_param.print_limit = strtoul(tok2, &endptr, 0);
-		tok2 = strtok(NULL, ",");
-		if (!tok2)
-			goto setup;
-	}
-
-	/* get the call chain order */
-	if (!strncmp(tok2, "caller", strlen("caller")))
-		callchain_param.order = ORDER_CALLER;
-	else if (!strncmp(tok2, "callee", strlen("callee")))
-		callchain_param.order = ORDER_CALLEE;
-	else
-		return -1;
-
-	/* Get the sort key */
-	tok2 = strtok(NULL, ",");
-	if (!tok2)
-		goto setup;
-	if (!strncmp(tok2, "function", strlen("function")))
-		callchain_param.key = CCKEY_FUNCTION;
-	else if (!strncmp(tok2, "address", strlen("address")))
-		callchain_param.key = CCKEY_ADDRESS;
-	else
-		return -1;
-setup:
-	if (callchain_register_param(&callchain_param) < 0) {
-		pr_err("Can't register callchain params\n");
-		return -1;
-	}
-	return 0;
+	return parse_callchain_report_opt(arg);
 }
 
 int
@@ -772,7 +697,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
 		    "Only display entries with parent-match"),
 	OPT_CALLBACK_DEFAULT('g', "call-graph", &report, "output_type,min_percent[,print_limit],call_order",
 		     "Display callchains using output_type (graph, flat, fractal, or none) , min percent threshold, optional print limit, callchain order, key (function or address). "
-		     "Default: fractal,0.5,callee,function", &parse_callchain_opt, callchain_default_opt),
+		     "Default: fractal,0.5,callee,function", &report_parse_callchain_opt, callchain_default_opt),
 	OPT_INTEGER(0, "max-stack", &report.max_stack,
 		    "Set the maximum stack depth when parsing the callchain, "
 		    "anything beyond the specified depth will be ignored. "
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c
index 8d9db45..2fa48a9 100644
--- a/tools/perf/util/callchain.c
+++ b/tools/perf/util/callchain.c
@@ -25,6 +25,88 @@
 
 __thread struct callchain_cursor callchain_cursor;
 
+int
+parse_callchain_report_opt(const char *arg)
+{
+	char *tok, *tok2;
+	char *endptr;
+
+	symbol_conf.use_callchain = true;
+
+	if (!arg)
+		return 0;
+
+	tok = strtok((char *)arg, ",");
+	if (!tok)
+		return -1;
+
+	/* get the output mode */
+	if (!strncmp(tok, "graph", strlen(arg)))
+		callchain_param.mode = CHAIN_GRAPH_ABS;
+
+	else if (!strncmp(tok, "flat", strlen(arg)))
+		callchain_param.mode = CHAIN_FLAT;
+
+	else if (!strncmp(tok, "fractal", strlen(arg)))
+		callchain_param.mode = CHAIN_GRAPH_REL;
+
+	else if (!strncmp(tok, "none", strlen(arg))) {
+		callchain_param.mode = CHAIN_NONE;
+		symbol_conf.use_callchain = false;
+
+		return 0;
+	}
+
+	else
+		return -1;
+
+	/* get the min percentage */
+	tok = strtok(NULL, ",");
+	if (!tok)
+		goto setup;
+
+	callchain_param.min_percent = strtod(tok, &endptr);
+	if (tok == endptr)
+		return -1;
+
+	/* get the print limit */
+	tok2 = strtok(NULL, ",");
+	if (!tok2)
+		goto setup;
+
+	if (tok2[0] != 'c') {
+		callchain_param.print_limit = strtoul(tok2, &endptr, 0);
+		tok2 = strtok(NULL, ",");
+		if (!tok2)
+			goto setup;
+	}
+
+	/* get the call chain order */
+	if (!strncmp(tok2, "caller", strlen("caller")))
+		callchain_param.order = ORDER_CALLER;
+	else if (!strncmp(tok2, "callee", strlen("callee")))
+		callchain_param.order = ORDER_CALLEE;
+	else
+		return -1;
+
+	/* Get the sort key */
+	tok2 = strtok(NULL, ",");
+	if (!tok2)
+		goto setup;
+	if (!strncmp(tok2, "function", strlen("function")))
+		callchain_param.key = CCKEY_FUNCTION;
+	else if (!strncmp(tok2, "address", strlen("address")))
+		callchain_param.key = CCKEY_ADDRESS;
+	else
+		return -1;
+setup:
+	if (callchain_register_param(&callchain_param) < 0) {
+		pr_err("Can't register callchain params\n");
+		return -1;
+	}
+	return 0;
+}
+
 static void
 rb_insert_callchain(struct rb_root *root, struct callchain_node *chain,
 		    enum chain_mode mode)
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h
index 8ad97e9..dda4cf8 100644
--- a/tools/perf/util/callchain.h
+++ b/tools/perf/util/callchain.h
@@ -157,4 +157,5 @@ int sample__resolve_callchain(struct perf_sample *sample, struct symbol **parent
 int hist_entry__append_callchain(struct hist_entry *he, struct perf_sample *sample);
 
 extern const char record_callchain_help[];
+int parse_callchain_report_opt(const char *arg);
 #endif	/* __PERF_CALLCHAIN_H */
-- 
1.7.11.7


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 0/4 v2] perf: Make some functions generic
  2014-04-07 18:55 [PATCH 0/4 v2] perf: Make some functions generic Don Zickus
                   ` (3 preceding siblings ...)
  2014-04-07 18:55 ` [PATCH 4/4 v2] perf, callchain: Add generic report parse callchain callback function Don Zickus
@ 2014-04-09  0:31 ` Namhyung Kim
  4 siblings, 0 replies; 14+ messages in thread
From: Namhyung Kim @ 2014-04-09  0:31 UTC (permalink / raw)
  To: Don Zickus; +Cc: acme, LKML, jolsa

On Mon,  7 Apr 2014 14:55:20 -0400, Don Zickus wrote:
> This patch just converts some private functions into global ones
> that can be used by other tools like the c2c tool I am trying to merge.

For the series,

Reviewed-by: Namhyung Kim <namhyung@kernel.org>

Thanks,
Namhyung

>
> Don Zickus (4):
>   perf: Allow ability to map cpus to nodes easily
>   perf: Use cpu/possible instead of cpu/kernel_max
>   perf, kmem: Utilize the new generic cpunode_map
>   perf, callchain: Add generic report parse callchain callback function
>
>  tools/perf/builtin-kmem.c   |  78 +----------------------
>  tools/perf/builtin-report.c |  81 +-----------------------
>  tools/perf/util/callchain.c |  82 ++++++++++++++++++++++++
>  tools/perf/util/callchain.h |   1 +
>  tools/perf/util/cpumap.c    | 149 ++++++++++++++++++++++++++++++++++++++++++++
>  tools/perf/util/cpumap.h    |  35 +++++++++++
>  6 files changed, 273 insertions(+), 153 deletions(-)

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 1/4 v2] perf: Allow ability to map cpus to nodes easily
  2014-04-07 18:55 ` [PATCH 1/4 v2] perf: Allow ability to map cpus to nodes easily Don Zickus
@ 2014-04-10  9:31   ` Jiri Olsa
  2014-04-10 13:15     ` Don Zickus
  2014-04-22 18:34   ` [tip:perf/core] perf tools: " tip-bot for Don Zickus
  1 sibling, 1 reply; 14+ messages in thread
From: Jiri Olsa @ 2014-04-10  9:31 UTC (permalink / raw)
  To: Don Zickus; +Cc: acme, LKML, namhyung

On Mon, Apr 07, 2014 at 02:55:21PM -0400, Don Zickus wrote:

SNIP

> +static int init_cpunode_map(void)
> +{
> +	int i;
> +
> +	set_max_cpu_num();
> +	set_max_node_num();
> +
> +	cpunode_map = calloc(max_cpu_num, sizeof(int));
> +	if (!cpunode_map) {
> +		pr_err("%s: calloc failed\n", __func__);
> +		goto out;
shuld probably be ^^^:

		return -1;

> +	}
> +
> +	for (i = 0; i < max_cpu_num; i++)
> +		cpunode_map[i] = -1;
> +
> +	return 0;
> +out:
> +	return -1;

and remove 'out' label code

other than that, it seems ok.. I'll queue it

thanks,
jirka

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 1/4 v2] perf: Allow ability to map cpus to nodes easily
  2014-04-10  9:31   ` Jiri Olsa
@ 2014-04-10 13:15     ` Don Zickus
  2014-04-10 13:24       ` Jiri Olsa
  0 siblings, 1 reply; 14+ messages in thread
From: Don Zickus @ 2014-04-10 13:15 UTC (permalink / raw)
  To: Jiri Olsa; +Cc: acme, LKML, namhyung

On Thu, Apr 10, 2014 at 11:31:46AM +0200, Jiri Olsa wrote:
> On Mon, Apr 07, 2014 at 02:55:21PM -0400, Don Zickus wrote:
> 
> SNIP
> 
> > +static int init_cpunode_map(void)
> > +{
> > +	int i;
> > +
> > +	set_max_cpu_num();
> > +	set_max_node_num();
> > +
> > +	cpunode_map = calloc(max_cpu_num, sizeof(int));
> > +	if (!cpunode_map) {
> > +		pr_err("%s: calloc failed\n", __func__);
> > +		goto out;
> shuld probably be ^^^:
> 
> 		return -1;
> 
> > +	}
> > +
> > +	for (i = 0; i < max_cpu_num; i++)
> > +		cpunode_map[i] = -1;
> > +
> > +	return 0;
> > +out:
> > +	return -1;
> 
> and remove 'out' label code

Sorry, probably leftover code that after snipping and changing didn't get
noticed.  Thanks.

> 
> other than that, it seems ok.. I'll queue it

I assume you are making the changes locally or should I resubmit?

Cheers,
Don

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 1/4 v2] perf: Allow ability to map cpus to nodes easily
  2014-04-10 13:15     ` Don Zickus
@ 2014-04-10 13:24       ` Jiri Olsa
  2014-04-10 13:54         ` Don Zickus
  0 siblings, 1 reply; 14+ messages in thread
From: Jiri Olsa @ 2014-04-10 13:24 UTC (permalink / raw)
  To: Don Zickus; +Cc: acme, LKML, namhyung

On Thu, Apr 10, 2014 at 09:15:15AM -0400, Don Zickus wrote:
> On Thu, Apr 10, 2014 at 11:31:46AM +0200, Jiri Olsa wrote:
> > On Mon, Apr 07, 2014 at 02:55:21PM -0400, Don Zickus wrote:
> > 
> > SNIP
> > 
> > > +static int init_cpunode_map(void)
> > > +{
> > > +	int i;
> > > +
> > > +	set_max_cpu_num();
> > > +	set_max_node_num();
> > > +
> > > +	cpunode_map = calloc(max_cpu_num, sizeof(int));
> > > +	if (!cpunode_map) {
> > > +		pr_err("%s: calloc failed\n", __func__);
> > > +		goto out;
> > shuld probably be ^^^:
> > 
> > 		return -1;
> > 
> > > +	}
> > > +
> > > +	for (i = 0; i < max_cpu_num; i++)
> > > +		cpunode_map[i] = -1;
> > > +
> > > +	return 0;
> > > +out:
> > > +	return -1;
> > 
> > and remove 'out' label code
> 
> Sorry, probably leftover code that after snipping and changing didn't get
> noticed.  Thanks.
> 
> > 
> > other than that, it seems ok.. I'll queue it
> 
> I assume you are making the changes locally or should I resubmit?

yes, I'll do that localy

jirka

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 1/4 v2] perf: Allow ability to map cpus to nodes easily
  2014-04-10 13:24       ` Jiri Olsa
@ 2014-04-10 13:54         ` Don Zickus
  0 siblings, 0 replies; 14+ messages in thread
From: Don Zickus @ 2014-04-10 13:54 UTC (permalink / raw)
  To: Jiri Olsa; +Cc: acme, LKML, namhyung

On Thu, Apr 10, 2014 at 03:24:58PM +0200, Jiri Olsa wrote:
> On Thu, Apr 10, 2014 at 09:15:15AM -0400, Don Zickus wrote:
> > On Thu, Apr 10, 2014 at 11:31:46AM +0200, Jiri Olsa wrote:
> > > On Mon, Apr 07, 2014 at 02:55:21PM -0400, Don Zickus wrote:
> > > 
> > > SNIP
> > > 
> > > > +static int init_cpunode_map(void)
> > > > +{
> > > > +	int i;
> > > > +
> > > > +	set_max_cpu_num();
> > > > +	set_max_node_num();
> > > > +
> > > > +	cpunode_map = calloc(max_cpu_num, sizeof(int));
> > > > +	if (!cpunode_map) {
> > > > +		pr_err("%s: calloc failed\n", __func__);
> > > > +		goto out;
> > > shuld probably be ^^^:
> > > 
> > > 		return -1;
> > > 
> > > > +	}
> > > > +
> > > > +	for (i = 0; i < max_cpu_num; i++)
> > > > +		cpunode_map[i] = -1;
> > > > +
> > > > +	return 0;
> > > > +out:
> > > > +	return -1;
> > > 
> > > and remove 'out' label code
> > 
> > Sorry, probably leftover code that after snipping and changing didn't get
> > noticed.  Thanks.
> > 
> > > 
> > > other than that, it seems ok.. I'll queue it
> > 
> > I assume you are making the changes locally or should I resubmit?
> 
> yes, I'll do that localy

Thanks!

Cheers,
Don

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [tip:perf/core] perf tools: Allow ability to map cpus to nodes easily
  2014-04-07 18:55 ` [PATCH 1/4 v2] perf: Allow ability to map cpus to nodes easily Don Zickus
  2014-04-10  9:31   ` Jiri Olsa
@ 2014-04-22 18:34   ` tip-bot for Don Zickus
  1 sibling, 0 replies; 14+ messages in thread
From: tip-bot for Don Zickus @ 2014-04-22 18:34 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, tglx, namhyung, jolsa, dzickus

Commit-ID:  7780c25bae59fd042281710f5e1243268e2c18dc
Gitweb:     http://git.kernel.org/tip/7780c25bae59fd042281710f5e1243268e2c18dc
Author:     Don Zickus <dzickus@redhat.com>
AuthorDate: Mon, 7 Apr 2014 14:55:21 -0400
Committer:  Jiri Olsa <jolsa@redhat.com>
CommitDate: Tue, 22 Apr 2014 17:39:12 +0200

perf tools: Allow ability to map cpus to nodes easily

This patch figures out the max number of cpus and nodes that are on the
system and creates a map of cpu to node.  This allows us to provide a cpu
and quickly get the node associated with it.

It was mostly copied from builtin-kmem.c and tweaked slightly to use less memory
(use possible cpus instead of max).  It also calculates the max number of nodes.

Signed-off-by: Don Zickus <dzickus@redhat.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Link: http://lkml.kernel.org/r/1396896924-129847-2-git-send-email-dzickus@redhat.com
[ Removing out label code in init_cpunode_map ]
[ Adding check for snprintf error ]
[ Removing unneeded returns ]
Signed-off-by: Jiri Olsa <jolsa@redhat.com>
---
 tools/perf/util/cpumap.c | 160 +++++++++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/cpumap.h |  35 +++++++++++
 2 files changed, 195 insertions(+)

diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
index 7fe4994..526da02 100644
--- a/tools/perf/util/cpumap.c
+++ b/tools/perf/util/cpumap.c
@@ -317,3 +317,163 @@ int cpu_map__build_core_map(struct cpu_map *cpus, struct cpu_map **corep)
 {
 	return cpu_map__build_map(cpus, corep, cpu_map__get_core);
 }
+
+/* setup simple routines to easily access node numbers given a cpu number */
+static int get_max_num(char *path, int *max)
+{
+	size_t num;
+	char *buf;
+	int err = 0;
+
+	if (filename__read_str(path, &buf, &num))
+		return -1;
+
+	buf[num] = '\0';
+
+	/* start on the right, to find highest node num */
+	while (--num) {
+		if ((buf[num] == ',') || (buf[num] == '-')) {
+			num++;
+			break;
+		}
+	}
+	if (sscanf(&buf[num], "%d", max) < 1) {
+		err = -1;
+		goto out;
+	}
+
+	/* convert from 0-based to 1-based */
+	(*max)++;
+
+out:
+	free(buf);
+	return err;
+}
+
+/* Determine highest possible cpu in the system for sparse allocation */
+static void set_max_cpu_num(void)
+{
+	const char *mnt;
+	char path[PATH_MAX];
+	int ret = -1;
+
+	/* set up default */
+	max_cpu_num = 4096;
+
+	mnt = sysfs__mountpoint();
+	if (!mnt)
+		goto out;
+
+	/* get the highest possible cpu number for a sparse allocation */
+	ret = snprintf(path, PATH_MAX, "%s/devices/system/cpu/kernel_max", mnt);
+	if (ret == PATH_MAX) {
+		pr_err("sysfs path crossed PATH_MAX(%d) size\n", PATH_MAX);
+		goto out;
+	}
+
+	ret = get_max_num(path, &max_cpu_num);
+
+out:
+	if (ret)
+		pr_err("Failed to read max cpus, using default of %d\n", max_cpu_num);
+}
+
+/* Determine highest possible node in the system for sparse allocation */
+static void set_max_node_num(void)
+{
+	const char *mnt;
+	char path[PATH_MAX];
+	int ret = -1;
+
+	/* set up default */
+	max_node_num = 8;
+
+	mnt = sysfs__mountpoint();
+	if (!mnt)
+		goto out;
+
+	/* get the highest possible cpu number for a sparse allocation */
+	ret = snprintf(path, PATH_MAX, "%s/devices/system/node/possible", mnt);
+	if (ret == PATH_MAX) {
+		pr_err("sysfs path crossed PATH_MAX(%d) size\n", PATH_MAX);
+		goto out;
+	}
+
+	ret = get_max_num(path, &max_node_num);
+
+out:
+	if (ret)
+		pr_err("Failed to read max nodes, using default of %d\n", max_node_num);
+}
+
+static int init_cpunode_map(void)
+{
+	int i;
+
+	set_max_cpu_num();
+	set_max_node_num();
+
+	cpunode_map = calloc(max_cpu_num, sizeof(int));
+	if (!cpunode_map) {
+		pr_err("%s: calloc failed\n", __func__);
+		return -1;
+	}
+
+	for (i = 0; i < max_cpu_num; i++)
+		cpunode_map[i] = -1;
+
+	return 0;
+}
+
+int cpu__setup_cpunode_map(void)
+{
+	struct dirent *dent1, *dent2;
+	DIR *dir1, *dir2;
+	unsigned int cpu, mem;
+	char buf[PATH_MAX];
+	char path[PATH_MAX];
+	const char *mnt;
+	int n;
+
+	/* initialize globals */
+	if (init_cpunode_map())
+		return -1;
+
+	mnt = sysfs__mountpoint();
+	if (!mnt)
+		return 0;
+
+	n = snprintf(path, PATH_MAX, "%s/devices/system/node", mnt);
+	if (n == PATH_MAX) {
+		pr_err("sysfs path crossed PATH_MAX(%d) size\n", PATH_MAX);
+		return -1;
+	}
+
+	dir1 = opendir(path);
+	if (!dir1)
+		return 0;
+
+	/* walk tree and setup map */
+	while ((dent1 = readdir(dir1)) != NULL) {
+		if (dent1->d_type != DT_DIR || sscanf(dent1->d_name, "node%u", &mem) < 1)
+			continue;
+
+		n = snprintf(buf, PATH_MAX, "%s/%s", path, dent1->d_name);
+		if (n == PATH_MAX) {
+			pr_err("sysfs path crossed PATH_MAX(%d) size\n", PATH_MAX);
+			continue;
+		}
+
+		dir2 = opendir(buf);
+		if (!dir2)
+			continue;
+		while ((dent2 = readdir(dir2)) != NULL) {
+			if (dent2->d_type != DT_LNK || sscanf(dent2->d_name, "cpu%u", &cpu) < 1)
+				continue;
+			cpunode_map[cpu] = mem;
+		}
+		closedir(dir2);
+	}
+	closedir(dir1);
+	return 0;
+}
diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h
index b123bb9..61a6548 100644
--- a/tools/perf/util/cpumap.h
+++ b/tools/perf/util/cpumap.h
@@ -4,6 +4,9 @@
 #include <stdio.h>
 #include <stdbool.h>
 
+#include "perf.h"
+#include "util/debug.h"
+
 struct cpu_map {
 	int nr;
 	int map[];
@@ -46,4 +49,36 @@ static inline bool cpu_map__empty(const struct cpu_map *map)
 	return map ? map->map[0] == -1 : true;
 }
 
+int max_cpu_num;
+int max_node_num;
+int *cpunode_map;
+
+int cpu__setup_cpunode_map(void);
+
+static inline int cpu__max_node(void)
+{
+	if (unlikely(!max_node_num))
+		pr_debug("cpu_map not initialized\n");
+
+	return max_node_num;
+}
+
+static inline int cpu__max_cpu(void)
+{
+	if (unlikely(!max_cpu_num))
+		pr_debug("cpu_map not initialized\n");
+
+	return max_cpu_num;
+}
+
+static inline int cpu__get_node(int cpu)
+{
+	if (unlikely(cpunode_map == NULL)) {
+		pr_debug("cpu_map not initialized\n");
+		return -1;
+	}
+
+	return cpunode_map[cpu];
+}
+
 #endif /* __PERF_CPUMAP_H */

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [tip:perf/core] perf tools: Use cpu/possible instead of cpu/ kernel_max
  2014-04-07 18:55 ` [PATCH 2/4 v2] perf: Use cpu/possible instead of cpu/kernel_max Don Zickus
@ 2014-04-22 18:34   ` tip-bot for Don Zickus
  0 siblings, 0 replies; 14+ messages in thread
From: tip-bot for Don Zickus @ 2014-04-22 18:34 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, tglx, namhyung, jolsa, dzickus

Commit-ID:  f5b1f4e483d55a88ed120e2c62b45ba5b939fa72
Gitweb:     http://git.kernel.org/tip/f5b1f4e483d55a88ed120e2c62b45ba5b939fa72
Author:     Don Zickus <dzickus@redhat.com>
AuthorDate: Mon, 7 Apr 2014 14:55:22 -0400
Committer:  Jiri Olsa <jolsa@redhat.com>
CommitDate: Tue, 22 Apr 2014 17:39:16 +0200

perf tools: Use cpu/possible instead of cpu/kernel_max

The system's max configuration is represented by cpu/possible and
cpu/kernel_max can be huge (4096 vs. 128), so save space by keeping
smaller structures.

Signed-off-by: Don Zickus <dzickus@redhat.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Link: http://lkml.kernel.org/r/1396896924-129847-3-git-send-email-dzickus@redhat.com
Signed-off-by: Jiri Olsa <jolsa@redhat.com>
---
 tools/perf/util/cpumap.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
index 526da02..c4e55b7 100644
--- a/tools/perf/util/cpumap.c
+++ b/tools/perf/util/cpumap.c
@@ -365,7 +365,7 @@ static void set_max_cpu_num(void)
 		goto out;
 
 	/* get the highest possible cpu number for a sparse allocation */
-	ret = snprintf(path, PATH_MAX, "%s/devices/system/cpu/kernel_max", mnt);
+	ret = snprintf(path, PATH_MAX, "%s/devices/system/cpu/possible", mnt);
 	if (ret == PATH_MAX) {
 		pr_err("sysfs path crossed PATH_MAX(%d) size\n", PATH_MAX);
 		goto out;

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [tip:perf/core] perf kmem: Utilize the new generic cpunode_map
  2014-04-07 18:55 ` [PATCH 3/4 v2] perf, kmem: Utilize the new generic cpunode_map Don Zickus
@ 2014-04-22 18:34   ` tip-bot for Don Zickus
  0 siblings, 0 replies; 14+ messages in thread
From: tip-bot for Don Zickus @ 2014-04-22 18:34 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, lizf, namhyung, jolsa, tglx, dzickus

Commit-ID:  4b6279579c84cca7f162cfbcb98f66418f3062f3
Gitweb:     http://git.kernel.org/tip/4b6279579c84cca7f162cfbcb98f66418f3062f3
Author:     Don Zickus <dzickus@redhat.com>
AuthorDate: Mon, 7 Apr 2014 14:55:23 -0400
Committer:  Jiri Olsa <jolsa@redhat.com>
CommitDate: Tue, 22 Apr 2014 17:39:20 +0200

perf kmem: Utilize the new generic cpunode_map

Use the previous patch implementation of cpunode_map for builtin-kmem.c
Should not be any functional difference.

Signed-off-by: Don Zickus <dzickus@redhat.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Cc: Li Zefan <lizf@cn.fujitsu.com>
Link: http://lkml.kernel.org/r/1396896924-129847-4-git-send-email-dzickus@redhat.com
Signed-off-by: Jiri Olsa <jolsa@redhat.com>
---
 tools/perf/builtin-kmem.c | 78 ++---------------------------------------------
 1 file changed, 3 insertions(+), 75 deletions(-)

diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c
index bd91de0..f91fa437 100644
--- a/tools/perf/builtin-kmem.c
+++ b/tools/perf/builtin-kmem.c
@@ -14,6 +14,7 @@
 #include "util/parse-options.h"
 #include "util/trace-event.h"
 #include "util/data.h"
+#include "util/cpumap.h"
 
 #include "util/debug.h"
 
@@ -31,9 +32,6 @@ static int			caller_lines = -1;
 
 static bool			raw_ip;
 
-static int			*cpunode_map;
-static int			max_cpu_num;
-
 struct alloc_stat {
 	u64	call_site;
 	u64	ptr;
@@ -55,76 +53,6 @@ static struct rb_root root_caller_sorted;
 static unsigned long total_requested, total_allocated;
 static unsigned long nr_allocs, nr_cross_allocs;
 
-#define PATH_SYS_NODE	"/sys/devices/system/node"
-
-static int init_cpunode_map(void)
-{
-	FILE *fp;
-	int i, err = -1;
-
-	fp = fopen("/sys/devices/system/cpu/kernel_max", "r");
-	if (!fp) {
-		max_cpu_num = 4096;
-		return 0;
-	}
-
-	if (fscanf(fp, "%d", &max_cpu_num) < 1) {
-		pr_err("Failed to read 'kernel_max' from sysfs");
-		goto out_close;
-	}
-
-	max_cpu_num++;
-
-	cpunode_map = calloc(max_cpu_num, sizeof(int));
-	if (!cpunode_map) {
-		pr_err("%s: calloc failed\n", __func__);
-		goto out_close;
-	}
-
-	for (i = 0; i < max_cpu_num; i++)
-		cpunode_map[i] = -1;
-
-	err = 0;
-out_close:
-	fclose(fp);
-	return err;
-}
-
-static int setup_cpunode_map(void)
-{
-	struct dirent *dent1, *dent2;
-	DIR *dir1, *dir2;
-	unsigned int cpu, mem;
-	char buf[PATH_MAX];
-
-	if (init_cpunode_map())
-		return -1;
-
-	dir1 = opendir(PATH_SYS_NODE);
-	if (!dir1)
-		return 0;
-
-	while ((dent1 = readdir(dir1)) != NULL) {
-		if (dent1->d_type != DT_DIR ||
-		    sscanf(dent1->d_name, "node%u", &mem) < 1)
-			continue;
-
-		snprintf(buf, PATH_MAX, "%s/%s", PATH_SYS_NODE, dent1->d_name);
-		dir2 = opendir(buf);
-		if (!dir2)
-			continue;
-		while ((dent2 = readdir(dir2)) != NULL) {
-			if (dent2->d_type != DT_LNK ||
-			    sscanf(dent2->d_name, "cpu%u", &cpu) < 1)
-				continue;
-			cpunode_map[cpu] = mem;
-		}
-		closedir(dir2);
-	}
-	closedir(dir1);
-	return 0;
-}
-
 static int insert_alloc_stat(unsigned long call_site, unsigned long ptr,
 			     int bytes_req, int bytes_alloc, int cpu)
 {
@@ -235,7 +163,7 @@ static int perf_evsel__process_alloc_node_event(struct perf_evsel *evsel,
 	int ret = perf_evsel__process_alloc_event(evsel, sample);
 
 	if (!ret) {
-		int node1 = cpunode_map[sample->cpu],
+		int node1 = cpu__get_node(sample->cpu),
 		    node2 = perf_evsel__intval(evsel, sample, "node");
 
 		if (node1 != node2)
@@ -772,7 +700,7 @@ int cmd_kmem(int argc, const char **argv, const char *prefix __maybe_unused)
 	if (!strncmp(argv[0], "rec", 3)) {
 		return __cmd_record(argc, argv);
 	} else if (!strcmp(argv[0], "stat")) {
-		if (setup_cpunode_map())
+		if (cpu__setup_cpunode_map())
 			return -1;
 
 		if (list_empty(&caller_sort))

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [tip:perf/core] perf callchain: Add generic report parse callchain callback function
  2014-04-07 18:55 ` [PATCH 4/4 v2] perf, callchain: Add generic report parse callchain callback function Don Zickus
@ 2014-04-22 18:34   ` tip-bot for Don Zickus
  0 siblings, 0 replies; 14+ messages in thread
From: tip-bot for Don Zickus @ 2014-04-22 18:34 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, tglx, namhyung, jolsa, dzickus

Commit-ID:  cff6bb46d477383092f46682a0d12e323e4b84d2
Gitweb:     http://git.kernel.org/tip/cff6bb46d477383092f46682a0d12e323e4b84d2
Author:     Don Zickus <dzickus@redhat.com>
AuthorDate: Mon, 7 Apr 2014 14:55:24 -0400
Committer:  Jiri Olsa <jolsa@redhat.com>
CommitDate: Tue, 22 Apr 2014 17:39:24 +0200

perf callchain: Add generic report parse callchain callback function

This takes the parse_callchain_opt function and copies it into the
callchain.c file.  Now the c2c tool can use it too without duplicating.

Update perf-report to use the new routine too.

Signed-off-by: Don Zickus <dzickus@redhat.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Link: http://lkml.kernel.org/r/1396896924-129847-5-git-send-email-dzickus@redhat.com
[ Adding missing braces to multiline if condition ]
Signed-off-by: Jiri Olsa <jolsa@redhat.com>
---
 tools/perf/builtin-report.c | 81 ++-------------------------------------------
 tools/perf/util/callchain.c | 78 +++++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/callchain.h |  1 +
 3 files changed, 82 insertions(+), 78 deletions(-)

diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index af8cb7a..76e2bb6 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -589,11 +589,9 @@ static int __cmd_report(struct report *rep)
 }
 
 static int
-parse_callchain_opt(const struct option *opt, const char *arg, int unset)
+report_parse_callchain_opt(const struct option *opt, const char *arg, int unset)
 {
 	struct report *rep = (struct report *)opt->value;
-	char *tok, *tok2;
-	char *endptr;
 
 	/*
 	 * --no-call-graph
@@ -603,80 +601,7 @@ parse_callchain_opt(const struct option *opt, const char *arg, int unset)
 		return 0;
 	}
 
-	symbol_conf.use_callchain = true;
-
-	if (!arg)
-		return 0;
-
-	tok = strtok((char *)arg, ",");
-	if (!tok)
-		return -1;
-
-	/* get the output mode */
-	if (!strncmp(tok, "graph", strlen(arg)))
-		callchain_param.mode = CHAIN_GRAPH_ABS;
-
-	else if (!strncmp(tok, "flat", strlen(arg)))
-		callchain_param.mode = CHAIN_FLAT;
-
-	else if (!strncmp(tok, "fractal", strlen(arg)))
-		callchain_param.mode = CHAIN_GRAPH_REL;
-
-	else if (!strncmp(tok, "none", strlen(arg))) {
-		callchain_param.mode = CHAIN_NONE;
-		symbol_conf.use_callchain = false;
-
-		return 0;
-	}
-
-	else
-		return -1;
-
-	/* get the min percentage */
-	tok = strtok(NULL, ",");
-	if (!tok)
-		goto setup;
-
-	callchain_param.min_percent = strtod(tok, &endptr);
-	if (tok == endptr)
-		return -1;
-
-	/* get the print limit */
-	tok2 = strtok(NULL, ",");
-	if (!tok2)
-		goto setup;
-
-	if (tok2[0] != 'c') {
-		callchain_param.print_limit = strtoul(tok2, &endptr, 0);
-		tok2 = strtok(NULL, ",");
-		if (!tok2)
-			goto setup;
-	}
-
-	/* get the call chain order */
-	if (!strncmp(tok2, "caller", strlen("caller")))
-		callchain_param.order = ORDER_CALLER;
-	else if (!strncmp(tok2, "callee", strlen("callee")))
-		callchain_param.order = ORDER_CALLEE;
-	else
-		return -1;
-
-	/* Get the sort key */
-	tok2 = strtok(NULL, ",");
-	if (!tok2)
-		goto setup;
-	if (!strncmp(tok2, "function", strlen("function")))
-		callchain_param.key = CCKEY_FUNCTION;
-	else if (!strncmp(tok2, "address", strlen("address")))
-		callchain_param.key = CCKEY_ADDRESS;
-	else
-		return -1;
-setup:
-	if (callchain_register_param(&callchain_param) < 0) {
-		pr_err("Can't register callchain params\n");
-		return -1;
-	}
-	return 0;
+	return parse_callchain_report_opt(arg);
 }
 
 int
@@ -788,7 +713,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
 		    "Only display entries with parent-match"),
 	OPT_CALLBACK_DEFAULT('g', "call-graph", &report, "output_type,min_percent[,print_limit],call_order",
 		     "Display callchains using output_type (graph, flat, fractal, or none) , min percent threshold, optional print limit, callchain order, key (function or address). "
-		     "Default: fractal,0.5,callee,function", &parse_callchain_opt, callchain_default_opt),
+		     "Default: fractal,0.5,callee,function", &report_parse_callchain_opt, callchain_default_opt),
 	OPT_INTEGER(0, "max-stack", &report.max_stack,
 		    "Set the maximum stack depth when parsing the callchain, "
 		    "anything beyond the specified depth will be ignored. "
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c
index 8d9db45..9a42382 100644
--- a/tools/perf/util/callchain.c
+++ b/tools/perf/util/callchain.c
@@ -25,6 +25,84 @@
 
 __thread struct callchain_cursor callchain_cursor;
 
+int
+parse_callchain_report_opt(const char *arg)
+{
+	char *tok, *tok2;
+	char *endptr;
+
+	symbol_conf.use_callchain = true;
+
+	if (!arg)
+		return 0;
+
+	tok = strtok((char *)arg, ",");
+	if (!tok)
+		return -1;
+
+	/* get the output mode */
+	if (!strncmp(tok, "graph", strlen(arg))) {
+		callchain_param.mode = CHAIN_GRAPH_ABS;
+
+	} else if (!strncmp(tok, "flat", strlen(arg))) {
+		callchain_param.mode = CHAIN_FLAT;
+	} else if (!strncmp(tok, "fractal", strlen(arg))) {
+		callchain_param.mode = CHAIN_GRAPH_REL;
+	} else if (!strncmp(tok, "none", strlen(arg))) {
+		callchain_param.mode = CHAIN_NONE;
+		symbol_conf.use_callchain = false;
+		return 0;
+	} else {
+		return -1;
+	}
+
+	/* get the min percentage */
+	tok = strtok(NULL, ",");
+	if (!tok)
+		goto setup;
+
+	callchain_param.min_percent = strtod(tok, &endptr);
+	if (tok == endptr)
+		return -1;
+
+	/* get the print limit */
+	tok2 = strtok(NULL, ",");
+	if (!tok2)
+		goto setup;
+
+	if (tok2[0] != 'c') {
+		callchain_param.print_limit = strtoul(tok2, &endptr, 0);
+		tok2 = strtok(NULL, ",");
+		if (!tok2)
+			goto setup;
+	}
+
+	/* get the call chain order */
+	if (!strncmp(tok2, "caller", strlen("caller")))
+		callchain_param.order = ORDER_CALLER;
+	else if (!strncmp(tok2, "callee", strlen("callee")))
+		callchain_param.order = ORDER_CALLEE;
+	else
+		return -1;
+
+	/* Get the sort key */
+	tok2 = strtok(NULL, ",");
+	if (!tok2)
+		goto setup;
+	if (!strncmp(tok2, "function", strlen("function")))
+		callchain_param.key = CCKEY_FUNCTION;
+	else if (!strncmp(tok2, "address", strlen("address")))
+		callchain_param.key = CCKEY_ADDRESS;
+	else
+		return -1;
+setup:
+	if (callchain_register_param(&callchain_param) < 0) {
+		pr_err("Can't register callchain params\n");
+		return -1;
+	}
+	return 0;
+}
+
 static void
 rb_insert_callchain(struct rb_root *root, struct callchain_node *chain,
 		    enum chain_mode mode)
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h
index 8ad97e9..dda4cf8 100644
--- a/tools/perf/util/callchain.h
+++ b/tools/perf/util/callchain.h
@@ -157,4 +157,5 @@ int sample__resolve_callchain(struct perf_sample *sample, struct symbol **parent
 int hist_entry__append_callchain(struct hist_entry *he, struct perf_sample *sample);
 
 extern const char record_callchain_help[];
+int parse_callchain_report_opt(const char *arg);
 #endif	/* __PERF_CALLCHAIN_H */

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2014-04-22 18:35 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-04-07 18:55 [PATCH 0/4 v2] perf: Make some functions generic Don Zickus
2014-04-07 18:55 ` [PATCH 1/4 v2] perf: Allow ability to map cpus to nodes easily Don Zickus
2014-04-10  9:31   ` Jiri Olsa
2014-04-10 13:15     ` Don Zickus
2014-04-10 13:24       ` Jiri Olsa
2014-04-10 13:54         ` Don Zickus
2014-04-22 18:34   ` [tip:perf/core] perf tools: " tip-bot for Don Zickus
2014-04-07 18:55 ` [PATCH 2/4 v2] perf: Use cpu/possible instead of cpu/kernel_max Don Zickus
2014-04-22 18:34   ` [tip:perf/core] perf tools: Use cpu/possible instead of cpu/ kernel_max tip-bot for Don Zickus
2014-04-07 18:55 ` [PATCH 3/4 v2] perf, kmem: Utilize the new generic cpunode_map Don Zickus
2014-04-22 18:34   ` [tip:perf/core] perf " tip-bot for Don Zickus
2014-04-07 18:55 ` [PATCH 4/4 v2] perf, callchain: Add generic report parse callchain callback function Don Zickus
2014-04-22 18:34   ` [tip:perf/core] perf " tip-bot for Don Zickus
2014-04-09  0:31 ` [PATCH 0/4 v2] perf: Make some functions generic Namhyung Kim

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome