Message ID | 56697572.90701@huawei.com |
---|---|
State | New |
Headers | show |
On 2015/12/10 23:12, 'Arnaldo Carvalho de Melo' wrote: [SNIP] > But this requires having these special refcnt__ routines, that will make > tools/perf/ code patterns for reference counts look different that the > refcount patterns in the kernel :-\ > > And would be a requirement to change the observed workload :-\ > > Is this _strictly_ required? No. The requirement should be: 1. The create/get/put/delete functions are non-inline (because dwarf info is not as reliable as symbol); 2. From their argument list, we can always get the variable we need (the pointer of objects, the value of refcnt, etc.) We don't have to use this refcnt things. > Can't we, for a project like perf, where we > know where some refcount (say, the one for 'struct thread') gets > initialized, use that (thread__new()) and then hook into thread__get and > thread__put and then use the destructor, thread__delete() as the place > to dump leaks? > I think it is possible. If we can abstract a common pattern about it, we can provide a perf subcommand which we can deal with generic alloc/free pattern. I'll put it on my todo-list. Currently we are focusing on perf daemonization. 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/
On 2015/12/11 10:08, 平松雅巳 / HIRAMATU,MASAMI wrote: > From: Wangnan (F) [mailto:wangnan0@huawei.com] >> On 2015/12/10 23:12, 'Arnaldo Carvalho de Melo' wrote: >> >> [SNIP] >>> But this requires having these special refcnt__ routines, that will make >>> tools/perf/ code patterns for reference counts look different that the >>> refcount patterns in the kernel :-\ >>> >>> And would be a requirement to change the observed workload :-\ >>> >>> Is this _strictly_ required? >> No. The requirement should be: >> >> 1. The create/get/put/delete functions are non-inline (because dwarf info >> is not as reliable as symbol); >> 2. From their argument list, we can always get the variable we need (the >> pointer of objects, the value of refcnt, etc.) > However, we have to customize it for each application. Perf itself might be OK > but others might have different implementation. If limited to pairwise operations ({{m,c}alloc,strdup} vs free, open vs close), I think it is possible to abstract a uniformed pattern. 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/
On 2015/12/11 10:15, 平松雅巳 / HIRAMATU,MASAMI wrote: > From: 'Arnaldo Carvalho de Melo' [mailto:acme@kernel.org] >> But this requires having these special refcnt__ routines, that will make >> tools/perf/ code patterns for reference counts look different that the >> refcount patterns in the kernel :-\ > BTW, I think even without the refcnt debugger, we'd better introduce this > kind API to unify the refcnt operation in perf code. As I said, we have many > miscodings on current implementation. Unifying the API can enforce developers > to avoid such miscodings. > > Thank you, > I tried this problem in another way, I'd like to share it here. First: create two uprobes: # ./perf probe --exec /home/wangnan/perf dso__new%return %ax Added new event: probe_perf:dso__new (on dso__new%return in /home/wangnan/perf with %ax) You can now use it in all perf tools, such as: perf record -e probe_perf:dso__new -aR sleep 1 # ./perf probe --exec /home/wangnan/perf dso__delete dso Added new event: probe_perf:dso__delete (on dso__delete in /home/wangnan/perf with dso) You can now use it in all perf tools, such as: perf record -e probe_perf:dso__delete -aR sleep 1 Then start test: # ./perf record -g -e probe_perf:dso__new -e probe_perf:dso__delete ./perf probe vfs_read Added new event: probe:vfs_read (on vfs_read) You can now use it in all perf tools, such as: perf record -e probe:vfs_read -aR sleep 1 [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.048 MB perf.data (178 samples) ] From the perf report result I know two dso objects are leak: 90 probe_perf:dso__new ` 88 probe_perf:dso__delete Then convert output to CTF: $ ./perf data convert --to-ctf ./out.ctf With a python script, try to find the exact leak objects (I'm not good at python, I believe we can do this with much shorter script): $ cat refcnt.py from babeltrace import TraceCollection tc = TraceCollection(); tc.add_trace('./out.ctf', 'ctf') objs = {} for event in tc.events: if event.name.startswith('probe_perf:dso__new'): if event['arg1'] not in objs: objs[event['arg1']] = 1 if event.name.startswith('probe_perf:dso__delete'): if event['dso'] in objs: objs[event['dso']] = 0 for x in objs: if objs[x] is 0: continue print("0x%x" % x) $ python3 ./refcnt.py 0x34cb350 0x34d4640 Then from perf script's result, search for the two address: perf 23203 [004] 665244.170387: probe_perf:dso__new: (4aaee0 <- 50a5eb) arg1=0x34cb350 10a5eb dso__load_sym (/home/w00229757/perf) af42d dso__load_vmlinux (/home/w00229757/perf) af58c dso__load_vmlinux_path (/home/w00229757/perf) 10c40a open_debuginfo (/home/w00229757/perf) 111d39 convert_perf_probe_events (/home/w00229757/perf) 603a7 __cmd_probe.isra.3 (/home/w00229757/perf) 60a44 cmd_probe (/home/w00229757/perf) 7f6d1 run_builtin (/home/w00229757/perf) 33056 main (/home/w00229757/perf) 21bd5 __libc_start_main (/tmp/oxygen_root-w00229757/lib64/libc-2.18.so) perf 23203 [004] 665244.170679: probe_perf:dso__new: (4aaee0 <- 50a5eb) arg1=0x34d4640 10a5eb dso__load_sym (/home/w00229757/perf) af42d dso__load_vmlinux (/home/w00229757/perf) af58c dso__load_vmlinux_path (/home/w00229757/perf) 10c40a open_debuginfo (/home/w00229757/perf) 111d39 convert_perf_probe_events (/home/w00229757/perf) 603a7 __cmd_probe.isra.3 (/home/w00229757/perf) 60a44 cmd_probe (/home/w00229757/perf) 7f6d1 run_builtin (/home/w00229757/perf) 33056 main (/home/w00229757/perf) 21bd5 __libc_start_main (/tmp/oxygen_root-w00229757/lib64/libc-2.18.so) 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/
On 2015/12/11 10:42, Wangnan (F) wrote: > > > On 2015/12/11 10:15, 平松雅巳 / HIRAMATU,MASAMI wrote: >> From: 'Arnaldo Carvalho de Melo' [mailto:acme@kernel.org] >>> But this requires having these special refcnt__ routines, that will >>> make >>> tools/perf/ code patterns for reference counts look different that the >>> refcount patterns in the kernel :-\ >> BTW, I think even without the refcnt debugger, we'd better introduce >> this >> kind API to unify the refcnt operation in perf code. As I said, we >> have many >> miscodings on current implementation. Unifying the API can enforce >> developers >> to avoid such miscodings. >> >> Thank you, >> > > I tried this problem in another way, I'd like to share it here. > > First: create two uprobes: > > # ./perf probe --exec /home/wangnan/perf dso__new%return %ax > Added new event: > probe_perf:dso__new (on dso__new%return in /home/wangnan/perf with > %ax) > > You can now use it in all perf tools, such as: > > perf record -e probe_perf:dso__new -aR sleep 1 > > # ./perf probe --exec /home/wangnan/perf dso__delete dso > Added new event: > probe_perf:dso__delete (on dso__delete in /home/wangnan/perf with dso) > > You can now use it in all perf tools, such as: > > perf record -e probe_perf:dso__delete -aR sleep 1 > > > Then start test: > > # ./perf record -g -e probe_perf:dso__new -e probe_perf:dso__delete > ./perf probe vfs_read > Added new event: > probe:vfs_read (on vfs_read) > > You can now use it in all perf tools, such as: > > perf record -e probe:vfs_read -aR sleep 1 > > [ perf record: Woken up 1 times to write data ] > [ perf record: Captured and wrote 0.048 MB perf.data (178 samples) ] > > > From the perf report result I know two dso objects are leak: > > 90 probe_perf:dso__new ` > 88 probe_perf:dso__delete > The above result is gotten from yesterday's perf/core. I also tried today's perf/core and get: 90 probe_perf:dso__new ` 90 probe_perf:dso__delete So we fix these leak. 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/
diff --git a/tools/perf/util/Build b/tools/perf/util/Build index 65fef59..2c45478 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -87,6 +87,7 @@ libperf-$(CONFIG_AUXTRACE) += intel-bts.o libperf-y += parse-branch-options.o libperf-y += parse-regs-options.o libperf-y += term.o +libperf-y += refcnt.o libperf-$(CONFIG_LIBBPF) += bpf-loader.o libperf-$(CONFIG_BPF_PROLOGUE) += bpf-prologue.o diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index e8e9a9d..de52ae8 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -1,6 +1,7 @@ #include <asm/bug.h> #include <sys/time.h> #include <sys/resource.h> +#include "refcnt.h" #include "symbol.h" #include "dso.h" #include "machine.h" diff --git a/tools/perf/util/refcnt.c b/tools/perf/util/refcnt.c new file mode 100644 index 0000000..f5a6659 --- /dev/null +++ b/tools/perf/util/refcnt.c @@ -0,0 +1,29 @@ +#include <linux/compiler.h> +#include "util/refcnt.h" + +void __attribute__ ((noinline)) +__refcnt__init(atomic_t *refcnt, int n, + void *obj __maybe_unused, + const char *name __maybe_unused) +{ + atomic_set(refcnt, n); +} + +void __attribute__ ((noinline)) +refcnt__delete(void *obj __maybe_unused) +{ +} + +void __attribute__ ((noinline)) +__refcnt__get(atomic_t *refcnt, void *obj __maybe_unused, + const char *name __maybe_unused) +{ + atomic_inc(refcnt); +} + +int __attribute__ ((noinline)) +__refcnt__put(atomic_t *refcnt, void *obj __maybe_unused, + const char *name __maybe_unused) +{ + return atomic_dec_and_test(refcnt); +} diff --git a/tools/perf/util/refcnt.h b/tools/perf/util/refcnt.h new file mode 100644 index 0000000..04f5390 --- /dev/null +++ b/tools/perf/util/refcnt.h @@ -0,0 +1,21 @@ +#ifndef PERF_REFCNT_H +#define PERF_REFCNT_H +#include <linux/atomic.h> + +void __refcnt__init(atomic_t *refcnt, int n, void *obj, const char *name); +void refcnt__delete(void *obj); +void __refcnt__get(atomic_t *refcnt, void *obj, const char *name); +int __refcnt__put(atomic_t *refcnt, void *obj, const char *name); + +#define refcnt__init(obj, member, n) \ + __refcnt__init(&(obj)->member, n, obj, #obj) +#define refcnt__init_as(obj, member, n, name) \ + __refcnt__init(&(obj)->member, n, obj, name) +#define refcnt__exit(obj, member) \ + refcnt__delete(obj) +#define refcnt__get(obj, member) \ + __refcnt__get(&(obj)->member, obj, #obj) +#define refcnt__put(obj, member) \ + __refcnt__put(&(obj)->member, obj, #obj) + +#endif