Re: [PATCH] ubi: Remove ubi_io_is_bad call from scan_peb

2017-09-26 Thread Hyeoncheol Lee
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

2017-09-26 Thread Hyeoncheol Lee
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

2014-01-02 Thread Hyeoncheol Lee
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

2014-01-02 Thread Hyeoncheol Lee
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

2013-02-19 Thread Hyeoncheol Lee
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

2013-02-19 Thread Hyeoncheol Lee
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

2013-01-25 Thread tip-bot for Hyeoncheol Lee
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

2013-01-25 Thread tip-bot for Hyeoncheol Lee
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

2012-11-13 Thread Hyeoncheol Lee
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

2012-11-13 Thread Hyeoncheol Lee
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

2012-10-24 Thread Hyeoncheol Lee
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

2012-10-24 Thread Hyeoncheol Lee
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

2012-10-24 Thread Hyeoncheol Lee
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

2012-10-24 Thread Hyeoncheol Lee
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

2012-10-17 Thread Hyeoncheol Lee
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-17 Thread Hyeoncheol Lee
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

2012-10-17 Thread Hyeoncheol Lee
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

2012-10-17 Thread Hyeoncheol Lee
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-17 Thread Hyeoncheol Lee
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

2012-10-17 Thread Hyeoncheol Lee
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

2012-10-16 Thread Hyeoncheol Lee
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

2012-10-16 Thread Hyeoncheol Lee
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

2012-10-16 Thread Hyeoncheol Lee
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

2012-10-16 Thread Hyeoncheol Lee
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

2012-10-16 Thread Hyeoncheol Lee
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

2012-10-16 Thread Hyeoncheol Lee
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

2012-10-15 Thread Hyeoncheol Lee
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

2012-10-15 Thread Hyeoncheol Lee
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

2012-09-26 Thread Hyeoncheol Lee
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-09-26 Thread Hyeoncheol Lee
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)?

2012-09-26 Thread Hyeoncheol Lee
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)?

2012-09-26 Thread Hyeoncheol Lee
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-09-26 Thread Hyeoncheol Lee
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

2012-09-26 Thread Hyeoncheol Lee
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

2012-09-19 Thread Hyeoncheol Lee
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

2012-09-19 Thread tip-bot for Hyeoncheol Lee
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

2012-09-19 Thread tip-bot for Hyeoncheol Lee
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

2012-09-19 Thread Hyeoncheol Lee
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

2012-09-12 Thread Hyeoncheol Lee
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

2012-09-12 Thread Hyeoncheol Lee
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

2012-09-11 Thread Hyeoncheol Lee
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

2012-09-11 Thread Hyeoncheol Lee
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/