perf record: why we used type casting of (uint64_t *) instead of int
Hey Stephane,
Just wondering why we used the type casting of (uint64_t *) on a data which is defined as "int" in the structure of "perf_record_opts".
struct perf_record_opts {
struct perf_target target;
bool call_graph;
bool group;
bool inherit_stat;
bool no_delay;
bool no_inherit;
bool no_samples;
bool pipe_output;
bool raw_samples;
bool sample_address;
bool sample_time;
bool sample_id_all_missing;
bool exclude_guest_missing;
bool period;
unsigned int freq;
unsigned int mmap_pages;
unsigned int user_freq;
int branch_stack;
u64 default_interval;
u64 user_interval;
};static intparse_branch_stack(const struct option *opt, const char *str, int unset) {
#define ONLY_PLM \
(PERF_SAMPLE_BRANCH_USER |\
PERF_SAMPLE_BRANCH_KERNEL |\
PERF_SAMPLE_BRANCH_HV)
uint64_t *mode = (uint64_t *)opt->value;--
Regards
Anshuman Khandual
This code is breaking in powerpc systems.
(1) 'opt->value' gets updated inside the function parse_branch_stack via dereferencing a (uint64_t *) type casted pointer.
(2) But the value is not accessible when we again use opt->value via dereferencing a (int *) type casted pointer.
(3) As a result record.opts.branch_stack remains 0 and unchanged by parse_branch_stack
This is caused by bit representation of 'uint64_t' and 'int' in powerpc systems. Bytes update for the data (when accessed trough (uint64_t *) casting) is no longer available to the data when accessed through (int *) type casting. Verified this from bit representation of the data (accessed through both type casting methods).
However this problem does not seem to be present on an Intel box. Integer dereferencing of the opt->value still gives the value which was updated as (uint64_t).
All this problem would not have been there if we had used (int *) instead of (uint64_t *) in the first place inside parse_branch_stack function.
Quoted 47 lines · Anshuman Khandual
Hey Stephane,
Just wondering why we used the type casting of (
uint64_t*) on a data which is defined as "int" in the structure of "perf_record_opts".struct perf_record_opts { struct perf_target target; bool call_graph; bool group; bool inherit_stat; bool no_delay; bool no_inherit; bool no_samples; bool pipe_output; bool raw_samples; bool sample_address; bool sample_time; bool sample_id_all_missing; bool exclude_guest_missing; bool period; unsigned int freq; unsigned int mmap_pages; unsigned int user_freq; int branch_stack; u64 default_interval; u64 user_interval; };static int
parse_branch_stack(const struct option *opt, const char *str, int unset){#define ONLY_PLM \ (PERF_SAMPLE_BRANCH_USER |\ PERF_SAMPLE_BRANCH_KERNEL |\ PERF_SAMPLE_BRANCH_HV) uint64_t *mode = (uint64_t *)opt->value;--
Regards
Anshuman Khandual--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Quoted 15 lines · Anshuman Khandual
This code is breaking in powerpc systems.
(1) '
opt->value' gets updated inside the functionparse_branch_stackvia dereferencing a (uint64_t*) type casted pointer.(2) But the value is not accessible when we again use
opt->valuevia dereferencing a (int *) type casted pointer.(3) As a result record.opts.branch_stack remains 0 and unchanged by
parse_branch_stackThis is caused by bit representation of '
uint64_t' and 'int' in powerpc systems. Bytes update for the data (when accessed trough (uint64_t*) casting) is no longer available to the data when accessed through (int *) type casting. Verified this from bit representation of the data (accessed through both type casting methods).
Quoted 6 lines
However this problem does not seem to be present on an Intel box. Integer dereferencing of the
opt->valuestill gives the value which was updated as (uint64_t).All this problem would not have been there if we had used (int *) instead of (
uint64_t*) in the first place insideparse_branch_stackfunction.
The bug is that in struct record_opts, branch_stack is declared int instead of u64.
I can post a patch to fix that. The value is eventually passed to struct perf_event_attr.branch_sample_type which is defined as u64.
I can post a patch to fix that.
Thanks for catching this.
Quoted 51 lines · Anshuman Khandual
Quoted 48 lines
Hey Stephane,
Just wondering why we used the type casting of (
uint64_t*) on a data which is defined as "int" in the structure of "perf_record_opts".struct
perf_record_opts{
structperf_targettarget;
boolcall_graph;
bool group;
boolinherit_stat;
boolno_delay;
boolno_inherit;
boolno_samples;
boolpipe_output;
boolraw_samples;
boolsample_address;
boolsample_time;
boolsample_id_all_missing;
boolexclude_guest_missing;
bool period;
unsigned int freq;
unsigned intmmap_pages;
unsigned intuser_freq;
int branch_stack;
u64 default_interval;
u64 user_interval;
};static int
parse_branch_stack(const struct option *opt, const char *str, int unset){
#defineONLY_PLM\
(PERF_SAMPLE_BRANCH_USER|\
PERF_SAMPLE_BRANCH_KERNEL |\
PERF_SAMPLE_BRANCH_HV)
uint64_t*mode = (uint64_t*)opt->value;
--
Regards
Anshuman Khandual--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] perf record: Fixing record option data type in parse_branch_stack
In reply to Anshuman KhandualHi,
It should be something like that instead:
tools/perf/perf.h +1 -1
@@ -228,7 +228,7 @@ struct perf_record_opts {unsigned int freq;unsigned int mmap_pages;unsigned int user_freq; -int branch_stack; +u64 branch_stack;u64 default_interval;u64 user_interval; };
Quoted 113 lines · Anshuman Khandual
perf record: Fixing record option data type in
parse_branch_stackCurrently
parse_branch_stackdoes not update record.opts.branch_stack value in powerpc architecture.opt->valueis declared as int in structperf_record_opts. But is worked on asuint64_tisnide the function. This breaks functionality in poweprc due to bit representation ofuint64_twhich is inaccessible as int.Signed-off-by Anshuman Khandual <[email protected]>---
tools/perf/builtin-record.c | 2 +-1 file changed, 1 insertion(+), 1 deletion(-)tools/perf/builtin-record.c +1
-2@@ -677,7 +677,7 @@ parse_branch_stack(const struct option *opt, const char *str, int unset) PERF_SAMPLE_BRANCH_KERNEL |\ PERF_SAMPLE_BRANCH_HV) - uint64_t *mode = (uint64_t *)opt->value; + int *mode = (int *)opt->value; const struct branch_mode *br; char *s, *os = NULL, *p; int ret = -1; --1.7.9.5
Quoted 78 lines · Anshuman Khandual
This code is breaking in powerpc systems.
(1) '
opt->value' gets updated inside the functionparse_branch_stackvia dereferencing a (uint64_t*) type casted pointer.(2) But the value is not accessible when we again use
opt->valuevia dereferencing a (int *) type casted pointer.(3) As a result record.opts.branch_stack remains 0 and unchanged by
parse_branch_stackThis is caused by bit representation of '
uint64_t' and 'int' in powerpc systems. Bytes update for the data (when accessed trough (uint64_t*) casting) is no longer available to the data when accessed through (int *) type casting. Verified this from bit representation of the data (accessed through both type casting methods).However this problem does not seem to be present on an Intel box. Integer dereferencing of the
opt->valuestill gives the value which was updated as (uint64_t).All this problem would not have been there if we had used (int *) instead of (
uint64_t*) in the first place insideparse_branch_stackfunction.Quoted 41 lines · Anshuman Khandual
Hey Stephane,
Just wondering why we used the type casting of (
uint64_t*) on a data which is defined as "int" in the structure of "perf_record_opts".struct
perf_record_opts{
structperf_targettarget;
boolcall_graph;
bool group;
boolinherit_stat;
boolno_delay;
boolno_inherit;
boolno_samples;
boolpipe_output;
boolraw_samples;
boolsample_address;
boolsample_time;
boolsample_id_all_missing;
boolexclude_guest_missing;
bool period;
unsigned int freq;
unsigned intmmap_pages;
unsigned intuser_freq;
int branch_stack;
u64 default_interval;
u64 user_interval;
};static int
parse_branch_stack(const struct option *opt, const char *str, int unset){
#defineONLY_PLM\
(PERF_SAMPLE_BRANCH_USER|\
PERF_SAMPLE_BRANCH_KERNEL |\
PERF_SAMPLE_BRANCH_HV)
uint64_t*mode = (uint64_t*)opt->value;
--
Regards
Anshuman KhandualQuoted 6 lines
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
PATCH 1/1 perf record: Fixing record option data type in parse_branch_stack
In reply to Anshuman Khandualperf record: Fixing record option data type in parse_branch_stack
Currently parse_branch_stack does not update record.opts.branch_stack value in powerpc architecture. opt->value is declared as int in struct perf_record_opts. But is worked on as uint64_t isnide the function. This breaks functionality in poweprc due to bit representation of uint64_t which is inaccessible as int.
--- tools/perf/builtin-record.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/builtin-record.c +1 -1
@@ -677,7 +677,7 @@ parse_branch_stack(const struct option *opt, const char *str, int unset) PERF_SAMPLE_BRANCH_KERNEL |\ PERF_SAMPLE_BRANCH_HV) -uint64_t *mode = (uint64_t *)opt->value; +int *mode = (int *)opt->value;const struct branch_mode *br;char *s, *os =NULL , *p;int ret =-1 ;
Signature · 1 line
1.7.9.5
Quoted 78 lines · Anshuman Khandual
This code is breaking in powerpc systems.
(1) '
opt->value' gets updated inside the functionparse_branch_stackvia dereferencing a (uint64_t*) type casted pointer.(2) But the value is not accessible when we again use
opt->valuevia dereferencing a (int *) type casted pointer.(3) As a result record.opts.branch_stack remains 0 and unchanged by
parse_branch_stackThis is caused by bit representation of '
uint64_t' and 'int' in powerpc systems. Bytes update for the data (when accessed trough (uint64_t*) casting) is no longer available to the data when accessed through (int *) type casting. Verified this from bit representation of the data (accessed through both type casting methods).However this problem does not seem to be present on an Intel box. Integer dereferencing of the
opt->valuestill gives the value which was updated as (uint64_t).All this problem would not have been there if we had used (int *) instead of (
uint64_t*) in the first place insideparse_branch_stackfunction.Quoted 41 lines · Anshuman Khandual
Hey Stephane,
Just wondering why we used the type casting of (
uint64_t*) on a data which is defined as "int" in the structure of "perf_record_opts".struct perf_record_opts { struct perf_target target; bool call_graph; bool group; bool inherit_stat; bool no_delay; bool no_inherit; bool no_samples; bool pipe_output; bool raw_samples; bool sample_address; bool sample_time; bool sample_id_all_missing; bool exclude_guest_missing; bool period; unsigned int freq; unsigned int mmap_pages; unsigned int user_freq; int branch_stack; u64 default_interval; u64 user_interval; };static int
parse_branch_stack(const struct option *opt, const char *str, int unset){#define ONLY_PLM \ (PERF_SAMPLE_BRANCH_USER |\ PERF_SAMPLE_BRANCH_KERNEL |\ PERF_SAMPLE_BRANCH_HV) uint64_t *mode = (uint64_t *)opt->value;--
Regards
Anshuman KhandualQuoted 6 lines
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] perf record: Fixing record option data type in parse_branch_stack
In reply to Stephane EranianQuoted 10 lines · Stephane Eranian
Hi,
It should be something like that instead:
tools/perf/perf.h +0
-0
tools/perf/perf.h struct perf_record_opts { · line 234
Quoted 8 lines
tools/perf/perf.h +1
-1@@ -228,7 +228,7 @@ struct perf_record_opts {unsigned int freq;unsigned int mmap_pages;unsigned int user_freq; -int branch_stack; +u64 branch_stack;u64 default_interval;u64 user_interval; };
Agreed. I just tried to fix the problem where it was more evident because of the data type mismatch.
Re: [PATCH] perf record: Fixing record option data type in parse_branch_stack
Em Fri, May 25, 2012 at 04:02:15PM +0530, Anshuman Khandual escreveu:
Quoted 17 lines · Stephane Eranian
Quoted 16 lines
Hi,
It should be something like that instead:
tools/perf/perf.h +1
-1@@ -228,7 +228,7 @@ struct perf_record_opts {unsigned int freq;unsigned int mmap_pages;unsigned int user_freq; -int branch_stack; +u64 branch_stack;u64 default_interval;
Quoted 8 lines
tools/perf/perf.h struct perf_record_opts { · line 234
Quoted 3 lines
tools/perf/perf.h +0
-0u64 user_interval; };Agreed. I just tried to fix the problem where it was more evident because of the data type mismatch.
Can you send an updated patch on a message just for that?
- Arnaldo