Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1032914AbbKFIbX (ORCPT ); Fri, 6 Nov 2015 03:31:23 -0500 Received: from szxga01-in.huawei.com ([58.251.152.64]:35048 "EHLO szxga01-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1032817AbbKFIbV (ORCPT ); Fri, 6 Nov 2015 03:31:21 -0500 Message-ID: <563C6539.7030605@huawei.com> Date: Fri, 6 Nov 2015 16:30:49 +0800 From: "Wangnan (F)" User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:31.0) Gecko/20100101 Thunderbird/31.6.0 MIME-Version: 1.0 To: =?UTF-8?B?5bmz5p2+6ZuF5bezIC8gSElSQU1BVFXvvIxNQVNBTUk=?= , "'ltc-kernel@ml.yrl.intra.hitachi.co.jp'" , "'acme@kernel.org'" CC: "namhyung@kernel.org" , "lizefan@huawei.com" , "pi3orama@163.com" , "linux-kernel@vger.kernel.org" , "jolsa@kernel.org" Subject: Re: [PATCH 2/2] perf tools: Fix find_perf_probe_point_from_map() which incorrectly returns success References: <1446729565-27592-1-git-send-email-wangnan0@huawei.com> <1446729565-27592-3-git-send-email-wangnan0@huawei.com> <50399556C9727B4D88A595C8584AAB3752604844@GSjpTKYDCembx32.service.hitachi.net> <20151105160000.GX13236@kernel.org> <50399556C9727B4D88A595C8584AAB3752606DC9@GSjpTKYDCembx32.service.hitachi.net> <50399556C9727B4D88A595C8584AAB37526070A4@GSjpTKYDCembx32.service.hitachi.net> In-Reply-To: <50399556C9727B4D88A595C8584AAB37526070A4@GSjpTKYDCembx32.service.hitachi.net> Content-Type: text/plain; charset="utf-8"; format=flowed Content-Transfer-Encoding: 8bit X-Originating-IP: [10.111.66.109] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A090204.563C654A.0045,ss=1,re=0.000,fgs=0, ip=0.0.0.0, so=2013-06-18 04:22:30, dmn=2011-05-27 18:58:46 X-Mirapoint-Loop-Id: d29f37c9bf95af655b067b7e177980c1 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 5853 Lines: 154 On 2015/11/6 15:12, 平松雅巳 / HIRAMATU,MASAMI wrote: > From: acme@kernel.org [mailto:acme@kernel.org] >>> Em Thu, Nov 05, 2015 at 02:08:48PM +0000, 平松雅巳 / HIRAMATU,MASAMI escreveu: >>>> From: Wang Nan [mailto:wangnan0@huawei.com] >>>>> It is possible that find_perf_probe_point_from_map() fails to find >>>>> symbol but still returns 0 because of an small error when coding: >>>>> find_perf_probe_point_from_map() set 'ret' to error code at first, >>>>> but also use it to hold return value of >>>>> kernel_get_symbol_address_by_name(). >>>> OK, I didn't expect that there is a symbol which can be found by >>>> kernel_get_symbol_address_by_name() but not by __find_kernel_function()... >>>> Would you have any example of the error? >>>> >>>>> This patch resets 'ret' to error even kernel_get_symbol_address_by_name() >>>>> success, so if !sym, the whole function returns error correctly. >>>> Hmm, that sounds tricky. I'd rather like to add *psym to kernel_get_symbol_address_by_name() >>>> to save symbol and don't use __find_kernel_function() instead. >>> Tricky? I don't think so, suboptimal? possibly, but it fixes an error, >>> so should be processed quickly, right? I'm applying his patch and then >>> whatever improvement can be done on top. >> OK, then I'll send an improvement patch. > Ah, finally I got what happened. I guess the problem may happen when we put > a probe on the kernel somewhere outside of any functions and run "perf probe -l". > I think it should not be allowed to put the probe outside any symbol. > > The background is here, at first "perf-probe -a somewhere" defines a probe in > the kernel but its address is relative from "_text". (thus, vfs_read becomes "_text+2348080" > for example). Since it is not readable by human, perf probe -l tries to get an appropriate > symbol from the "_text+OFFSET". > For the purpose, the first kernel_get_symbol_address_by_name() is for translating _text to > an address, and the second __find_kernel_function() is for finding a symbol from the > address+OFFSET. > Then, if the address+OFFSET is out of the symbol map, the second one can fail. > This means the first symbol and the second symbol is not same. > > So, the direction of Wang solution is good :). Just a cleanup is required. > > Thank you! I also tried to finger out the problem for all day and made some progress. It is another problem. It happeneds when probing an address reside in a module on aarch64 system. On my aarch64 system I use kcore. Different from x86, on aarch64, modules address is lower than normal kernel. For example: On x86_64: # readelf -a /proc/kcore Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align ... LOAD 0x00007fff81003000 0xffffffff81000000 0x0000000000000000 <-- kernel 0x0000000001026000 0x0000000001026000 RWE 1000 LOAD 0x00007fffa0003000 0xffffffffa0000000 0x0000000000000000 <-- module 0x000000005f000000 0x000000005f000000 RWE 1000 On aarch64: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align ... LOAD 0x0000000000002000 0xffffffc000000000 0x0000000000000000 <-- kernel 0x000000007fc00000 0x000000007fc00000 RWE 1000 LOAD 0xfffffffffc002000 0xffffffbffc000000 0x0000000000000000 <-- module 0x0000000004000000 0x0000000004000000 RWE 1000 See? On aarch64, Offset field of module address area is negative. Which causes a problem in dso__split_kallsyms_for_kcore(): when it adjusting symbols using "pos->start -= curr_map->start - curr_map->pgoff", the relative order between module functions and normal kernel function is changed. For example: funca at 0xffffffc00021b428 is a normal kernel function. funcb at 0xffffffbffc000000 is a function in kernel. During parsing /proc/kallsyms, address of funca > address of funcb. However, after the adjusting: funca becomes: 0xffffffc00021b428 - (0xffffffc000000000 - 0x2000) = 0x21d428 funcb becomes: 0xffffffbffc000000 - (0xffffffbffc000000 - 0xfffffffffc002000) = 0xfffffffffc002000 address of funca < address of funcb. Unfortunately, the rbtree is not adjusted in this case. I hacked symbols__find: diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index b4cc766..8463b0c 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -332,12 +332,14 @@ static struct symbol *symbols__find(struct rb_root *symbols, u64 ip) while (n) { struct symbol *s = rb_entry(n, struct symbol, rb_node); - if (ip < s->start) + if ((s64)ip < (s64)s->start) n = n->rb_left; - else if (ip >= s->end) + else if ((s64)ip >= (s64)s->end) n = n->rb_right; - else + else { + pr_debug("found %p\n", (void *)ip); return s; + } } return NULL; and get correct result: try to find information at 3ffc000000 in kernel_module Failed to find module kernel_module. Failed to find the path for kernel_module: [kernel_module] Failed to find corresponding probes from debuginfo. found 0xfffffffffc002000 However, what we really need is adjusting rbtree in this case. Could you please give me some hint for fixing this problem? I'm not familiar with this part of code. Thank you. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/