[tip:perf/core] perf data: Fix signedness of value

2015-05-05 Thread tip-bot for Wang Nan
Commit-ID:  d4ae42139289cbe38d5b84fa1558161d330d6e54
Gitweb: http://git.kernel.org/tip/d4ae42139289cbe38d5b84fa1558161d330d6e54
Author: Wang Nan 
AuthorDate: Sat, 18 Apr 2015 17:50:20 +0200
Committer:  Arnaldo Carvalho de Melo 
CommitDate: Wed, 29 Apr 2015 10:37:49 -0300

perf data: Fix signedness of value

When converting int values, perf first extractes it to a ulonglong, then
feeds it to babeltrace as a signed value.

For negative 32 bit values (for example, return values of failed
syscalls), the extracted data should be something like 0xfffe (-2).
It becomes a large int64 value.

Babeltrace denies to insert it with bt_ctf_field_signed_integer_set_value()
because it is larger than 0x7fff, the largest positive value a
 32 bit int can be.

This patch introduces adjust_signedness(), which fills high bits of
ulonglong with 1 if the value is negative.

Signed-off-by: Wang Nan 
Cc: David Ahern 
Cc: Frederic Weisbecker 
Cc: He Kuang 
Cc: Jeremie Galarneau 
Cc: Namhyung Kim 
Cc: Paul Mackerras 
Cc: Peter Zijlstra 
Cc: Sebastian Andrzej Siewior 
Cc: Tom Zanussi 
Link: http://lkml.kernel.org/r/1429372220-6406-8-git-send-email-jo...@kernel.org
Signed-off-by: Jiri Olsa 
[ s/signess/signedness/g ]
Signed-off-by: Arnaldo Carvalho de Melo 
---
 tools/perf/util/data-convert-bt.c | 64 +++
 1 file changed, 52 insertions(+), 12 deletions(-)

diff --git a/tools/perf/util/data-convert-bt.c 
b/tools/perf/util/data-convert-bt.c
index 8eda4ed..5bfc119 100644
--- a/tools/perf/util/data-convert-bt.c
+++ b/tools/perf/util/data-convert-bt.c
@@ -166,6 +166,43 @@ get_tracepoint_field_type(struct ctf_writer *cw, struct 
format_field *field)
return cw->data.u32;
 }
 
