From patchwork Mon Jan 11 13:48:06 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wang Nan X-Patchwork-Id: 59528 Delivered-To: patch@linaro.org Received: by 10.112.130.2 with SMTP id oa2csp2129044lbb; Mon, 11 Jan 2016 06:04:07 -0800 (PST) X-Received: by 10.66.158.37 with SMTP id wr5mr31037745pab.48.1452521047039; Mon, 11 Jan 2016 06:04:07 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id m3si28827831pfi.179.2016.01.11.06.04.06; Mon, 11 Jan 2016 06:04:07 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933253AbcAKODf (ORCPT + 29 others); Mon, 11 Jan 2016 09:03:35 -0500 Received: from szxga03-in.huawei.com ([119.145.14.66]:41225 "EHLO szxga03-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1759942AbcAKNtk (ORCPT ); Mon, 11 Jan 2016 08:49:40 -0500 Received: from 172.24.1.50 (EHLO szxeml422-hub.china.huawei.com) ([172.24.1.50]) by szxrg03-dlp.huawei.com (MOS 4.4.3-GA FastPath queued) with ESMTP id BUI71797; Mon, 11 Jan 2016 21:49:08 +0800 (CST) Received: from linux-4hy3.site (10.107.193.248) by szxeml422-hub.china.huawei.com (10.82.67.152) with Microsoft SMTP Server id 14.3.235.1; Mon, 11 Jan 2016 21:49:01 +0800 From: Wang Nan To: CC: , , , , , Wang Nan , Arnaldo Carvalho de Melo , "Masami Hiramatsu" , Namhyung Kim Subject: [PATCH 15/53] perf tools: Fix symbols searching for offline module in buildid-cache Date: Mon, 11 Jan 2016 13:48:06 +0000 Message-ID: <1452520124-2073-16-git-send-email-wangnan0@huawei.com> X-Mailer: git-send-email 1.8.3.4 In-Reply-To: <1452520124-2073-1-git-send-email-wangnan0@huawei.com> References: <1452520124-2073-1-git-send-email-wangnan0@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.107.193.248] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A090201.5693B2D5.0029, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0, ip=0.0.0.0, so=2013-05-26 15:14:31, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: ea3fa58cc655154c367b73016a1a18e8 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Before this patch, if a sample is triggered inside an offline module (module not in /lib/modules/`uname -r`/), even if the module is in buildid-cache, 'perf report' is still unable to get correct symbol. For example: # rm -rf ~/.debug/ # perf buildid-cache -a ./mymodule.ko # perf probe -m ./mymodule.ko -a get_mymodule_val Added new event: probe:get_mymodule_val (on get_mymodule_val in mymodule) You can now use it in all perf tools, such as: perf record -e probe:get_mymodule_val -aR sleep 1 # perf record -e probe:get_mymodule_val cat /proc/mymodule mymodule:3 [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.011 MB perf.data (1 samples) ] # perf report --stdio [SNIP] # # Overhead Command Shared Object Symbol # ........ ....... ................ ...................... # 100.00% cat [mymodule] [k] 0x0000000000000001 # perf report -vvvv --stdio dso__load_sym: adjusting symbol: st_value: 0 sh_addr: 0 sh_offset: 0x70 symbol__new: get_mymodule_val 0x70-0x8a [SNIP] This is caused by dso__load() -> dso__load_sym(). In dso__load(), kmod is true only when dso is regular kernel module. All files loaded from buildid-cache is treated as user programs. Following dso__load_sym() set map->pgoff incorrectly. This patch gives kernel modules in buildid-cache a chance to adjust value of kmod. After dso__load() get the type of symbols, if it is buildid, check the last 3 chars of original filename against '.ko', and adjust the value of kmod if the file is a kernel module. Signed-off-by: Wang Nan Cc: Arnaldo Carvalho de Melo Cc: Masami Hiramatsu Cc: Namhyung Kim Cc: Li Zefan --- tools/perf/util/build-id.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ tools/perf/util/build-id.h | 1 + tools/perf/util/symbol.c | 4 ++++ 3 files changed, 49 insertions(+) -- 1.8.3.4 diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index 6a7e273..6b18082 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c @@ -166,6 +166,50 @@ char *dso__build_id_filename(const struct dso *dso, char *bf, size_t size) return build_id__filename(build_id_hex, bf, size); } +bool dso__build_id_is_kmod(const struct dso *dso, char *bf, size_t size) +{ + char *id_name, *ch; + struct stat sb; + + id_name = dso__build_id_filename(dso, bf, size); + if (!id_name) + goto err; + if (access(id_name, F_OK)) + goto err; + if (lstat(id_name, &sb) == -1) + goto err; + if ((size_t)sb.st_size > size - 1) + goto err; + if (readlink(id_name, bf, size - 1) < 0) + goto err; + + bf[sb.st_size] = '\0'; + + /* + * link should be: + * ../../lib/modules/4.4.0-rc4/kernel/net/ipv4/netfilter/nf_nat_ipv4.ko/a09fe3eb3147dafa4e3b31dbd6257e4d696bdc92 + */ + ch = strrchr(bf, '/'); + if (!ch) + goto err; + if (ch - 3 < bf) + goto err; + + return strncmp(".ko", ch - 3, 3) == 0; +err: + /* + * If dso__build_id_filename work, get id_name again, + * because id_name points to bf and is broken. + */ + if (id_name) + id_name = dso__build_id_filename(dso, bf, size); + pr_err("Invalid build id: %s\n", id_name ? : + dso->long_name ? : + dso->short_name ? : + "[unknown]"); + return false; +} + #define dsos__for_each_with_build_id(pos, head) \ list_for_each_entry(pos, head, node) \ if (!pos->has_build_id) \ diff --git a/tools/perf/util/build-id.h b/tools/perf/util/build-id.h index 27a14a8..64af3e2 100644 --- a/tools/perf/util/build-id.h +++ b/tools/perf/util/build-id.h @@ -16,6 +16,7 @@ int sysfs__sprintf_build_id(const char *root_dir, char *sbuild_id); int filename__sprintf_build_id(const char *pathname, char *sbuild_id); char *dso__build_id_filename(const struct dso *dso, char *bf, size_t size); +bool dso__build_id_is_kmod(const struct dso *dso, char *bf, size_t size); int build_id__mark_dso_hit(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, struct perf_evsel *evsel, diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 3b2de6e..d78d105 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -1525,6 +1525,10 @@ int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter) if (!runtime_ss && syms_ss) runtime_ss = syms_ss; + if (syms_ss && syms_ss->type == DSO_BINARY_TYPE__BUILD_ID_CACHE) + if (dso__build_id_is_kmod(dso, name, PATH_MAX)) + kmod = true; + if (syms_ss) ret = dso__load_sym(dso, map, syms_ss, runtime_ss, filter, kmod); else