[PATCH v2] perf tools: Add hugetlbfs memory recognition

From: Hou Pengyang
Date: Tue Jun 30 2015 - 09:15:45 EST


Maps for JIT is helpful for symbols-parsing for anon-executable-memory.
What we need to do is to add (START, SIZE, symbolname) to /tmp/perf-%d.map
(%d = pid of process), and perf would parse symbol located in this area
according to /tmp/perf-%d.map. It works well for normal mmap.

However, when we alloc such memory from hugetlbfs by the following code:

......

fd = open("/mnt/huge/hugepagefile", O_CREAT | O_RDWR, 0755);
if (fd < 0) {
perror("Open failed");
exit(1);
}
addr = mmap(ADDR, LENGTH, PROT_READ | PROT_WRITE | \
PROT_EXEC, MAP_SHARED, fd, 0);

......
where hugetlbfs is mounted in /mnt/huge. Symbols could not be parsed correctly:

#perf report
86.96% 0.00% hugepage-mmap hugepagefile [.] 0xffffffe00000005c
86.96% 0.00% hugepage-mmap hugepagefile [.] 0xffffffe0000000ac

This is because such mmap area's file backed is "/mnt/huge/hugepagefile", a node
in pseudo filesystem, it is useless for symbol-parsing. so wo had better recognize
such hugetlbfs area, and rename it's filename to /tmp/perf-%d.map, just as anon-memory
and no_dso_memory do.

This patch imports a new option named --hugetlb-file to let user tell perf
explicitly which file is in hugetlbfs, and mmap area whose backed filenode is in
hugetlbfs would be recognized as memory without dso in function is_no_dso_memory.

After this patch:
#perf report
86.96% 0.00% hugepage-mmap perf-182.map [.] 0x000000200000005c
86.96% 0.00% hugepage-mmap perf-182.map [.] 0x00000020000000ac

We can add maps info to perf-182.map for further symbols-parsing.

Signed-off-by: Hou Pengyang <houpengyang@xxxxxxxxxx>
---
tools/perf/builtin-report.c | 3 +++
tools/perf/util/map.c | 10 +++++++++-
tools/perf/util/symbol.c | 7 +++++++
tools/perf/util/symbol.h | 2 ++
4 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 348bed4..9b506af 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -685,6 +685,9 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
"only consider these symbols"),
OPT_STRING(0, "symbol-filter", &report.symbol_filter_str, "filter",
"only show symbols that (partially) match with this filter"),
+ OPT_STRING(0, "hugetlb-file", &symbol_conf.hugetlb_list_str, "file[,file...]",
+ "These files would be recoginized as files in hugetlbfs,"
+ "and JIT would be used for symbol-parsing"),
OPT_STRING('w', "column-widths", &symbol_conf.col_width_list_str,
"width[,width...]",
"don't try to adjust column width, use these fixed values"),
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index b5a5e9c..f919a3ad 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -30,11 +30,19 @@ static inline int is_anon_memory(const char *filename)
!strcmp(filename, "/anon_hugepage (deleted)");
}

+static inline int is_hugetlb_memory(const char *filename)
+{
+ return (symbol_conf.hugetlb_list != NULL) &&
+ (strlist__has_entry(symbol_conf.hugetlb_list,
+ filename));
+}
+
static inline int is_no_dso_memory(const char *filename)
{
return !strncmp(filename, "[stack", 6) ||
!strncmp(filename, "/SYSV",5) ||
- !strcmp(filename, "[heap]");
+ !strcmp(filename, "[heap]") ||
+ is_hugetlb_memory(filename);
}

static inline int is_android_lib(const char *filename)
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 48b588c..c3855fd 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -1990,6 +1990,10 @@ int symbol__init(struct perf_session_env *env)
symbol_conf.sym_list_str, "symbol") < 0)
goto out_free_tid_list;

+ if (setup_list(&symbol_conf.hugetlb_list,
+ symbol_conf.hugetlb_list_str, "hugetlb") < 0)
+ goto out_free_hugetlb_list;
+
/*
* A path to symbols of "/" is identical to ""
* reset here for simplicity.
@@ -2007,6 +2011,8 @@ int symbol__init(struct perf_session_env *env)
symbol_conf.initialized = true;
return 0;

+out_free_hugetlb_list:
+ strlist__delete(symbol_conf.hugetlb_list);
out_free_tid_list:
intlist__delete(symbol_conf.tid_list);
out_free_pid_list:
@@ -2025,6 +2031,7 @@ void symbol__exit(void)
strlist__delete(symbol_conf.sym_list);
strlist__delete(symbol_conf.dso_list);
strlist__delete(symbol_conf.comm_list);
+ strlist__delete(symbol_conf.hugetlb_list);
intlist__delete(symbol_conf.tid_list);
intlist__delete(symbol_conf.pid_list);
vmlinux_path__exit();
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index bef47ead..81fb99c 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -116,12 +116,14 @@ struct symbol_conf {
const char *guestmount;
const char *dso_list_str,
*comm_list_str,
+ *hugetlb_list_str,
*pid_list_str,
*tid_list_str,
*sym_list_str,
*col_width_list_str;
struct strlist *dso_list,
*comm_list,
+ *hugetlb_list,
*sym_list,
*dso_from_list,
*dso_to_list,
--
1.8.3.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/