Re: [PATCH] ubi: Remove ubi_io_is_bad call from scan_peb
Please, ignore this patch. I made a mistake. while headers are read, ubi_io_is_bad is called only when chk_io is true. 2017-09-26 13:54 GMT+09:00 Hyunchul Lee: > From: Hyunchul Lee > > When erase count and volume identifier headers are read, > ubi_io_is_bad is called. So instead of calling ubi_io_is_bad > from scan_peb, use the result. > > this patch reduces the attach time by about 15% in my > environment. > > ARMv7 1GHZ based board, 66.8MiB MTD partition > before after > attach time 308.365 usec257.100 usec > > Signed-off-by: Hyunchul Lee > --- > drivers/mtd/ubi/attach.c | 15 ++- > drivers/mtd/ubi/io.c | 9 ++--- > drivers/mtd/ubi/ubi.h| 2 ++ > 3 files changed, 14 insertions(+), 12 deletions(-) > > diff --git a/drivers/mtd/ubi/attach.c b/drivers/mtd/ubi/attach.c > index 93ceea4..07b9162 100644 > --- a/drivers/mtd/ubi/attach.c > +++ b/drivers/mtd/ubi/attach.c > @@ -962,15 +962,6 @@ static int scan_peb(struct ubi_device *ubi, struct > ubi_attach_info *ai, > > dbg_bld("scan PEB %d", pnum); > > - /* Skip bad physical eraseblocks */ > - err = ubi_io_is_bad(ubi, pnum); > - if (err < 0) > - return err; > - else if (err) { > - ai->bad_peb_count += 1; > - return 0; > - } > - > err = ubi_io_read_ec_hdr(ubi, pnum, ech, 0); > if (err < 0) > return err; > @@ -999,6 +990,9 @@ static int scan_peb(struct ubi_device *ubi, struct > ubi_attach_info *ai, > ec = UBI_UNKNOWN; > bitflips = 1; > break; > + case UBI_IO_BAD_BLK: > + ai->bad_peb_count += 1; > + return 0; > default: > ubi_err(ubi, "'ubi_io_read_ec_hdr()' returned unknown code > %d", > err); > @@ -1136,6 +1130,9 @@ static int scan_peb(struct ubi_device *ubi, struct > ubi_attach_info *ai, > if (err) > return err; > goto adjust_mean_ec; > + case UBI_IO_BAD_BLK: > + ai->bad_peb_count += 1; > + return 0; > default: > ubi_err(ubi, "'ubi_io_read_vid_hdr()' returned unknown code > %d", > err); > diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c > index 8290432..ae52e7e 100644 > --- a/drivers/mtd/ubi/io.c > +++ b/drivers/mtd/ubi/io.c > @@ -117,6 +117,7 @@ static int self_check_write(struct ubi_device *ubi, const > void *buf, int pnum, > * o %UBI_IO_BITFLIPS if all the requested data were successfully read, but > * correctable bit-flips were detected; this is harmless but may indicate > * that this eraseblock may become bad soon (but do not have to); > + * o %UBI_IO_BAD_BLK if the erabse block is bad > * o %-EBADMSG if the MTD subsystem reported about data integrity problems, > for > * example it can be an ECC error in case of NAND; this most probably means > * that the data is corrupted; > @@ -137,7 +138,9 @@ int ubi_io_read(const struct ubi_device *ubi, void *buf, > int pnum, int offset, > ubi_assert(len > 0); > > err = self_check_not_bad(ubi, pnum); > - if (err) > + if (err == -EBADSLT) > + return UBI_IO_BAD_BLK; > + else if (err) > return err; > > /* > @@ -1131,7 +1134,7 @@ int ubi_io_write_vid_hdr(struct ubi_device *ubi, int > pnum, > * @ubi: UBI device description object > * @pnum: physical eraseblock number to check > * > - * This function returns zero if the physical eraseblock is good, %-EINVAL if > + * This function returns zero if the physical eraseblock is good, %-EBADSLT > if > * it is bad and a negative error code if an error occurred. > */ > static int self_check_not_bad(const struct ubi_device *ubi, int pnum) > @@ -1147,7 +1150,7 @@ static int self_check_not_bad(const struct ubi_device > *ubi, int pnum) > > ubi_err(ubi, "self-check failed for PEB %d", pnum); > dump_stack(); > - return err > 0 ? -EINVAL : err; > + return err > 0 ? -EBADSLT : err; > } > > /** > diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h > index 5fe6265..5c5207d 100644 > --- a/drivers/mtd/ubi/ubi.h > +++ b/drivers/mtd/ubi/ubi.h > @@ -107,6 +107,7 @@ > * data integrity error reported by the MTD driver > * (uncorrectable ECC error in case of NAND) > * UBI_IO_BITFLIPS: bit-flips were detected and corrected > + * UBI_IO_BAD_BLK: bad erase block > * > * Note, it is probably better to have bit-flip and ebadmsg as flags which > can > * be or'ed with other error code. But this is a big change because there are > @@ -118,6 +119,7 @@ enum { > UBI_IO_BAD_HDR, > UBI_IO_BAD_HDR_EBADMSG, > UBI_IO_BITFLIPS, > + UBI_IO_BAD_BLK, > }; > > /* > -- > 1.9.1 > > >
Re: [PATCH] ubi: Remove ubi_io_is_bad call from scan_peb
Please, ignore this patch. I made a mistake. while headers are read, ubi_io_is_bad is called only when chk_io is true. 2017-09-26 13:54 GMT+09:00 Hyunchul Lee : > From: Hyunchul Lee > > When erase count and volume identifier headers are read, > ubi_io_is_bad is called. So instead of calling ubi_io_is_bad > from scan_peb, use the result. > > this patch reduces the attach time by about 15% in my > environment. > > ARMv7 1GHZ based board, 66.8MiB MTD partition > before after > attach time 308.365 usec257.100 usec > > Signed-off-by: Hyunchul Lee > --- > drivers/mtd/ubi/attach.c | 15 ++- > drivers/mtd/ubi/io.c | 9 ++--- > drivers/mtd/ubi/ubi.h| 2 ++ > 3 files changed, 14 insertions(+), 12 deletions(-) > > diff --git a/drivers/mtd/ubi/attach.c b/drivers/mtd/ubi/attach.c > index 93ceea4..07b9162 100644 > --- a/drivers/mtd/ubi/attach.c > +++ b/drivers/mtd/ubi/attach.c > @@ -962,15 +962,6 @@ static int scan_peb(struct ubi_device *ubi, struct > ubi_attach_info *ai, > > dbg_bld("scan PEB %d", pnum); > > - /* Skip bad physical eraseblocks */ > - err = ubi_io_is_bad(ubi, pnum); > - if (err < 0) > - return err; > - else if (err) { > - ai->bad_peb_count += 1; > - return 0; > - } > - > err = ubi_io_read_ec_hdr(ubi, pnum, ech, 0); > if (err < 0) > return err; > @@ -999,6 +990,9 @@ static int scan_peb(struct ubi_device *ubi, struct > ubi_attach_info *ai, > ec = UBI_UNKNOWN; > bitflips = 1; > break; > + case UBI_IO_BAD_BLK: > + ai->bad_peb_count += 1; > + return 0; > default: > ubi_err(ubi, "'ubi_io_read_ec_hdr()' returned unknown code > %d", > err); > @@ -1136,6 +1130,9 @@ static int scan_peb(struct ubi_device *ubi, struct > ubi_attach_info *ai, > if (err) > return err; > goto adjust_mean_ec; > + case UBI_IO_BAD_BLK: > + ai->bad_peb_count += 1; > + return 0; > default: > ubi_err(ubi, "'ubi_io_read_vid_hdr()' returned unknown code > %d", > err); > diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c > index 8290432..ae52e7e 100644 > --- a/drivers/mtd/ubi/io.c > +++ b/drivers/mtd/ubi/io.c > @@ -117,6 +117,7 @@ static int self_check_write(struct ubi_device *ubi, const > void *buf, int pnum, > * o %UBI_IO_BITFLIPS if all the requested data were successfully read, but > * correctable bit-flips were detected; this is harmless but may indicate > * that this eraseblock may become bad soon (but do not have to); > + * o %UBI_IO_BAD_BLK if the erabse block is bad > * o %-EBADMSG if the MTD subsystem reported about data integrity problems, > for > * example it can be an ECC error in case of NAND; this most probably means > * that the data is corrupted; > @@ -137,7 +138,9 @@ int ubi_io_read(const struct ubi_device *ubi, void *buf, > int pnum, int offset, > ubi_assert(len > 0); > > err = self_check_not_bad(ubi, pnum); > - if (err) > + if (err == -EBADSLT) > + return UBI_IO_BAD_BLK; > + else if (err) > return err; > > /* > @@ -1131,7 +1134,7 @@ int ubi_io_write_vid_hdr(struct ubi_device *ubi, int > pnum, > * @ubi: UBI device description object > * @pnum: physical eraseblock number to check > * > - * This function returns zero if the physical eraseblock is good, %-EINVAL if > + * This function returns zero if the physical eraseblock is good, %-EBADSLT > if > * it is bad and a negative error code if an error occurred. > */ > static int self_check_not_bad(const struct ubi_device *ubi, int pnum) > @@ -1147,7 +1150,7 @@ static int self_check_not_bad(const struct ubi_device > *ubi, int pnum) > > ubi_err(ubi, "self-check failed for PEB %d", pnum); > dump_stack(); > - return err > 0 ? -EINVAL : err; > + return err > 0 ? -EBADSLT : err; > } > > /** > diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h > index 5fe6265..5c5207d 100644 > --- a/drivers/mtd/ubi/ubi.h > +++ b/drivers/mtd/ubi/ubi.h > @@ -107,6 +107,7 @@ > * data integrity error reported by the MTD driver > * (uncorrectable ECC error in case of NAND) > * UBI_IO_BITFLIPS: bit-flips were detected and corrected > + * UBI_IO_BAD_BLK: bad erase block > * > * Note, it is probably better to have bit-flip and ebadmsg as flags which > can > * be or'ed with other error code. But this is a big change because there are > @@ -118,6 +119,7 @@ enum { > UBI_IO_BAD_HDR, > UBI_IO_BAD_HDR_EBADMSG, > UBI_IO_BITFLIPS, > + UBI_IO_BAD_BLK, > }; > > /* > -- > 1.9.1 > > > __ >
RE: [PATCH 15/17] tracing/uprobes: Add support for full argument access methods
Patches look good to me. Signed-off-by: Hyeoncheol Lee -Original Message- From: Steven Rostedt [mailto:rost...@goodmis.org] Sent: Friday, January 03, 2014 6:02 AM To: Steven Rostedt Cc: Namhyung Kim; Oleg Nesterov; Masami Hiramatsu; Srikar Dronamraju; Hyeoncheol Lee; zhangwei(Jovi); Arnaldo Carvalho de Melo; Hemant Kumar; LKML; Namhyung Kim Subject: Re: [PATCH 15/17] tracing/uprobes: Add support for full argument access methods On Thu, 2 Jan 2014 15:58:27 -0500 Steven Rostedt wrote: > On Mon, 16 Dec 2013 13:32:14 +0900 > Namhyung Kim wrote: > > > From: Namhyung Kim > > > > Enable to fetch other types of argument for the uprobes. IOW, we > > can access stack, memory, deref, bitfield and retval from uprobes now. > > > > The format for the argument types are same as kprobes (but @SYMBOL > > type is not supported for uprobes), i.e: > > > > @ADDR : Fetch memory at ADDR > > $stackN : Fetch Nth entry of stack (N >= 0) > > $stack : Fetch stack address > > $retval : Fetch return value > > +|-offs(FETCHARG) : Fetch memory at FETCHARG +|- offs address > > > > Note that the retval only can be used with uretprobes. > > > > Original-patch-by: Hyeoncheol Lee > > Where was the original patch posted? And can we get Hyeoncheol's SOB > for this? > Was this the other part of patch 11? Still should have Hyeoncheol's signed-off-by. If you already had it on the original (before the split) then we can add it here too, as he already signed off on the code that this was based on. -- Steve -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
RE: [PATCH 15/17] tracing/uprobes: Add support for full argument access methods
Patches look good to me. Signed-off-by: Hyeoncheol Lee cheol@lge.com -Original Message- From: Steven Rostedt [mailto:rost...@goodmis.org] Sent: Friday, January 03, 2014 6:02 AM To: Steven Rostedt Cc: Namhyung Kim; Oleg Nesterov; Masami Hiramatsu; Srikar Dronamraju; Hyeoncheol Lee; zhangwei(Jovi); Arnaldo Carvalho de Melo; Hemant Kumar; LKML; Namhyung Kim Subject: Re: [PATCH 15/17] tracing/uprobes: Add support for full argument access methods On Thu, 2 Jan 2014 15:58:27 -0500 Steven Rostedt rost...@goodmis.org wrote: On Mon, 16 Dec 2013 13:32:14 +0900 Namhyung Kim namhy...@kernel.org wrote: From: Namhyung Kim namhyung@lge.com Enable to fetch other types of argument for the uprobes. IOW, we can access stack, memory, deref, bitfield and retval from uprobes now. The format for the argument types are same as kprobes (but @SYMBOL type is not supported for uprobes), i.e: @ADDR : Fetch memory at ADDR $stackN : Fetch Nth entry of stack (N = 0) $stack : Fetch stack address $retval : Fetch return value +|-offs(FETCHARG) : Fetch memory at FETCHARG +|- offs address Note that the retval only can be used with uretprobes. Original-patch-by: Hyeoncheol Lee cheol@lge.com Where was the original patch posted? And can we get Hyeoncheol's SOB for this? Was this the other part of patch 11? Still should have Hyeoncheol's signed-off-by. If you already had it on the original (before the split) then we can add it here too, as he already signed off on the code that this was based on. -- Steve -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] fat: instead of constant number, use the i_blkbits of struct inode to calculate the number of blocks
To calculate the number of blocks from the number of clusters, use the i_blkbits of struct inode instead of 9. Signed-off-by: Hyeoncheol Lee --- fs/fat/misc.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/fat/misc.c b/fs/fat/misc.c index 6d93360..ccdf663 100644 --- a/fs/fat/misc.c +++ b/fs/fat/misc.c @@ -156,7 +156,7 @@ int fat_chain_add(struct inode *inode, int new_dclus, int nr_cluster) (llu)(inode->i_blocks >> (sbi->cluster_bits - 9))); fat_cache_inval_inode(inode); } - inode->i_blocks += nr_cluster << (sbi->cluster_bits - 9); + inode->i_blocks += nr_cluster << (sbi->cluster_bits - inode->i_blkbits); return 0; } -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] fat: instead of constant number, use the i_blkbits of struct inode to calculate the number of blocks
To calculate the number of blocks from the number of clusters, use the i_blkbits of struct inode instead of 9. Signed-off-by: Hyeoncheol Lee hyc@gmail.com --- fs/fat/misc.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/fat/misc.c b/fs/fat/misc.c index 6d93360..ccdf663 100644 --- a/fs/fat/misc.c +++ b/fs/fat/misc.c @@ -156,7 +156,7 @@ int fat_chain_add(struct inode *inode, int new_dclus, int nr_cluster) (llu)(inode-i_blocks (sbi-cluster_bits - 9))); fat_cache_inval_inode(inode); } - inode-i_blocks += nr_cluster (sbi-cluster_bits - 9); + inode-i_blocks += nr_cluster (sbi-cluster_bits - inode-i_blkbits); return 0; } -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[tip:perf/core] perf probe: Allow of casting an array of char to string
Commit-ID: 7ce28b5b5b320e26ac6a0e352d5005bce3530e05 Gitweb: http://git.kernel.org/tip/7ce28b5b5b320e26ac6a0e352d5005bce3530e05 Author: Hyeoncheol Lee AuthorDate: Tue, 11 Sep 2012 16:57:28 +0900 Committer: Arnaldo Carvalho de Melo CommitDate: Thu, 24 Jan 2013 16:40:20 -0300 perf probe: Allow of casting an array of char to string Before casting a type of a variable to string, convert_variable_type() confirms that the type is a pointer or an array. then if it is a pointer to char, it is casted to string. but in case of an array of char, it isn't Signed-off-by: H.C. Lee Acked-by: Masami Hiramatsu Cc: Ingo Molnar Cc: Masami Hiramatsu Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Srikar Dronamraju Link: http://lkml.kernel.org/r/CANFS6bb75e8a_UtyAD9yF73hfXDy0N8tSjDz=a+Vna=y8or...@mail.gmail.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/probe-finder.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index 1daf5c1..be03293 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c @@ -413,12 +413,12 @@ static int convert_variable_type(Dwarf_Die *vr_die, dwarf_diename(vr_die), dwarf_diename()); return -EINVAL; } + if (die_get_real_type(, ) == NULL) { + pr_warning("Failed to get a type" + " information.\n"); + return -ENOENT; + } if (ret == DW_TAG_pointer_type) { - if (die_get_real_type(, ) == NULL) { - pr_warning("Failed to get a type" - " information.\n"); - return -ENOENT; - } while (*ref_ptr) ref_ptr = &(*ref_ptr)->next; /* Add new reference with offset +0 */ -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[tip:perf/core] perf probe: Allow of casting an array of char to string
Commit-ID: 7ce28b5b5b320e26ac6a0e352d5005bce3530e05 Gitweb: http://git.kernel.org/tip/7ce28b5b5b320e26ac6a0e352d5005bce3530e05 Author: Hyeoncheol Lee hyc@gmail.com AuthorDate: Tue, 11 Sep 2012 16:57:28 +0900 Committer: Arnaldo Carvalho de Melo a...@redhat.com CommitDate: Thu, 24 Jan 2013 16:40:20 -0300 perf probe: Allow of casting an array of char to string Before casting a type of a variable to string, convert_variable_type() confirms that the type is a pointer or an array. then if it is a pointer to char, it is casted to string. but in case of an array of char, it isn't Signed-off-by: H.C. Lee hyc@gmail.com Acked-by: Masami Hiramatsu masami.hiramatsu...@hitachi.com Cc: Ingo Molnar mi...@redhat.com Cc: Masami Hiramatsu masami.hiramatsu...@hitachi.com Cc: Paul Mackerras pau...@samba.org Cc: Peter Zijlstra a.p.zijls...@chello.nl Cc: Srikar Dronamraju sri...@linux.vnet.ibm.com Link: http://lkml.kernel.org/r/CANFS6bb75e8a_UtyAD9yF73hfXDy0N8tSjDz=a+Vna=y8or...@mail.gmail.com Signed-off-by: Arnaldo Carvalho de Melo a...@redhat.com --- tools/perf/util/probe-finder.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index 1daf5c1..be03293 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c @@ -413,12 +413,12 @@ static int convert_variable_type(Dwarf_Die *vr_die, dwarf_diename(vr_die), dwarf_diename(type)); return -EINVAL; } + if (die_get_real_type(type, type) == NULL) { + pr_warning(Failed to get a type + information.\n); + return -ENOENT; + } if (ret == DW_TAG_pointer_type) { - if (die_get_real_type(type, type) == NULL) { - pr_warning(Failed to get a type - information.\n); - return -ENOENT; - } while (*ref_ptr) ref_ptr = (*ref_ptr)-next; /* Add new reference with offset +0 */ -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] uprobes tracer: Add support for @ADDR, @stackN, dereference, bitfield arguments
Add support for @ADDR, @stackN, dereference, bitfield arguments. Uprobes tracer supported only register argument. @SYMBOL, $retval, $stack are not supported. because a symbol address and whether function starts at a given address can't be known. Uprobes tracer and kprobes tracer have their own fetch type information tables and fetch type functions. But they share printing type functions and some fetch type functions for register, dereference, and bitfield. The common functions are defined in trace_probe.c. Signed-off-by: Hyeoncheol Lee Cc: Masami Hiramatsu Cc: Srikar Dronamraju --- v2 - separate fetch type functions for uprobes and kprobes tracer v3 - define macro for fetch type table definition and fix CHECK_FETCH_FUNCS and string dereference bugs --- kernel/trace/trace_kprobe.c | 97 +- kernel/trace/trace_probe.c | 434 --- kernel/trace/trace_probe.h | 140 +- kernel/trace/trace_uprobe.c | 166 - 4 files changed, 546 insertions(+), 291 deletions(-) diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 1a21170..676f514 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -24,10 +24,102 @@ #define KPROBE_EVENT_SYSTEM "kprobes" +/* Stack fetch function */ +#define DEFINE_FETCH_stack(type) \ +static __kprobes void FETCH_FUNC_NAME(stack, type)(struct pt_regs *regs,\ + void *offset, void *dest) \ +{ \ + *(type *)dest = (type)regs_get_kernel_stack_nth(regs, \ + (unsigned int)((unsigned long)offset)); \ +} +DEFINE_BASIC_FETCH_FUNCS(stack) +#define fetch_stack_string NULL +#define fetch_stack_string_sizeNULL + +/* Memory fetch function */ +#define DEFINE_FETCH_memory(type) \ +static __kprobes void FETCH_FUNC_NAME(memory, type)(struct pt_regs *regs,\ + void *addr, void *dest) \ +{ \ + type retval;\ + if (probe_kernel_address(addr, retval)) \ + *(type *)dest = 0; \ + else\ + *(type *)dest = retval; \ +} +DEFINE_BASIC_FETCH_FUNCS(memory) + +/* + * Fetch a null-terminated string. Caller MUST set *(u32 *)dest with max + * length and relative data location. + */ +static __kprobes void FETCH_FUNC_NAME(memory, string)(struct pt_regs *regs, + void *addr, void *dest) +{ + long ret; + int maxlen = get_rloc_len(*(u32 *)dest); + u8 *dst = get_rloc_data(dest); + u8 *src = addr; + mm_segment_t old_fs = get_fs(); + + if (!maxlen) + return; + + /* +* Try to get string again, since the string can be changed while +* probing. +*/ + set_fs(KERNEL_DS); + pagefault_disable(); + + do + ret = __copy_from_user_inatomic(dst++, src++, 1); + while (dst[-1] && ret == 0 && src - (u8 *)addr < maxlen); + + dst[-1] = '\0'; + pagefault_enable(); + set_fs(old_fs); + + if (ret < 0) { /* Failed to fetch string */ + ((u8 *)get_rloc_data(dest))[0] = '\0'; + *(u32 *)dest = make_data_rloc(0, get_rloc_offs(*(u32 *)dest)); + } else { + *(u32 *)dest = make_data_rloc(src - (u8 *)addr, + get_rloc_offs(*(u32 *)dest)); + } +} + +/* Return the length of string -- including null terminal byte */ +static __kprobes void FETCH_FUNC_NAME(memory, string_size)(struct pt_regs *regs, + void *addr, void *dest) +{ + mm_segment_t old_fs; + int ret, len = 0; + u8 c; + + old_fs = get_fs(); + set_fs(KERNEL_DS); + pagefault_disable(); + + do { + ret = __copy_from_user_inatomic(, (u8 *)addr + len, 1); + len++; + } while (c && ret == 0 && len < MAX_STRING_SIZE); + + pagefault_enable(); + set_fs(old_fs); + + if (ret < 0)/* Failed to check the length */ + *(u32 *)dest = 0; + else + *(u32 *)dest = len; +} + +static DEFINE_FETCH_TYPE_TABLE(fetch_type_table); + /** * Kprobe event core functions */ - struct trace_probe { struct list_headlist; struct kretproberp; /* Use rp.kp for kprobe use */ @@ -525,7 +617,8 @@ static int create_trace_probe(int argc, char **argv)
[PATCH] uprobes tracer: Add support for @ADDR, @stackN, dereference, bitfield arguments
Add support for @ADDR, @stackN, dereference, bitfield arguments. Uprobes tracer supported only register argument. @SYMBOL, $retval, $stack are not supported. because a symbol address and whether function starts at a given address can't be known. Uprobes tracer and kprobes tracer have their own fetch type information tables and fetch type functions. But they share printing type functions and some fetch type functions for register, dereference, and bitfield. The common functions are defined in trace_probe.c. Signed-off-by: Hyeoncheol Lee hyc@gmail.com Cc: Masami Hiramatsu masami.hiramatsu...@hitachi.com Cc: Srikar Dronamraju sri...@linux.vnet.ibm.com --- v2 - separate fetch type functions for uprobes and kprobes tracer v3 - define macro for fetch type table definition and fix CHECK_FETCH_FUNCS and string dereference bugs --- kernel/trace/trace_kprobe.c | 97 +- kernel/trace/trace_probe.c | 434 --- kernel/trace/trace_probe.h | 140 +- kernel/trace/trace_uprobe.c | 166 - 4 files changed, 546 insertions(+), 291 deletions(-) diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 1a21170..676f514 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -24,10 +24,102 @@ #define KPROBE_EVENT_SYSTEM kprobes +/* Stack fetch function */ +#define DEFINE_FETCH_stack(type) \ +static __kprobes void FETCH_FUNC_NAME(stack, type)(struct pt_regs *regs,\ + void *offset, void *dest) \ +{ \ + *(type *)dest = (type)regs_get_kernel_stack_nth(regs, \ + (unsigned int)((unsigned long)offset)); \ +} +DEFINE_BASIC_FETCH_FUNCS(stack) +#define fetch_stack_string NULL +#define fetch_stack_string_sizeNULL + +/* Memory fetch function */ +#define DEFINE_FETCH_memory(type) \ +static __kprobes void FETCH_FUNC_NAME(memory, type)(struct pt_regs *regs,\ + void *addr, void *dest) \ +{ \ + type retval;\ + if (probe_kernel_address(addr, retval)) \ + *(type *)dest = 0; \ + else\ + *(type *)dest = retval; \ +} +DEFINE_BASIC_FETCH_FUNCS(memory) + +/* + * Fetch a null-terminated string. Caller MUST set *(u32 *)dest with max + * length and relative data location. + */ +static __kprobes void FETCH_FUNC_NAME(memory, string)(struct pt_regs *regs, + void *addr, void *dest) +{ + long ret; + int maxlen = get_rloc_len(*(u32 *)dest); + u8 *dst = get_rloc_data(dest); + u8 *src = addr; + mm_segment_t old_fs = get_fs(); + + if (!maxlen) + return; + + /* +* Try to get string again, since the string can be changed while +* probing. +*/ + set_fs(KERNEL_DS); + pagefault_disable(); + + do + ret = __copy_from_user_inatomic(dst++, src++, 1); + while (dst[-1] ret == 0 src - (u8 *)addr maxlen); + + dst[-1] = '\0'; + pagefault_enable(); + set_fs(old_fs); + + if (ret 0) { /* Failed to fetch string */ + ((u8 *)get_rloc_data(dest))[0] = '\0'; + *(u32 *)dest = make_data_rloc(0, get_rloc_offs(*(u32 *)dest)); + } else { + *(u32 *)dest = make_data_rloc(src - (u8 *)addr, + get_rloc_offs(*(u32 *)dest)); + } +} + +/* Return the length of string -- including null terminal byte */ +static __kprobes void FETCH_FUNC_NAME(memory, string_size)(struct pt_regs *regs, + void *addr, void *dest) +{ + mm_segment_t old_fs; + int ret, len = 0; + u8 c; + + old_fs = get_fs(); + set_fs(KERNEL_DS); + pagefault_disable(); + + do { + ret = __copy_from_user_inatomic(c, (u8 *)addr + len, 1); + len++; + } while (c ret == 0 len MAX_STRING_SIZE); + + pagefault_enable(); + set_fs(old_fs); + + if (ret 0)/* Failed to check the length */ + *(u32 *)dest = 0; + else + *(u32 *)dest = len; +} + +static DEFINE_FETCH_TYPE_TABLE(fetch_type_table); + /** * Kprobe event core functions */ - struct trace_probe { struct list_headlist; struct kretproberp; /* Use rp.kp for kprobe use */ @@ -525,7 +617,8 @@ static int create_trace_probe(int argc, char **argv
[PATCH v2] uprobes tracer: Add stack/memory/retval access support
Event arguments except @SYM are supported for uprobes tracer. They are @ADDR, $stack, $stackN, $retval, and off(arguments). uprobes tracer and kprobes tracer have their own fetch type information tables and fetch type functions. But they share printing type functions and some fetch type functions for register, retval, and memory dereference. Common functions are defined in trace_probe.c. Cc: Masami Hiramatsu Cc: Srikar Dronamraju Signed-off-by: Hyeoncheol Lee --- v2 - separate fetch type functions for uprobes and kprobes tracer kernel/trace/trace_kprobe.c | 147 +- kernel/trace/trace_probe.c | 292 --- kernel/trace/trace_probe.h | 79 +++- kernel/trace/trace_uprobe.c | 158 ++- 4 files changed, 460 insertions(+), 216 deletions(-) diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 1a21170..a912946 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -24,10 +24,152 @@ #define KPROBE_EVENT_SYSTEM "kprobes" +/* + * Define macro for basic types - we don't need to define s* types, because + * we have to care only about bitwidth at recording time. + */ +#define DEFINE_BASIC_FETCH_FUNCS(method) \ + DEFINE_FETCH_##method(u8) \ + DEFINE_FETCH_##method(u16) \ + DEFINE_FETCH_##method(u32) \ + DEFINE_FETCH_##method(u64) + +/* Stack fetch function */ +#define DEFINE_FETCH_stack(type) \ +static __kprobes void FETCH_FUNC_NAME(stack, type)(struct pt_regs *regs,\ + void *offset, void *dest) \ +{ \ + *(type *)dest = (type)regs_get_kernel_stack_nth(regs, \ + (unsigned int)((unsigned long)offset)); \ +} +DEFINE_BASIC_FETCH_FUNCS(stack) +#define fetch_stack_string NULL +#define fetch_stack_string_sizeNULL + +/* Memory fetch function */ +#define DEFINE_FETCH_memory(type) \ +static __kprobes void FETCH_FUNC_NAME(memory, type)(struct pt_regs *regs,\ + void *addr, void *dest) \ +{ \ + type retval;\ + if (probe_kernel_address(addr, retval)) \ + *(type *)dest = 0; \ + else\ + *(type *)dest = retval; \ +} +DEFINE_BASIC_FETCH_FUNCS(memory) + +/* + * Fetch a null-terminated string. Caller MUST set *(u32 *)dest with max + * length and relative data location. + */ +static __kprobes void FETCH_FUNC_NAME(memory, string)(struct pt_regs *regs, + void *addr, void *dest) +{ + long ret; + int maxlen = get_rloc_len(*(u32 *)dest); + u8 *dst = get_rloc_data(dest); + u8 *src = addr; + mm_segment_t old_fs = get_fs(); + + if (!maxlen) + return; + + /* +* Try to get string again, since the string can be changed while +* probing. +*/ + set_fs(KERNEL_DS); + pagefault_disable(); + + do + ret = __copy_from_user_inatomic(dst++, src++, 1); + while (dst[-1] && ret == 0 && src - (u8 *)addr < maxlen); + + dst[-1] = '\0'; + pagefault_enable(); + set_fs(old_fs); + + if (ret < 0) { /* Failed to fetch string */ + ((u8 *)get_rloc_data(dest))[0] = '\0'; + *(u32 *)dest = make_data_rloc(0, get_rloc_offs(*(u32 *)dest)); + } else { + *(u32 *)dest = make_data_rloc(src - (u8 *)addr, + get_rloc_offs(*(u32 *)dest)); + } +} + +/* Return the length of string -- including null terminal byte */ +static __kprobes void FETCH_FUNC_NAME(memory, string_size)(struct pt_regs *regs, + void *addr, void *dest) +{ + mm_segment_t old_fs; + int ret, len = 0; + u8 c; + + old_fs = get_fs(); + set_fs(KERNEL_DS); + pagefault_disable(); + + do { + ret = __copy_from_user_inatomic(, (u8 *)addr + len, 1); + len++; + } while (c && ret == 0 && len < MAX_STRING_SIZE); + + pagefault_enable(); + set_fs(old_fs); + + if (ret < 0)/* Failed to check the length */ + *(u32 *)dest = 0; + else + *(u32 *)dest = len; +} + +#define ASSIGN_FETCH_FUNC(method, type)\ + [FETCH_MTD_##method] = FETCH_FUNC_NAME(method, type) + +#define __ASSIGN
[PATCH v2] uprobes tracer: Add stack/memory/retval access support
Event arguments except @SYM are supported for uprobes tracer. They are @ADDR, $stack, $stackN, $retval, and off(arguments). uprobes tracer and kprobes tracer have their own fetch type information tables and fetch type functions. But they share printing type functions and some fetch type functions for register, retval, and memory dereference. Common functions are defined in trace_probe.c. Signed-off-by: Hyeoncheol Lee --- v2 - separate fetch type functions for uprobes and kprobes tracer kernel/trace/trace_kprobe.c | 147 +- kernel/trace/trace_probe.c | 292 --- kernel/trace/trace_probe.h | 79 +++- kernel/trace/trace_uprobe.c | 158 ++- 4 files changed, 460 insertions(+), 216 deletions(-) diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 1a21170..a912946 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -24,10 +24,152 @@ #define KPROBE_EVENT_SYSTEM "kprobes" +/* + * Define macro for basic types - we don't need to define s* types, because + * we have to care only about bitwidth at recording time. + */ +#define DEFINE_BASIC_FETCH_FUNCS(method) \ + DEFINE_FETCH_##method(u8) \ + DEFINE_FETCH_##method(u16) \ + DEFINE_FETCH_##method(u32) \ + DEFINE_FETCH_##method(u64) + +/* Stack fetch function */ +#define DEFINE_FETCH_stack(type) \ +static __kprobes void FETCH_FUNC_NAME(stack, type)(struct pt_regs *regs,\ + void *offset, void *dest) \ +{ \ + *(type *)dest = (type)regs_get_kernel_stack_nth(regs, \ + (unsigned int)((unsigned long)offset)); \ +} +DEFINE_BASIC_FETCH_FUNCS(stack) +#define fetch_stack_string NULL +#define fetch_stack_string_sizeNULL + +/* Memory fetch function */ +#define DEFINE_FETCH_memory(type) \ +static __kprobes void FETCH_FUNC_NAME(memory, type)(struct pt_regs *regs,\ + void *addr, void *dest) \ +{ \ + type retval;\ + if (probe_kernel_address(addr, retval)) \ + *(type *)dest = 0; \ + else\ + *(type *)dest = retval; \ +} +DEFINE_BASIC_FETCH_FUNCS(memory) + +/* + * Fetch a null-terminated string. Caller MUST set *(u32 *)dest with max + * length and relative data location. + */ +static __kprobes void FETCH_FUNC_NAME(memory, string)(struct pt_regs *regs, + void *addr, void *dest) +{ + long ret; + int maxlen = get_rloc_len(*(u32 *)dest); + u8 *dst = get_rloc_data(dest); + u8 *src = addr; + mm_segment_t old_fs = get_fs(); + + if (!maxlen) + return; + + /* +* Try to get string again, since the string can be changed while +* probing. +*/ + set_fs(KERNEL_DS); + pagefault_disable(); + + do + ret = __copy_from_user_inatomic(dst++, src++, 1); + while (dst[-1] && ret == 0 && src - (u8 *)addr < maxlen); + + dst[-1] = '\0'; + pagefault_enable(); + set_fs(old_fs); + + if (ret < 0) { /* Failed to fetch string */ + ((u8 *)get_rloc_data(dest))[0] = '\0'; + *(u32 *)dest = make_data_rloc(0, get_rloc_offs(*(u32 *)dest)); + } else { + *(u32 *)dest = make_data_rloc(src - (u8 *)addr, + get_rloc_offs(*(u32 *)dest)); + } +} + +/* Return the length of string -- including null terminal byte */ +static __kprobes void FETCH_FUNC_NAME(memory, string_size)(struct pt_regs *regs, + void *addr, void *dest) +{ + mm_segment_t old_fs; + int ret, len = 0; + u8 c; + + old_fs = get_fs(); + set_fs(KERNEL_DS); + pagefault_disable(); + + do { + ret = __copy_from_user_inatomic(, (u8 *)addr + len, 1); + len++; + } while (c && ret == 0 && len < MAX_STRING_SIZE); + + pagefault_enable(); + set_fs(old_fs); + + if (ret < 0)/* Failed to check the length */ + *(u32 *)dest = 0; + else + *(u32 *)dest = len; +} + +#define ASSIGN_FETCH_FUNC(method, type)\ + [FETCH_MTD_##method] = FETCH_FUNC_NAME(method, type) + +#define __ASSIGN_FETCH_TYPE(_name, ptype, ftype, _
[PATCH v2] uprobes tracer: Add stack/memory/retval access support
Event arguments except @SYM are supported for uprobes tracer. They are @ADDR, $stack, $stackN, $retval, and off(arguments). uprobes tracer and kprobes tracer have their own fetch type information tables and fetch type functions. But they share printing type functions and some fetch type functions for register, retval, and memory dereference. Common functions are defined in trace_probe.c. Signed-off-by: Hyeoncheol Lee hyc@gmail.com --- v2 - separate fetch type functions for uprobes and kprobes tracer kernel/trace/trace_kprobe.c | 147 +- kernel/trace/trace_probe.c | 292 --- kernel/trace/trace_probe.h | 79 +++- kernel/trace/trace_uprobe.c | 158 ++- 4 files changed, 460 insertions(+), 216 deletions(-) diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 1a21170..a912946 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -24,10 +24,152 @@ #define KPROBE_EVENT_SYSTEM kprobes +/* + * Define macro for basic types - we don't need to define s* types, because + * we have to care only about bitwidth at recording time. + */ +#define DEFINE_BASIC_FETCH_FUNCS(method) \ + DEFINE_FETCH_##method(u8) \ + DEFINE_FETCH_##method(u16) \ + DEFINE_FETCH_##method(u32) \ + DEFINE_FETCH_##method(u64) + +/* Stack fetch function */ +#define DEFINE_FETCH_stack(type) \ +static __kprobes void FETCH_FUNC_NAME(stack, type)(struct pt_regs *regs,\ + void *offset, void *dest) \ +{ \ + *(type *)dest = (type)regs_get_kernel_stack_nth(regs, \ + (unsigned int)((unsigned long)offset)); \ +} +DEFINE_BASIC_FETCH_FUNCS(stack) +#define fetch_stack_string NULL +#define fetch_stack_string_sizeNULL + +/* Memory fetch function */ +#define DEFINE_FETCH_memory(type) \ +static __kprobes void FETCH_FUNC_NAME(memory, type)(struct pt_regs *regs,\ + void *addr, void *dest) \ +{ \ + type retval;\ + if (probe_kernel_address(addr, retval)) \ + *(type *)dest = 0; \ + else\ + *(type *)dest = retval; \ +} +DEFINE_BASIC_FETCH_FUNCS(memory) + +/* + * Fetch a null-terminated string. Caller MUST set *(u32 *)dest with max + * length and relative data location. + */ +static __kprobes void FETCH_FUNC_NAME(memory, string)(struct pt_regs *regs, + void *addr, void *dest) +{ + long ret; + int maxlen = get_rloc_len(*(u32 *)dest); + u8 *dst = get_rloc_data(dest); + u8 *src = addr; + mm_segment_t old_fs = get_fs(); + + if (!maxlen) + return; + + /* +* Try to get string again, since the string can be changed while +* probing. +*/ + set_fs(KERNEL_DS); + pagefault_disable(); + + do + ret = __copy_from_user_inatomic(dst++, src++, 1); + while (dst[-1] ret == 0 src - (u8 *)addr maxlen); + + dst[-1] = '\0'; + pagefault_enable(); + set_fs(old_fs); + + if (ret 0) { /* Failed to fetch string */ + ((u8 *)get_rloc_data(dest))[0] = '\0'; + *(u32 *)dest = make_data_rloc(0, get_rloc_offs(*(u32 *)dest)); + } else { + *(u32 *)dest = make_data_rloc(src - (u8 *)addr, + get_rloc_offs(*(u32 *)dest)); + } +} + +/* Return the length of string -- including null terminal byte */ +static __kprobes void FETCH_FUNC_NAME(memory, string_size)(struct pt_regs *regs, + void *addr, void *dest) +{ + mm_segment_t old_fs; + int ret, len = 0; + u8 c; + + old_fs = get_fs(); + set_fs(KERNEL_DS); + pagefault_disable(); + + do { + ret = __copy_from_user_inatomic(c, (u8 *)addr + len, 1); + len++; + } while (c ret == 0 len MAX_STRING_SIZE); + + pagefault_enable(); + set_fs(old_fs); + + if (ret 0)/* Failed to check the length */ + *(u32 *)dest = 0; + else + *(u32 *)dest = len; +} + +#define ASSIGN_FETCH_FUNC(method, type)\ + [FETCH_MTD_##method] = FETCH_FUNC_NAME(method, type) + +#define __ASSIGN_FETCH_TYPE(_name, ptype, ftype, _size, sign, _fmttype) \ + {.name = _name
[PATCH v2] uprobes tracer: Add stack/memory/retval access support
Event arguments except @SYM are supported for uprobes tracer. They are @ADDR, $stack, $stackN, $retval, and off(arguments). uprobes tracer and kprobes tracer have their own fetch type information tables and fetch type functions. But they share printing type functions and some fetch type functions for register, retval, and memory dereference. Common functions are defined in trace_probe.c. Cc: Masami Hiramatsu masami.hiramatsu...@hitachi.com Cc: Srikar Dronamraju sri...@linux.vnet.ibm.com Signed-off-by: Hyeoncheol Lee hyc@gmail.com --- v2 - separate fetch type functions for uprobes and kprobes tracer kernel/trace/trace_kprobe.c | 147 +- kernel/trace/trace_probe.c | 292 --- kernel/trace/trace_probe.h | 79 +++- kernel/trace/trace_uprobe.c | 158 ++- 4 files changed, 460 insertions(+), 216 deletions(-) diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 1a21170..a912946 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -24,10 +24,152 @@ #define KPROBE_EVENT_SYSTEM kprobes +/* + * Define macro for basic types - we don't need to define s* types, because + * we have to care only about bitwidth at recording time. + */ +#define DEFINE_BASIC_FETCH_FUNCS(method) \ + DEFINE_FETCH_##method(u8) \ + DEFINE_FETCH_##method(u16) \ + DEFINE_FETCH_##method(u32) \ + DEFINE_FETCH_##method(u64) + +/* Stack fetch function */ +#define DEFINE_FETCH_stack(type) \ +static __kprobes void FETCH_FUNC_NAME(stack, type)(struct pt_regs *regs,\ + void *offset, void *dest) \ +{ \ + *(type *)dest = (type)regs_get_kernel_stack_nth(regs, \ + (unsigned int)((unsigned long)offset)); \ +} +DEFINE_BASIC_FETCH_FUNCS(stack) +#define fetch_stack_string NULL +#define fetch_stack_string_sizeNULL + +/* Memory fetch function */ +#define DEFINE_FETCH_memory(type) \ +static __kprobes void FETCH_FUNC_NAME(memory, type)(struct pt_regs *regs,\ + void *addr, void *dest) \ +{ \ + type retval;\ + if (probe_kernel_address(addr, retval)) \ + *(type *)dest = 0; \ + else\ + *(type *)dest = retval; \ +} +DEFINE_BASIC_FETCH_FUNCS(memory) + +/* + * Fetch a null-terminated string. Caller MUST set *(u32 *)dest with max + * length and relative data location. + */ +static __kprobes void FETCH_FUNC_NAME(memory, string)(struct pt_regs *regs, + void *addr, void *dest) +{ + long ret; + int maxlen = get_rloc_len(*(u32 *)dest); + u8 *dst = get_rloc_data(dest); + u8 *src = addr; + mm_segment_t old_fs = get_fs(); + + if (!maxlen) + return; + + /* +* Try to get string again, since the string can be changed while +* probing. +*/ + set_fs(KERNEL_DS); + pagefault_disable(); + + do + ret = __copy_from_user_inatomic(dst++, src++, 1); + while (dst[-1] ret == 0 src - (u8 *)addr maxlen); + + dst[-1] = '\0'; + pagefault_enable(); + set_fs(old_fs); + + if (ret 0) { /* Failed to fetch string */ + ((u8 *)get_rloc_data(dest))[0] = '\0'; + *(u32 *)dest = make_data_rloc(0, get_rloc_offs(*(u32 *)dest)); + } else { + *(u32 *)dest = make_data_rloc(src - (u8 *)addr, + get_rloc_offs(*(u32 *)dest)); + } +} + +/* Return the length of string -- including null terminal byte */ +static __kprobes void FETCH_FUNC_NAME(memory, string_size)(struct pt_regs *regs, + void *addr, void *dest) +{ + mm_segment_t old_fs; + int ret, len = 0; + u8 c; + + old_fs = get_fs(); + set_fs(KERNEL_DS); + pagefault_disable(); + + do { + ret = __copy_from_user_inatomic(c, (u8 *)addr + len, 1); + len++; + } while (c ret == 0 len MAX_STRING_SIZE); + + pagefault_enable(); + set_fs(old_fs); + + if (ret 0)/* Failed to check the length */ + *(u32 *)dest = 0; + else + *(u32 *)dest = len; +} + +#define ASSIGN_FETCH_FUNC(method, type)\ + [FETCH_MTD_##method] = FETCH_FUNC_NAME(method, type) + +#define
[PATCH v2] perf probe: convert_name_to_addr() allocated the wrong size buffers for names
The function allocated wrong size buffers for names Cc: Masami Hiramatsu Cc: Srikar Dronamraju Signed-off-by: Hyeoncheol Lee --- v2: - Added a comment for MAX_ADDRNAME_LEN tools/perf/util/probe-event.c | 17 + 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 49a256e..661bbdf 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -2274,6 +2274,14 @@ int show_available_funcs(const char *target, struct strfilter *_filter, } /* + * MAX_ADDRNAME_LEN is the maximum length of a function name for uprobe_events + * Because each half byte is encoded in one hex character, + * sizeof(type)*2 is the maximum length of hexadecimal number of the type. + * Another 3 bytes are for "0x" and a null character + */ +#define MAX_ADDRNAME_LEN (3 + sizeof(unsigned long long) * 2) + +/* * uprobe_events only accepts address: * Convert function and any offset to address */ @@ -2332,7 +2340,7 @@ static int convert_name_to_addr(struct perf_probe_event *pev, const char *exec) if (!pev->group) { char *ptr1, *ptr2, *exec_copy; - pev->group = zalloc(sizeof(char *) * 64); + pev->group = zalloc(sizeof(char) * 64); exec_copy = strdup(exec); if (!exec_copy) { ret = -ENOMEM; @@ -2352,14 +2360,15 @@ static int convert_name_to_addr(struct perf_probe_event *pev, const char *exec) free(exec_copy); } free(pp->function); - pp->function = zalloc(sizeof(char *) * MAX_PROBE_ARGS); + pp->function = zalloc(sizeof(char) * MAX_ADDRNAME_LEN); if (!pp->function) { ret = -ENOMEM; pr_warning("Failed to allocate memory by zalloc.\n"); goto out; } - e_snprintf(pp->function, MAX_PROBE_ARGS, "0x%llx", vaddr); - ret = 0; + ret = e_snprintf(pp->function, MAX_ADDRNAME_LEN, "0x%llx", vaddr); + if (ret > 0) + ret = 0; out: if (map) { -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] uprobes tracer: Add stack/memory/retval access support
2012/10/16 Masami Hiramatsu : > (2012/10/16 18:02), Hyeoncheol Lee wrote: >> Event arguments except @SYM are supported. They are @ADDR, >> $stack, $stackN, $retval, and offs(arguments). >> >> Cc: Masami Hiramatsu >> Cc: Srikar Dronamraju >> Signed-off-by: Hyeoncheol Lee >> --- > > [...] >> #define DEFINE_FETCH_stack(type) \ >> static __kprobes void FETCH_FUNC_NAME(stack, type)(struct pt_regs *regs,\ >> - void *offset, void *dest) \ >> + void *offset, void *dest, \ >> + bool kprobe) \ >> {\ >> - *(type *)dest = (type)regs_get_kernel_stack_nth(regs, \ >> + if (kprobe) \ >> + *(type *)dest = (type)regs_get_kernel_stack_nth(regs, \ >> (unsigned int)((unsigned long)offset)); \ >> + else\ >> + *(type *)dest = (type)regs_get_user_stack_nth(regs, \ >> + (unsigned int)((unsigned long)offset)); \ >> } > > > Hmm, I don't think this is a good way to do that. > If fetching user space objects is different from the kernel one, > we'd better introduce new fetch handlers for it, instead of checking > a bool flag every time, because it will be done on every events. > > Thank you, > > > -- > Masami HIRAMATSU > IT Management Research Dept. Linux Technology Center > Hitachi, Ltd., Yokohama Research Laboratory > E-mail: masami.hiramatsu...@hitachi.com > > Yes Thank you for your comment -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] perf probe: convert_name_to_addr() allocated the wrong size buffers for names
The function allocated wrong size buffers for names Cc: Masami Hiramatsu Cc: Srikar Dronamraju Signed-off-by: Hyeoncheol Lee --- tools/perf/util/probe-event.c | 11 +++ 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 49a256e..5cd7c42 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -2273,6 +2273,8 @@ int show_available_funcs(const char *target, struct strfilter *_filter, return available_user_funcs(target); } +#define MAX_ADDRNAME_LEN (3 + sizeof(unsigned long long) * 2) + /* * uprobe_events only accepts address: * Convert function and any offset to address @@ -2332,7 +2334,7 @@ static int convert_name_to_addr(struct perf_probe_event *pev, const char *exec) if (!pev->group) { char *ptr1, *ptr2, *exec_copy; - pev->group = zalloc(sizeof(char *) * 64); + pev->group = zalloc(sizeof(char) * 64); exec_copy = strdup(exec); if (!exec_copy) { ret = -ENOMEM; @@ -2352,14 +2354,15 @@ static int convert_name_to_addr(struct perf_probe_event *pev, const char *exec) free(exec_copy); } free(pp->function); - pp->function = zalloc(sizeof(char *) * MAX_PROBE_ARGS); + pp->function = zalloc(sizeof(char) * MAX_ADDRNAME_LEN); if (!pp->function) { ret = -ENOMEM; pr_warning("Failed to allocate memory by zalloc.\n"); goto out; } - e_snprintf(pp->function, MAX_PROBE_ARGS, "0x%llx", vaddr); - ret = 0; + ret = e_snprintf(pp->function, MAX_ADDRNAME_LEN, "0x%llx", vaddr); + if (ret > 0) + ret = 0; out: if (map) { -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] perf probe: convert_name_to_addr() allocated the wrong size buffers for names
The function allocated wrong size buffers for names Cc: Masami Hiramatsu masami.hiramatsu...@hitachi.com Cc: Srikar Dronamraju sri...@linux.vnet.ibm.com Signed-off-by: Hyeoncheol Lee hyc@gmail.com --- tools/perf/util/probe-event.c | 11 +++ 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 49a256e..5cd7c42 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -2273,6 +2273,8 @@ int show_available_funcs(const char *target, struct strfilter *_filter, return available_user_funcs(target); } +#define MAX_ADDRNAME_LEN (3 + sizeof(unsigned long long) * 2) + /* * uprobe_events only accepts address: * Convert function and any offset to address @@ -2332,7 +2334,7 @@ static int convert_name_to_addr(struct perf_probe_event *pev, const char *exec) if (!pev-group) { char *ptr1, *ptr2, *exec_copy; - pev-group = zalloc(sizeof(char *) * 64); + pev-group = zalloc(sizeof(char) * 64); exec_copy = strdup(exec); if (!exec_copy) { ret = -ENOMEM; @@ -2352,14 +2354,15 @@ static int convert_name_to_addr(struct perf_probe_event *pev, const char *exec) free(exec_copy); } free(pp-function); - pp-function = zalloc(sizeof(char *) * MAX_PROBE_ARGS); + pp-function = zalloc(sizeof(char) * MAX_ADDRNAME_LEN); if (!pp-function) { ret = -ENOMEM; pr_warning(Failed to allocate memory by zalloc.\n); goto out; } - e_snprintf(pp-function, MAX_PROBE_ARGS, 0x%llx, vaddr); - ret = 0; + ret = e_snprintf(pp-function, MAX_ADDRNAME_LEN, 0x%llx, vaddr); + if (ret 0) + ret = 0; out: if (map) { -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] uprobes tracer: Add stack/memory/retval access support
2012/10/16 Masami Hiramatsu masami.hiramatsu...@hitachi.com: (2012/10/16 18:02), Hyeoncheol Lee wrote: Event arguments except @SYM are supported. They are @ADDR, $stack, $stackN, $retval, and offs(arguments). Cc: Masami Hiramatsu masami.hiramatsu...@hitachi.com Cc: Srikar Dronamraju sri...@linux.vnet.ibm.com Signed-off-by: Hyeoncheol Lee hyc@gmail.com --- [...] #define DEFINE_FETCH_stack(type) \ static __kprobes void FETCH_FUNC_NAME(stack, type)(struct pt_regs *regs,\ - void *offset, void *dest) \ + void *offset, void *dest, \ + bool kprobe) \ {\ - *(type *)dest = (type)regs_get_kernel_stack_nth(regs, \ + if (kprobe) \ + *(type *)dest = (type)regs_get_kernel_stack_nth(regs, \ (unsigned int)((unsigned long)offset)); \ + else\ + *(type *)dest = (type)regs_get_user_stack_nth(regs, \ + (unsigned int)((unsigned long)offset)); \ } Hmm, I don't think this is a good way to do that. If fetching user space objects is different from the kernel one, we'd better introduce new fetch handlers for it, instead of checking a bool flag every time, because it will be done on every events. Thank you, -- Masami HIRAMATSU IT Management Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: masami.hiramatsu...@hitachi.com Yes Thank you for your comment -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2] perf probe: convert_name_to_addr() allocated the wrong size buffers for names
The function allocated wrong size buffers for names Cc: Masami Hiramatsu masami.hiramatsu...@hitachi.com Cc: Srikar Dronamraju sri...@linux.vnet.ibm.com Signed-off-by: Hyeoncheol Lee hyc@gmail.com --- v2: - Added a comment for MAX_ADDRNAME_LEN tools/perf/util/probe-event.c | 17 + 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 49a256e..661bbdf 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -2274,6 +2274,14 @@ int show_available_funcs(const char *target, struct strfilter *_filter, } /* + * MAX_ADDRNAME_LEN is the maximum length of a function name for uprobe_events + * Because each half byte is encoded in one hex character, + * sizeof(type)*2 is the maximum length of hexadecimal number of the type. + * Another 3 bytes are for 0x and a null character + */ +#define MAX_ADDRNAME_LEN (3 + sizeof(unsigned long long) * 2) + +/* * uprobe_events only accepts address: * Convert function and any offset to address */ @@ -2332,7 +2340,7 @@ static int convert_name_to_addr(struct perf_probe_event *pev, const char *exec) if (!pev-group) { char *ptr1, *ptr2, *exec_copy; - pev-group = zalloc(sizeof(char *) * 64); + pev-group = zalloc(sizeof(char) * 64); exec_copy = strdup(exec); if (!exec_copy) { ret = -ENOMEM; @@ -2352,14 +2360,15 @@ static int convert_name_to_addr(struct perf_probe_event *pev, const char *exec) free(exec_copy); } free(pp-function); - pp-function = zalloc(sizeof(char *) * MAX_PROBE_ARGS); + pp-function = zalloc(sizeof(char) * MAX_ADDRNAME_LEN); if (!pp-function) { ret = -ENOMEM; pr_warning(Failed to allocate memory by zalloc.\n); goto out; } - e_snprintf(pp-function, MAX_PROBE_ARGS, 0x%llx, vaddr); - ret = 0; + ret = e_snprintf(pp-function, MAX_ADDRNAME_LEN, 0x%llx, vaddr); + if (ret 0) + ret = 0; out: if (map) { -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] uprobes tracer: Add stack/memory/retval access support
Event arguments except @SYM are supported. They are @ADDR, $stack, $stackN, $retval, and offs(arguments). Cc: Masami Hiramatsu Cc: Srikar Dronamraju Signed-off-by: Hyeoncheol Lee --- kernel/trace/trace_kprobe.c |6 +- kernel/trace/trace_probe.c | 162 ++- kernel/trace/trace_probe.h |6 +- kernel/trace/trace_uprobe.c |6 +- 4 files changed, 124 insertions(+), 56 deletions(-) diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 1a21170..60046d3 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -683,7 +683,7 @@ static __kprobes int __get_data_size(struct trace_probe *tp, for (i = 0; i < tp->nr_args; i++) if (unlikely(tp->args[i].fetch_size.fn)) { - call_fetch(>args[i].fetch_size, regs, ); + call_fetch(>args[i].fetch_size, regs, , true); ret += len; } @@ -708,7 +708,7 @@ static __kprobes void store_trace_args(int ent_size, struct trace_probe *tp, dl = (u32 *)(data + tp->args[i].offset); *dl = make_data_rloc(maxlen, end - tp->args[i].offset); /* Then try to fetch string or dynamic array data */ - call_fetch(>args[i].fetch, regs, dl); + call_fetch(>args[i].fetch, regs, dl, true); /* Reduce maximum length */ end += get_rloc_len(*dl); maxlen -= get_rloc_len(*dl); @@ -718,7 +718,7 @@ static __kprobes void store_trace_args(int ent_size, struct trace_probe *tp, } else /* Just fetching data normally */ call_fetch(>args[i].fetch, regs, - data + tp->args[i].offset); + data + tp->args[i].offset, true); } } diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c index daa9980..955c3fa 100644 --- a/kernel/trace/trace_probe.c +++ b/kernel/trace/trace_probe.c @@ -112,7 +112,8 @@ DEFINE_FETCH_##method(u64) /* Data fetch function templates */ #define DEFINE_FETCH_reg(type) \ static __kprobes void FETCH_FUNC_NAME(reg, type)(struct pt_regs *regs, \ - void *offset, void *dest) \ + void *offset, void *dest, \ + bool kprobe)\ { \ *(type *)dest = (type)regs_get_register(regs, \ (unsigned int)((unsigned long)offset)); \ @@ -122,12 +123,49 @@ DEFINE_BASIC_FETCH_FUNCS(reg) #define fetch_reg_string NULL #define fetch_reg_string_size NULL +#ifdef CONFIG_STACK_GROWSUP +#defineWITHIN_USER_STACK(vma, addr, n) \ + ( \ + addr -= n, \ + (vma)->vm_start <= (unsigned long)(addr)\ + ) +#else +#defineWITHIN_USER_STACK(vma, addr, n) \ + ( \ + addr += n, \ + (vma)->vm_end >= (unsigned long)(addr) \ + ) +#endif + +static unsigned long regs_get_user_stack_nth(struct pt_regs *regs, +unsigned int n) +{ + struct vm_area_struct *vma; + unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs); + unsigned long ret = 0; + + down_read(>mm->mmap_sem); + vma = find_vma(current->mm, (unsigned long)addr); + if (vma && vma->vm_start <= (unsigned long)addr) { + if (WITHIN_USER_STACK(vma, addr, n)) + if (get_user(ret, addr) != 0) + ret = 0; + } + up_read(>mm->mmap_sem); + return ret; +} + #define DEFINE_FETCH_stack(type) \ static __kprobes void FETCH_FUNC_NAME(stack, type)(struct pt_regs *regs,\ - void *offset, void *dest) \ + void *offset, void *dest, \ + bool kprobe) \ { \ - *(type *)dest = (type)regs_get_kernel_stack_nth(regs, \ + if (kprobe) \ + *(type *)dest = (type)regs_get_kernel_stack_nth(regs, \
Re: [PATCH] perf probe: convert_name_to_addr() allocated the wrong size buffer for a function name
Hi, 2012/10/16 Srikar Dronamraju : > * Masami Hiramatsu [2012-10-16 13:19:57]: > >> (2012/10/16 10:37), Hyeoncheol Lee wrote: >> > convert_name_to_addr() allocated sizeof(char *) * MAX_PROBE_ARGS >> > bytes for a function name >> >> Yeah, that one was from my laziness... >> > > Guess not your fault, but mine. > >> > >> > Cc: Masami Hiramatsu >> > Cc: Srikar Dronamraju >> > Signed-off-by: Hyeoncheol Lee >> > --- >> > tools/perf/util/probe-event.c |5 +++-- >> > 1 file changed, 3 insertions(+), 2 deletions(-) >> > >> > diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c >> > index 49a256e..bb40ed4 100644 >> > --- a/tools/perf/util/probe-event.c >> > +++ b/tools/perf/util/probe-event.c >> > @@ -2352,13 +2352,14 @@ static int convert_name_to_addr(struct >> > perf_probe_event *pev, const char *exec) >> > free(exec_copy); >> > } >> > free(pp->function); >> > - pp->function = zalloc(sizeof(char *) * MAX_PROBE_ARGS); >> > + pp->function = zalloc(sizeof(char) * >> > + (3 + sizeof(unsigned long long) * 2)); >> >> Could you comment that this is enough long here? > > Also can we move the arith into a macro? > I will do. >> >> > if (!pp->function) { >> > ret = -ENOMEM; >> > pr_warning("Failed to allocate memory by zalloc.\n"); >> > goto out; >> > } >> > - e_snprintf(pp->function, MAX_PROBE_ARGS, "0x%llx", vaddr); >> > + sprintf(pp->function, "0x%llx", vaddr); >> >> And at least we should use snprintf instead of sprintf... >> (I think ret = e_snprintf(...) is better) >> > > Agree. Yes > >> > ret = 0; >> > >> > out: >> > >> > > -- > Thanks and Regards > Srikar > Thank you for your comment. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] perf probe: convert_name_to_addr() allocated the wrong size buffer for a function name
Hi, 2012/10/16 Masami Hiramatsu : > (2012/10/16 10:37), Hyeoncheol Lee wrote: >> convert_name_to_addr() allocated sizeof(char *) * MAX_PROBE_ARGS >> bytes for a function name > > Yeah, that one was from my laziness... > >> >> Cc: Masami Hiramatsu >> Cc: Srikar Dronamraju >> Signed-off-by: Hyeoncheol Lee >> --- >> tools/perf/util/probe-event.c |5 +++-- >> 1 file changed, 3 insertions(+), 2 deletions(-) >> >> diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c >> index 49a256e..bb40ed4 100644 >> --- a/tools/perf/util/probe-event.c >> +++ b/tools/perf/util/probe-event.c >> @@ -2352,13 +2352,14 @@ static int convert_name_to_addr(struct >> perf_probe_event *pev, const char *exec) >> free(exec_copy); >> } >> free(pp->function); >> - pp->function = zalloc(sizeof(char *) * MAX_PROBE_ARGS); >> + pp->function = zalloc(sizeof(char) * >> + (3 + sizeof(unsigned long long) * 2)); > > Could you comment that this is enough long here? > Because a hexadecimal address that starts with "0x" will be stored in pp->function. sizeof(unsigned long long) * 2 is maximum length of hexadecimal number of variable "vaddr" and 3 bytes are for "0x" and null character. >> if (!pp->function) { >> ret = -ENOMEM; >> pr_warning("Failed to allocate memory by zalloc.\n"); >> goto out; >> } >> - e_snprintf(pp->function, MAX_PROBE_ARGS, "0x%llx", vaddr); >> + sprintf(pp->function, "0x%llx", vaddr); > > And at least we should use snprintf instead of sprintf... > (I think ret = e_snprintf(...) is better) > You are right, but I didn't want to write down the length of "pp->function" again. >> ret = 0; >> >> out: >> > > Thank you, > > -- > Masami HIRAMATSU > IT Management Research Dept. Linux Technology Center > Hitachi, Ltd., Yokohama Research Laboratory > E-mail: masami.hiramatsu...@hitachi.com > > Thank you very much! -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] perf probe: convert_name_to_addr() allocated the wrong size buffer for a function name
Hi, 2012/10/16 Masami Hiramatsu masami.hiramatsu...@hitachi.com: (2012/10/16 10:37), Hyeoncheol Lee wrote: convert_name_to_addr() allocated sizeof(char *) * MAX_PROBE_ARGS bytes for a function name Yeah, that one was from my laziness... Cc: Masami Hiramatsu masami.hiramatsu...@hitachi.com Cc: Srikar Dronamraju sri...@linux.vnet.ibm.com Signed-off-by: Hyeoncheol Lee hyc@gmail.com --- tools/perf/util/probe-event.c |5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 49a256e..bb40ed4 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -2352,13 +2352,14 @@ static int convert_name_to_addr(struct perf_probe_event *pev, const char *exec) free(exec_copy); } free(pp-function); - pp-function = zalloc(sizeof(char *) * MAX_PROBE_ARGS); + pp-function = zalloc(sizeof(char) * + (3 + sizeof(unsigned long long) * 2)); Could you comment that this is enough long here? Because a hexadecimal address that starts with 0x will be stored in pp-function. sizeof(unsigned long long) * 2 is maximum length of hexadecimal number of variable vaddr and 3 bytes are for 0x and null character. if (!pp-function) { ret = -ENOMEM; pr_warning(Failed to allocate memory by zalloc.\n); goto out; } - e_snprintf(pp-function, MAX_PROBE_ARGS, 0x%llx, vaddr); + sprintf(pp-function, 0x%llx, vaddr); And at least we should use snprintf instead of sprintf... (I think ret = e_snprintf(...) is better) You are right, but I didn't want to write down the length of pp-function again. ret = 0; out: Thank you, -- Masami HIRAMATSU IT Management Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: masami.hiramatsu...@hitachi.com Thank you very much! -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] perf probe: convert_name_to_addr() allocated the wrong size buffer for a function name
Hi, 2012/10/16 Srikar Dronamraju sri...@linux.vnet.ibm.com: * Masami Hiramatsu masami.hiramatsu...@hitachi.com [2012-10-16 13:19:57]: (2012/10/16 10:37), Hyeoncheol Lee wrote: convert_name_to_addr() allocated sizeof(char *) * MAX_PROBE_ARGS bytes for a function name Yeah, that one was from my laziness... Guess not your fault, but mine. Cc: Masami Hiramatsu masami.hiramatsu...@hitachi.com Cc: Srikar Dronamraju sri...@linux.vnet.ibm.com Signed-off-by: Hyeoncheol Lee hyc@gmail.com --- tools/perf/util/probe-event.c |5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 49a256e..bb40ed4 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -2352,13 +2352,14 @@ static int convert_name_to_addr(struct perf_probe_event *pev, const char *exec) free(exec_copy); } free(pp-function); - pp-function = zalloc(sizeof(char *) * MAX_PROBE_ARGS); + pp-function = zalloc(sizeof(char) * + (3 + sizeof(unsigned long long) * 2)); Could you comment that this is enough long here? Also can we move the arith into a macro? I will do. if (!pp-function) { ret = -ENOMEM; pr_warning(Failed to allocate memory by zalloc.\n); goto out; } - e_snprintf(pp-function, MAX_PROBE_ARGS, 0x%llx, vaddr); + sprintf(pp-function, 0x%llx, vaddr); And at least we should use snprintf instead of sprintf... (I think ret = e_snprintf(...) is better) Agree. Yes ret = 0; out: -- Thanks and Regards Srikar Thank you for your comment. -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] uprobes tracer: Add stack/memory/retval access support
Event arguments except @SYM are supported. They are @ADDR, $stack, $stackN, $retval, and offs(arguments). Cc: Masami Hiramatsu masami.hiramatsu...@hitachi.com Cc: Srikar Dronamraju sri...@linux.vnet.ibm.com Signed-off-by: Hyeoncheol Lee hyc@gmail.com --- kernel/trace/trace_kprobe.c |6 +- kernel/trace/trace_probe.c | 162 ++- kernel/trace/trace_probe.h |6 +- kernel/trace/trace_uprobe.c |6 +- 4 files changed, 124 insertions(+), 56 deletions(-) diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 1a21170..60046d3 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -683,7 +683,7 @@ static __kprobes int __get_data_size(struct trace_probe *tp, for (i = 0; i tp-nr_args; i++) if (unlikely(tp-args[i].fetch_size.fn)) { - call_fetch(tp-args[i].fetch_size, regs, len); + call_fetch(tp-args[i].fetch_size, regs, len, true); ret += len; } @@ -708,7 +708,7 @@ static __kprobes void store_trace_args(int ent_size, struct trace_probe *tp, dl = (u32 *)(data + tp-args[i].offset); *dl = make_data_rloc(maxlen, end - tp-args[i].offset); /* Then try to fetch string or dynamic array data */ - call_fetch(tp-args[i].fetch, regs, dl); + call_fetch(tp-args[i].fetch, regs, dl, true); /* Reduce maximum length */ end += get_rloc_len(*dl); maxlen -= get_rloc_len(*dl); @@ -718,7 +718,7 @@ static __kprobes void store_trace_args(int ent_size, struct trace_probe *tp, } else /* Just fetching data normally */ call_fetch(tp-args[i].fetch, regs, - data + tp-args[i].offset); + data + tp-args[i].offset, true); } } diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c index daa9980..955c3fa 100644 --- a/kernel/trace/trace_probe.c +++ b/kernel/trace/trace_probe.c @@ -112,7 +112,8 @@ DEFINE_FETCH_##method(u64) /* Data fetch function templates */ #define DEFINE_FETCH_reg(type) \ static __kprobes void FETCH_FUNC_NAME(reg, type)(struct pt_regs *regs, \ - void *offset, void *dest) \ + void *offset, void *dest, \ + bool kprobe)\ { \ *(type *)dest = (type)regs_get_register(regs, \ (unsigned int)((unsigned long)offset)); \ @@ -122,12 +123,49 @@ DEFINE_BASIC_FETCH_FUNCS(reg) #define fetch_reg_string NULL #define fetch_reg_string_size NULL +#ifdef CONFIG_STACK_GROWSUP +#defineWITHIN_USER_STACK(vma, addr, n) \ + ( \ + addr -= n, \ + (vma)-vm_start = (unsigned long)(addr)\ + ) +#else +#defineWITHIN_USER_STACK(vma, addr, n) \ + ( \ + addr += n, \ + (vma)-vm_end = (unsigned long)(addr) \ + ) +#endif + +static unsigned long regs_get_user_stack_nth(struct pt_regs *regs, +unsigned int n) +{ + struct vm_area_struct *vma; + unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs); + unsigned long ret = 0; + + down_read(current-mm-mmap_sem); + vma = find_vma(current-mm, (unsigned long)addr); + if (vma vma-vm_start = (unsigned long)addr) { + if (WITHIN_USER_STACK(vma, addr, n)) + if (get_user(ret, addr) != 0) + ret = 0; + } + up_read(current-mm-mmap_sem); + return ret; +} + #define DEFINE_FETCH_stack(type) \ static __kprobes void FETCH_FUNC_NAME(stack, type)(struct pt_regs *regs,\ - void *offset, void *dest) \ + void *offset, void *dest, \ + bool kprobe) \ { \ - *(type *)dest = (type)regs_get_kernel_stack_nth(regs, \ + if (kprobe) \ + *(type *)dest = (type)regs_get_kernel_stack_nth(regs
[PATCH] perf probe: convert_name_to_addr() allocated the wrong size buffer for a function name
convert_name_to_addr() allocated sizeof(char *) * MAX_PROBE_ARGS bytes for a function name Cc: Masami Hiramatsu Cc: Srikar Dronamraju Signed-off-by: Hyeoncheol Lee --- tools/perf/util/probe-event.c |5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 49a256e..bb40ed4 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -2352,13 +2352,14 @@ static int convert_name_to_addr(struct perf_probe_event *pev, const char *exec) free(exec_copy); } free(pp->function); - pp->function = zalloc(sizeof(char *) * MAX_PROBE_ARGS); + pp->function = zalloc(sizeof(char) * + (3 + sizeof(unsigned long long) * 2)); if (!pp->function) { ret = -ENOMEM; pr_warning("Failed to allocate memory by zalloc.\n"); goto out; } - e_snprintf(pp->function, MAX_PROBE_ARGS, "0x%llx", vaddr); + sprintf(pp->function, "0x%llx", vaddr); ret = 0; out: -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] perf probe: convert_name_to_addr() allocated the wrong size buffer for a function name
convert_name_to_addr() allocated sizeof(char *) * MAX_PROBE_ARGS bytes for a function name Cc: Masami Hiramatsu masami.hiramatsu...@hitachi.com Cc: Srikar Dronamraju sri...@linux.vnet.ibm.com Signed-off-by: Hyeoncheol Lee hyc@gmail.com --- tools/perf/util/probe-event.c |5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 49a256e..bb40ed4 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -2352,13 +2352,14 @@ static int convert_name_to_addr(struct perf_probe_event *pev, const char *exec) free(exec_copy); } free(pp-function); - pp-function = zalloc(sizeof(char *) * MAX_PROBE_ARGS); + pp-function = zalloc(sizeof(char) * + (3 + sizeof(unsigned long long) * 2)); if (!pp-function) { ret = -ENOMEM; pr_warning(Failed to allocate memory by zalloc.\n); goto out; } - e_snprintf(pp-function, MAX_PROBE_ARGS, 0x%llx, vaddr); + sprintf(pp-function, 0x%llx, vaddr); ret = 0; out: -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] perf probe: print an enum type variable in "enum variable-name" format when showing accessible variables
When showing accessible variables, an enum type variable was printed in "variable-name" format. Change this format into "enum variable-name". Cc: Masami Hiramatsu Signed-off-by: Hyeoncheol Lee --- tools/perf/util/dwarf-aux.c |2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c index ee51e9b..3e5f543 100644 --- a/tools/perf/util/dwarf-aux.c +++ b/tools/perf/util/dwarf-aux.c @@ -804,6 +804,8 @@ int die_get_typename(Dwarf_Die *vr_die, char *buf, int len) tmp = "union "; else if (tag == DW_TAG_structure_type) tmp = "struct "; + else if (tag == DW_TAG_enumeration_type) + tmp = "enum "; /* Write a base name */ ret = snprintf(buf, len, "%s%s", tmp, dwarf_diename()); return (ret >= len) ? -E2BIG : ret; -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [QUESTION] Can uprobe_event support @ADDR, $retval, offs(FETCHARG)?
2012/9/26 Srikar Dronamraju : >> >> Perhaps, it is not so small things, but at least, we can try. >> In the userspace, memories(pages) can be paged out on swap or >> files. In that case, memory dereference function needs to track >> down the data on the disk and it causes I/O. This means we will >> see the visible performance degradation with tracing. >> And also, sometime a pointer value (address) is broken, in that >> case we have to ensure the address is actually valid before >> accessing it. >> >> Of cause, without tracking paged-out data, it is easy >> to support, because that is already done in kprobe event. >> I'm not sure how it is useful, because sometimes it will >> fail to access gather the data. >> However it is good for the first step, I think. >> >> Srikar, what would you think? > > I think we should do the best effort basis first. i.e support for > tracking data thats not paged out. > Most times the data that is requested tends to the hot data. > > We could look at supporting data that is paged out later. > >> >> BTW, if we can support offs(FETCHARGS), $stack and $stackN >> are also available. ;) >> > > -- > Thanks and Regards > Srikar Dronamraju > I asked this question. because I need Perf that supports to access user process's variables. and I am trying to add this feature. Thank you for your answer. Hyeoncheol -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [QUESTION] Can uprobe_event support @ADDR, $retval, offs(FETCHARG)?
Hi, 2012/9/26 Masami Hiramatsu : > (2012/09/26 11:52), Hyeoncheol Lee wrote: >> Hi, >> >> uprobe_event only supports %REG arguments. I think that memory fetch, >> return value fetch, memory dereference functions in >> kernel/trace/trace_probe.c are good for uprobe_event. So with a little >> modification of parse_probe_arg(), uprobe_event can support @ADDR, >> $retval, offs(FETCHARGS) except @SYM, $stack, $stackN. Is it right? > > Hi Hyeoncheol, > > Perhaps, it is not so small things, but at least, we can try. > In the userspace, memories(pages) can be paged out on swap or > files. In that case, memory dereference function needs to track > down the data on the disk and it causes I/O. This means we will > see the visible performance degradation with tracing. > And also, sometime a pointer value (address) is broken, in that > case we have to ensure the address is actually valid before > accessing it. > > Of cause, without tracking paged-out data, it is easy > to support, because that is already done in kprobe event. > I'm not sure how it is useful, because sometimes it will > fail to access gather the data. > However it is good for the first step, I think. Yes, we should consider paged-out data. I forgot this. > > Srikar, what would you think? > > BTW, if we can support offs(FETCHARGS), $stack and $stackN > are also available. ;) Yes, but we should check whether the given address is in an user stack or not. and these require CPU architecture dependent codes. > > Thank you, > > -- > Masami HIRAMATSU > Software Platform Research Dept. Linux Technology Center > Hitachi, Ltd., Yokohama Research Laboratory > E-mail: masami.hiramatsu...@hitachi.com > > Thanks for your answer. It is very help to me. ;) Hyeoncheol -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [QUESTION] Can uprobe_event support @ADDR, $retval, offs(FETCHARG)?
Hi, 2012/9/26 Masami Hiramatsu masami.hiramatsu...@hitachi.com: (2012/09/26 11:52), Hyeoncheol Lee wrote: Hi, uprobe_event only supports %REG arguments. I think that memory fetch, return value fetch, memory dereference functions in kernel/trace/trace_probe.c are good for uprobe_event. So with a little modification of parse_probe_arg(), uprobe_event can support @ADDR, $retval, offs(FETCHARGS) except @SYM, $stack, $stackN. Is it right? Hi Hyeoncheol, Perhaps, it is not so small things, but at least, we can try. In the userspace, memories(pages) can be paged out on swap or files. In that case, memory dereference function needs to track down the data on the disk and it causes I/O. This means we will see the visible performance degradation with tracing. And also, sometime a pointer value (address) is broken, in that case we have to ensure the address is actually valid before accessing it. Of cause, without tracking paged-out data, it is easy to support, because that is already done in kprobe event. I'm not sure how it is useful, because sometimes it will fail to access gather the data. However it is good for the first step, I think. Yes, we should consider paged-out data. I forgot this. Srikar, what would you think? BTW, if we can support offs(FETCHARGS), $stack and $stackN are also available. ;) Yes, but we should check whether the given address is in an user stack or not. and these require CPU architecture dependent codes. Thank you, -- Masami HIRAMATSU Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: masami.hiramatsu...@hitachi.com Thanks for your answer. It is very help to me. ;) Hyeoncheol -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [QUESTION] Can uprobe_event support @ADDR, $retval, offs(FETCHARG)?
2012/9/26 Srikar Dronamraju sri...@linux.vnet.ibm.com: Perhaps, it is not so small things, but at least, we can try. In the userspace, memories(pages) can be paged out on swap or files. In that case, memory dereference function needs to track down the data on the disk and it causes I/O. This means we will see the visible performance degradation with tracing. And also, sometime a pointer value (address) is broken, in that case we have to ensure the address is actually valid before accessing it. Of cause, without tracking paged-out data, it is easy to support, because that is already done in kprobe event. I'm not sure how it is useful, because sometimes it will fail to access gather the data. However it is good for the first step, I think. Srikar, what would you think? I think we should do the best effort basis first. i.e support for tracking data thats not paged out. Most times the data that is requested tends to the hot data. We could look at supporting data that is paged out later. BTW, if we can support offs(FETCHARGS), $stack and $stackN are also available. ;) -- Thanks and Regards Srikar Dronamraju I asked this question. because I need Perf that supports to access user process's variables. and I am trying to add this feature. Thank you for your answer. Hyeoncheol -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] perf probe: print an enum type variable in enum variable-name format when showing accessible variables
When showing accessible variables, an enum type variable was printed in variable-name format. Change this format into enum variable-name. Cc: Masami Hiramatsu masami.hiramatsu...@hitachi.com Signed-off-by: Hyeoncheol Lee hyc@gmail.com --- tools/perf/util/dwarf-aux.c |2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c index ee51e9b..3e5f543 100644 --- a/tools/perf/util/dwarf-aux.c +++ b/tools/perf/util/dwarf-aux.c @@ -804,6 +804,8 @@ int die_get_typename(Dwarf_Die *vr_die, char *buf, int len) tmp = union ; else if (tag == DW_TAG_structure_type) tmp = struct ; + else if (tag == DW_TAG_enumeration_type) + tmp = enum ; /* Write a base name */ ret = snprintf(buf, len, %s%s, tmp, dwarf_diename(type)); return (ret = len) ? -E2BIG : ret; -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] perf probe: Allow of casting an array of char to string
Before casting a type of a variable to string, convert_variable_type() confirms that the type is a pointer or an array. if it is a pointer to char, it is casted to string. but in case of an array of char, it isn't Cc: Masami Hiramatsu Cc: Srikar Dronamraju Signed-off-by: Hyeoncheol Lee --- tools/perf/util/probe-finder.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index 1daf5c1..be03293 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c @@ -413,12 +413,12 @@ static int convert_variable_type(Dwarf_Die *vr_die, dwarf_diename(vr_die), dwarf_diename()); return -EINVAL; } + if (die_get_real_type(, ) == NULL) { + pr_warning("Failed to get a type" + " information.\n"); + return -ENOENT; + } if (ret == DW_TAG_pointer_type) { - if (die_get_real_type(, ) == NULL) { - pr_warning("Failed to get a type" - " information.\n"); - return -ENOENT; - } while (*ref_ptr) ref_ptr = &(*ref_ptr)->next; /* Add new reference with offset +0 */ -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[tip:perf/core] perf probe: Add union member access support
Commit-ID: 7b0295b3db20a89b3296673871858b9ab6b68404 Gitweb: http://git.kernel.org/tip/7b0295b3db20a89b3296673871858b9ab6b68404 Author: Hyeoncheol Lee AuthorDate: Wed, 12 Sep 2012 16:57:45 +0900 Committer: Arnaldo Carvalho de Melo CommitDate: Fri, 14 Sep 2012 15:48:08 -0300 perf probe: Add union member access support Union members can be accessed with '.' or '->' like data structure member access Signed-off-by: Hyunchul Lee Acked-by: Masami Hiramatsu Cc: Masami Hiramatsu Cc: Srikar Dronamraju Link: http://lkml.kernel.org/r/canfs6baeusbxpgq8suzwzerj2bws-nojg+fso138e1qk8bj...@mail.gmail.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/probe-finder.c | 24 1 files changed, 16 insertions(+), 8 deletions(-) diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index 526ba56..1daf5c1 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c @@ -525,8 +525,10 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname, return -ENOENT; } /* Verify it is a data structure */ - if (dwarf_tag() != DW_TAG_structure_type) { - pr_warning("%s is not a data structure.\n", varname); + tag = dwarf_tag(); + if (tag != DW_TAG_structure_type && tag != DW_TAG_union_type) { + pr_warning("%s is not a data structure nor an union.\n", + varname); return -EINVAL; } @@ -539,8 +541,9 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname, *ref_ptr = ref; } else { /* Verify it is a data structure */ - if (tag != DW_TAG_structure_type) { - pr_warning("%s is not a data structure.\n", varname); + if (tag != DW_TAG_structure_type && tag != DW_TAG_union_type) { + pr_warning("%s is not a data structure nor an union.\n", + varname); return -EINVAL; } if (field->name[0] == '[') { @@ -567,10 +570,15 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname, } /* Get the offset of the field */ - ret = die_get_data_member_location(die_mem, ); - if (ret < 0) { - pr_warning("Failed to get the offset of %s.\n", field->name); - return ret; + if (tag == DW_TAG_union_type) { + offs = 0; + } else { + ret = die_get_data_member_location(die_mem, ); + if (ret < 0) { + pr_warning("Failed to get the offset of %s.\n", + field->name); + return ret; + } } ref->offset += (long)offs; -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[tip:perf/core] perf probe: Add union member access support
Commit-ID: 7b0295b3db20a89b3296673871858b9ab6b68404 Gitweb: http://git.kernel.org/tip/7b0295b3db20a89b3296673871858b9ab6b68404 Author: Hyeoncheol Lee hyc@gmail.com AuthorDate: Wed, 12 Sep 2012 16:57:45 +0900 Committer: Arnaldo Carvalho de Melo a...@redhat.com CommitDate: Fri, 14 Sep 2012 15:48:08 -0300 perf probe: Add union member access support Union members can be accessed with '.' or '-' like data structure member access Signed-off-by: Hyunchul Lee hyc@gmail.com Acked-by: Masami Hiramatsu masami.hiramatsu...@hitachi.com Cc: Masami Hiramatsu masami.hiramatsu...@hitachi.com Cc: Srikar Dronamraju sri...@linux.vnet.ibm.com Link: http://lkml.kernel.org/r/canfs6baeusbxpgq8suzwzerj2bws-nojg+fso138e1qk8bj...@mail.gmail.com Signed-off-by: Arnaldo Carvalho de Melo a...@redhat.com --- tools/perf/util/probe-finder.c | 24 1 files changed, 16 insertions(+), 8 deletions(-) diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index 526ba56..1daf5c1 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c @@ -525,8 +525,10 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname, return -ENOENT; } /* Verify it is a data structure */ - if (dwarf_tag(type) != DW_TAG_structure_type) { - pr_warning(%s is not a data structure.\n, varname); + tag = dwarf_tag(type); + if (tag != DW_TAG_structure_type tag != DW_TAG_union_type) { + pr_warning(%s is not a data structure nor an union.\n, + varname); return -EINVAL; } @@ -539,8 +541,9 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname, *ref_ptr = ref; } else { /* Verify it is a data structure */ - if (tag != DW_TAG_structure_type) { - pr_warning(%s is not a data structure.\n, varname); + if (tag != DW_TAG_structure_type tag != DW_TAG_union_type) { + pr_warning(%s is not a data structure nor an union.\n, + varname); return -EINVAL; } if (field-name[0] == '[') { @@ -567,10 +570,15 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname, } /* Get the offset of the field */ - ret = die_get_data_member_location(die_mem, offs); - if (ret 0) { - pr_warning(Failed to get the offset of %s.\n, field-name); - return ret; + if (tag == DW_TAG_union_type) { + offs = 0; + } else { + ret = die_get_data_member_location(die_mem, offs); + if (ret 0) { + pr_warning(Failed to get the offset of %s.\n, + field-name); + return ret; + } } ref-offset += (long)offs; -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] perf probe: Allow of casting an array of char to string
Before casting a type of a variable to string, convert_variable_type() confirms that the type is a pointer or an array. if it is a pointer to char, it is casted to string. but in case of an array of char, it isn't Cc: Masami Hiramatsu masami.hiramatsu...@hitachi.com Cc: Srikar Dronamraju sri...@linux.vnet.ibm.com Signed-off-by: Hyeoncheol Lee hyc@gmail.com --- tools/perf/util/probe-finder.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index 1daf5c1..be03293 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c @@ -413,12 +413,12 @@ static int convert_variable_type(Dwarf_Die *vr_die, dwarf_diename(vr_die), dwarf_diename(type)); return -EINVAL; } + if (die_get_real_type(type, type) == NULL) { + pr_warning(Failed to get a type + information.\n); + return -ENOENT; + } if (ret == DW_TAG_pointer_type) { - if (die_get_real_type(type, type) == NULL) { - pr_warning(Failed to get a type - information.\n); - return -ENOENT; - } while (*ref_ptr) ref_ptr = (*ref_ptr)-next; /* Add new reference with offset +0 */ -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH -tip/perf/core] perf probe: Add union member access support
Union members can be accessed with '.' or '->' like data structure member access Cc: Masami Hiramatsu Cc: Srikar Dronamraju Signed-off-by: Hyunchul Lee --- tools/perf/util/probe-finder.c | 24 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index 94a00de..cc2b856 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c @@ -525,8 +525,10 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname, return -ENOENT; } /* Verify it is a data structure */ - if (dwarf_tag() != DW_TAG_structure_type) { - pr_warning("%s is not a data structure.\n", varname); + tag = dwarf_tag(); + if (tag != DW_TAG_structure_type && tag != DW_TAG_union_type) { + pr_warning("%s is not a data structure nor an union.\n", + varname); return -EINVAL; } @@ -539,8 +541,9 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname, *ref_ptr = ref; } else { /* Verify it is a data structure */ - if (tag != DW_TAG_structure_type) { - pr_warning("%s is not a data structure.\n", varname); + if (tag != DW_TAG_structure_type && tag != DW_TAG_union_type) { + pr_warning("%s is not a data structure nor an union.\n", + varname); return -EINVAL; } if (field->name[0] == '[') { @@ -567,10 +570,15 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname, } /* Get the offset of the field */ - ret = die_get_data_member_location(die_mem, ); - if (ret < 0) { - pr_warning("Failed to get the offset of %s.\n", field->name); - return ret; + if (tag == DW_TAG_union_type) { + offs = 0; + } else { + ret = die_get_data_member_location(die_mem, ); + if (ret < 0) { + pr_warning("Failed to get the offset of %s.\n", + field->name); + return ret; + } } ref->offset += (long)offs; -- 1.7.10 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH -tip/perf/core] perf probe: Add union member access support
Union members can be accessed with '.' or '-' like data structure member access Cc: Masami Hiramatsu masami.hiramatsu...@hitachi.com Cc: Srikar Dronamraju sri...@linux.vnet.ibm.com Signed-off-by: Hyunchul Lee hyc@gmail.com --- tools/perf/util/probe-finder.c | 24 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index 94a00de..cc2b856 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c @@ -525,8 +525,10 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname, return -ENOENT; } /* Verify it is a data structure */ - if (dwarf_tag(type) != DW_TAG_structure_type) { - pr_warning(%s is not a data structure.\n, varname); + tag = dwarf_tag(type); + if (tag != DW_TAG_structure_type tag != DW_TAG_union_type) { + pr_warning(%s is not a data structure nor an union.\n, + varname); return -EINVAL; } @@ -539,8 +541,9 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname, *ref_ptr = ref; } else { /* Verify it is a data structure */ - if (tag != DW_TAG_structure_type) { - pr_warning(%s is not a data structure.\n, varname); + if (tag != DW_TAG_structure_type tag != DW_TAG_union_type) { + pr_warning(%s is not a data structure nor an union.\n, + varname); return -EINVAL; } if (field-name[0] == '[') { @@ -567,10 +570,15 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname, } /* Get the offset of the field */ - ret = die_get_data_member_location(die_mem, offs); - if (ret 0) { - pr_warning(Failed to get the offset of %s.\n, field-name); - return ret; + if (tag == DW_TAG_union_type) { + offs = 0; + } else { + ret = die_get_data_member_location(die_mem, offs); + if (ret 0) { + pr_warning(Failed to get the offset of %s.\n, + field-name); + return ret; + } } ref-offset += (long)offs; -- 1.7.10 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH -tip/perf/core ] perf probe: Allow of casting an array of char to string
Before casting a type of a variable to string, convert_variable_type() confirms that the type is a pointer or an array. then if it is a pointer to char, it is casted to string. but in case of an array of char, it isn't Cc: Masami Hiramatsu Cc: Srikar Dronamraju Signed-off-by: H.C. Lee --- tools/perf/util/probe-finder.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index d448984..94a00de 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c @@ -413,12 +413,12 @@ static int convert_variable_type(Dwarf_Die *vr_die, dwarf_diename(vr_die), dwarf_diename()); return -EINVAL; } + if (die_get_real_type(, ) == NULL) { + pr_warning("Failed to get a type" + " information.\n"); + return -ENOENT; + } if (ret == DW_TAG_pointer_type) { - if (die_get_real_type(, ) == NULL) { - pr_warning("Failed to get a type" - " information.\n"); - return -ENOENT; - } while (*ref_ptr) ref_ptr = &(*ref_ptr)->next; /* Add new reference with offset +0 */ -- 1.7.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH -tip/perf/core ] perf probe: Allow of casting an array of char to string
Before casting a type of a variable to string, convert_variable_type() confirms that the type is a pointer or an array. then if it is a pointer to char, it is casted to string. but in case of an array of char, it isn't Cc: Masami Hiramatsu masami.hiramatsu...@hitachi.com Cc: Srikar Dronamraju sri...@linux.vnet.ibm.com Signed-off-by: H.C. Lee hyc@gmail.com --- tools/perf/util/probe-finder.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index d448984..94a00de 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c @@ -413,12 +413,12 @@ static int convert_variable_type(Dwarf_Die *vr_die, dwarf_diename(vr_die), dwarf_diename(type)); return -EINVAL; } + if (die_get_real_type(type, type) == NULL) { + pr_warning(Failed to get a type + information.\n); + return -ENOENT; + } if (ret == DW_TAG_pointer_type) { - if (die_get_real_type(type, type) == NULL) { - pr_warning(Failed to get a type - information.\n); - return -ENOENT; - } while (*ref_ptr) ref_ptr = (*ref_ptr)-next; /* Add new reference with offset +0 */ -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/