+static unsigned long long adjust_signedness(unsigned long long value_int, int 
size)
+{
+   unsigned long long value_mask;
+
+   /*
+* value_mask = (1 << (size * 8 - 1)) - 1.
+* Directly set value_mask for code readers.
+*/
+   switch (size) {
+   case 1:
+   value_mask = 0x7fULL;
+   break;
+   case 2:
+   value_mask = 0x7fffULL;
+   break;
+   case 4:
+   value_mask = 0x7fffULL;
+   break;
+   case 8:
+   /*
+* For 64 bit value, return it self. There is no need
+* to fill high bit.
+*/
+   /* Fall through */
+   default:
+   /* BUG! */
+   return value_int;
+   }
+
+   /* If it is a positive value, don't adjust. */
+   if ((value_int & (~0ULL - value_mask)) == 0)
+   return value_int;
+
+   /* Fill upper part of value_int with 1 to make it a negative long long. 
*/
+   return (value_int & value_mask) | ~value_mask;
+}
+
 static int add_tracepoint_field_value(struct ctf_writer *cw,
  struct bt_ctf_event_class *event_class,
  struct bt_ctf_event *event,
@@ -177,7 +214,6 @@ static int add_tracepoint_field_value(struct ctf_writer *cw,
struct bt_ctf_field *field;
const char *name = fmtf->name;
void *data = sample->raw_data;
-   unsigned long long value_int;
unsigned long flags = fmtf->flags;
unsigned int n_items;
unsigned int i;
@@ -222,11 +258,6 @@ static int add_tracepoint_field_value(struct ctf_writer 
*cw,
type = get_tracepoint_field_type(cw, fmtf);
 
for (i = 0; i < n_items; i++) {
-   if (!(flags & FIELD_IS_STRING))
-   value_int = pevent_read_number(
-   fmtf->event->pevent,
-   data + offset + i * len, len);
-
if (flags & FIELD_IS_ARRAY)
field = bt_ctf_field_array_get_field(array_field, i);
else
@@ -240,12 +271,21 @@ static int add_tracepoint_field_value(struct ctf_writer 
*cw,
if (flags & FIELD_IS_STRING)
ret = bt_ctf_field_string_set_value(field,
data + offset + i * len);
-   else if (!(flags & FIELD_IS_SIGNED))
-   ret = bt_ctf_field_unsigned_integer_set_value(
-   field, value_int);
-   else
-   ret = bt_ctf_field_signed_integer_set_value(
-   field, value_int);
+   else {
+   unsigned long long value_int;
+
+   value_int = pevent_read_number(
+   fmtf->event->pevent,
+   data + offset + i * len, len);
+
+   if (!(flags & FIELD_IS_SIGNED))
+   ret = bt_ctf_field_unsigned_integer_set_value(
+   field, value_int);
+ 

[tip:perf/core] perf data: Fix signedness of value

2015-05-05 Thread tip-bot for Wang Nan
Commit-ID:  d4ae42139289cbe38d5b84fa1558161d330d6e54
Gitweb: http://git.kernel.org/tip/d4ae42139289cbe38d5b84fa1558161d330d6e54
Author: Wang Nan wangn...@huawei.com
AuthorDate: Sat, 18 Apr 2015 17:50:20 +0200
Committer:  Arnaldo Carvalho de Melo a...@redhat.com
CommitDate: Wed, 29 Apr 2015 10:37:49 -0300

perf data: Fix signedness of value

When converting int values, perf first extractes it to a ulonglong, then
feeds it to babeltrace as a signed value.

For negative 32 bit values (for example, return values of failed
syscalls), the extracted data should be something like 0xfffe (-2).
It becomes a large int64 value.

Babeltrace denies to insert it with bt_ctf_field_signed_integer_set_value()
because it is larger than 0x7fff, the largest positive value a
 32 bit int can be.

This patch introduces adjust_signedness(), which fills high bits of
ulonglong with 1 if the value is negative.

Signed-off-by: Wang Nan wangn...@huawei.com
Cc: David Ahern dsah...@gmail.com
Cc: Frederic Weisbecker fweis...@gmail.com
Cc: He Kuang heku...@huawei.com
Cc: Jeremie Galarneau jga...@efficios.com
Cc: Namhyung Kim namhy...@kernel.org
Cc: Paul Mackerras pau...@samba.org
Cc: Peter Zijlstra a.p.zijls...@chello.nl
Cc: Sebastian Andrzej Siewior bige...@linutronix.de
Cc: Tom Zanussi tzanu...@gmail.com
Link: http://lkml.kernel.org/r/1429372220-6406-8-git-send-email-jo...@kernel.org
Signed-off-by: Jiri Olsa jo...@kernel.org
[ s/signess/signedness/g ]
Signed-off-by: Arnaldo Carvalho de Melo a...@redhat.com
---
 tools/perf/util/data-convert-bt.c | 64 +++
 1 file changed, 52 insertions(+), 12 deletions(-)

diff --git a/tools/perf/util/data-convert-bt.c 
b/tools/perf/util/data-convert-bt.c
index 8eda4ed..5bfc119 100644
--- a/tools/perf/util/data-convert-bt.c
+++ b/tools/perf/util/data-convert-bt.c
@@ -166,6 +166,43 @@ get_tracepoint_field_type(struct ctf_writer *cw, struct 
format_field *field)
return cw-data.u32;
 }
 
+static unsigned long long adjust_signedness(unsigned long long value_int, int 
size)
+{
+   unsigned long long value_mask;
+
+   /*
+* value_mask = (1  (size * 8 - 1)) - 1.
+* Directly set value_mask for code readers.
+*/
+   switch (size) {
+   case 1:
+   value_mask = 0x7fULL;
+   break;
+   case 2:
+   value_mask = 0x7fffULL;
+   break;
+   case 4:
+   value_mask = 0x7fffULL;
+   break;
+   case 8:
+   /*
+* For 64 bit value, return it self. There is no need
+* to fill high bit.
+*/
+   /* Fall through */
+   default:
+   /* BUG! */
+   return value_int;
+   }
+
+   /* If it is a positive value, don't adjust. */
+   if ((value_int  (~0ULL - value_mask)) == 0)
+   return value_int;
+
+   /* Fill upper part of value_int with 1 to make it a negative long long. 
*/
+   return (value_int  value_mask) | ~value_mask;
+}
+
 static int add_tracepoint_field_value(struct ctf_writer *cw,
  struct bt_ctf_event_class *event_class,
  struct bt_ctf_event *event,
@@ -177,7 +214,6 @@ static int add_tracepoint_field_value(struct ctf_writer *cw,
struct bt_ctf_field *field;
const char *name = fmtf-name;
void *data = sample-raw_data;
-   unsigned long long value_int;
unsigned long flags = fmtf-flags;
unsigned int n_items;
unsigned int i;
@@ -222,11 +258,6 @@ static int add_tracepoint_field_value(struct ctf_writer 
*cw,
type = get_tracepoint_field_type(cw, fmtf);
 
for (i = 0; i  n_items; i++) {
-   if (!(flags  FIELD_IS_STRING))
-   value_int = pevent_read_number(
-   fmtf-event-pevent,
-   data + offset + i * len, len);
-
if (flags  FIELD_IS_ARRAY)
field = bt_ctf_field_array_get_field(array_field, i);
else
@@ -240,12 +271,21 @@ static int add_tracepoint_field_value(struct ctf_writer 
*cw,
if (flags  FIELD_IS_STRING)
ret = bt_ctf_field_string_set_value(field,
data + offset + i * len);
-   else if (!(flags  FIELD_IS_SIGNED))
-   ret = bt_ctf_field_unsigned_integer_set_value(
-   field, value_int);
-   else
-   ret = bt_ctf_field_signed_integer_set_value(
-   field, value_int);
+   else {
+   unsigned long long value_int;
+
+   value_int = pevent_read_number(
+   fmtf-event-pevent,
+   data +