On 23/08/2024 10:57 am, Ganapatrao Kulkarni wrote:
>
> Hi James/Mike,
>
> On 23-08-2024 02:33 pm, James Clark wrote:
>>
>>
>> On 19/08/2024 11:59 am, Mike Leach wrote:
>>> Hi,
>>>
>>> A new branch of OpenCSD is available - ocsd-consistency-checks-1.5.4-rc1
>>>
>>> Testing I managed to do confirms the N atom on unconditional branches
>>> appear to work. I do not have a test case for the range
>>> discontinuities.
>>>
>>> The checks are enabled using operation flags on decoder creation. See
>>> the docs for details.
>>>
>>> Mike
>>>
>>
>> Hi Mike,
>>
>> I tested the new OpenCSD and I don't see the error anymore in the
>> disassembly script. I'm not sure if we need to go any further and add
>> the backwards check, it looks like just a later symptom and the checks
>> that you've added already prevent it.
>>
>> If you release a new version I can send the perf patch. I was going to
>> use these flags if that looks right to you? As far as I know that's the
>> set that can be always on and won't fail on bad hardware?
>>
>> I also assumed that ETM4_OPFLG_PKTDEC_AA64_OPCODE_CHK can be given even
>> for etmv3 and it's just a nop?
>>
>> diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
>> b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
>> index e917985bbbe6..90967fd807e6 100644
>> --- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
>> +++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
>> @@ -685,9 +685,14 @@ cs_etm_decoder__create_etm_decoder(struct
>> cs_etm_decoder_params *d_params,
>> return 0;
>>
>> if (d_params->operation == CS_ETM_OPERATION_DECODE) {
>> + int decode_flags = OCSD_CREATE_FLG_FULL_DECODER;
>> +#ifdef OCSD_OPFLG_N_UNCOND_DIR_BR_CHK
>> + decode_flags |= OCSD_OPFLG_N_UNCOND_DIR_BR_CHK |
>> OCSD_OPFLG_CHK_RANGE_CONTINUE |
>> + ETM4_OPFLG_PKTDEC_AA64_OPCODE_CHK;
>> +#endif
>> if (ocsd_dt_create_decoder(decoder->dcd_tree,
>> decoder->decoder_name,
>> - OCSD_CREATE_FLG_FULL_DECODER,
>> + decode_flags,
>> trace_config, &csid))
>> return -1;
>>
>
> I tried Mike's branch with above James's patch and still the segfault is
> happening to us.
>
Looks like the Perf bug is only on the timestamped decode path, you can
force timeless as a workaround. Timestamps aren't used by the
disassembly script anyway:
--itrace=Zb
Full command:
perf script -i ./kcore -s python:tools/perf/scripts/python/arm-cs-\
trace-disasm.py --itrace=Zb -- -k ./kcore/kcore_dir/kcore
You can also disable timestamps when recording then you don't need the
itrace option. This will save you a lot of data anyway.
But I'm still working on the proper fix.
On 8/29/2024 12:55 AM, Leo Yan wrote:
> On 8/29/2024 12:17 AM, Steve Clevenger wrote:
>>
>> Changes in V5:
>> - In symbol-elf.c, branch to exit_close label if open file.
>> - In trace_event_python.c, correct indentation. set_sym_in_dict
>> call parameter "map_pgoff" renamed as "addr_map_pgoff" to
>> match local naming.
>
> For the series:
>
> Reviewed-by: Leo Yan <leo.yan(a)arm.com>
>
> Hi Steve,
>
> Later when you respin a new version patches, it is better to amend the review
> and ACK tags you have received. (Just remind, b4 is your friend for helping do
> these things).
>
> Thanks,
> Leo
Got it. Thanks, Leo. By the way, I noticed when I rebased to
perf-tools-next the kernel version was 6.11-rc3. Is there any chance
this patch gets into 6.11?
Steve
OpenCSD version 1.5.4 is now released.
This update contains a number of optional consistency checks that the
client can enable in the library to detect incorrect memory images or
corrupt trace being supplied to the decoder by the client.
Mike
--
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK
On 07/08/2024 5:48 pm, Leo Yan wrote:
> Hi all,
>
> On 8/7/2024 3:53 PM, James Clark wrote:
>
> A minor suggestion: if the discussion is too long, please delete the
> irrelevant message ;)
>
> [...]
>
>>> --- a/tools/perf/scripts/python/arm-cs-trace-disasm.py
>>> +++ b/tools/perf/scripts/python/arm-cs-trace-disasm.py
>>> @@ -257,6 +257,11 @@ def process_event(param_dict):
>>> print("Stop address 0x%x is out of range [ 0x%x .. 0x%x
>>> ] for dso %s" % (stop_addr, int(dso_start), int(dso_end), dso))
>>> return
>>>
>>> + if (stop_addr < start_addr):
>>> + if (options.verbose == True):
>>> + print("Packet Dropped, Discontinuity detected
>>> [stop_add:0x%x start_addr:0x%x ] for dso %s" % (stop_addr, start_addr,
>>> dso))
>>> + return
>>> +
>>
>> I suppose my only concern with this is that it hides real errors and
>> Perf shouldn't be outputting samples that go backwards. Considering that
>> fixing this in OpenCSD and Perf has a much wider benefit I think that
>> should be the ultimate goal. I'm putting this on my todo list for now
>> (including Steve's merging idea).
>
> In the perf's util/cs-etm.c file, it handles DISCONTINUITY with:
>
> case CS_ETM_DISCONTINUITY:
> /*
> * The trace is discontinuous, if the previous packet is
> * instruction packet, set flag PERF_IP_FLAG_TRACE_END
> * for previous packet.
> */
> if (prev_packet->sample_type == CS_ETM_RANGE)
> prev_packet->flags |= PERF_IP_FLAG_BRANCH |
> PERF_IP_FLAG_TRACE_END;
>
> I am wandering if OpenCSD has passed the correct info so Perf decoder can
> detect the discontinuity. If yes, then the flag 'PERF_IP_FLAG_TRACE_END' will
> be set (it is a general flag in branch sample), then we can consider use it in
> the python script to handle discontinuous data.
No OpenCSD isn't passing the correct info here. Higher up in the thread
I suggested an OpenCSD patch that makes it detect the error earlier and
fixes the issue. It also needs to output a discontinuity when the
address goes backwards. So two fixes and then the script works without
modifications.
>
>>
>> But in the mean time what about having a force option?
>>
>>> + if (stop_addr < start_addr):
>>> + if (options.verbose == True or not options.force):
>>> + print("Packet Dropped, Discontinuity detected
>>> [stop_add:0x%x start_addr:0x%x ] for dso %s" % (stop_addr, start_addr,
>>> dso))
>>> + if (not options.force):
>>> + return
>
> If the stop address is less than the start address, it must be something
> wrong. In this case, we can report a warning for discontinuity and directly
> return (also need to save the `addr` into global variable for next parsing).
>
> I prefer to not add force option for this case - eventually, this will consume
> much time for reporting this kind of failure and need to root causing it. A
> better way is we just print out the reasoning in the log and continue to dump.
But in this case we've identified all the known issues that would cause
the script to fail and we can fix them in Perf and OpenCSD. There may
not even be any more issues that will cause the script to fail in the
future so there's no point in softening the error IMO. That will only
hide future issues (of which there may be none) and make root causing
harder when it hits some other tool.
Changes in V5:
- In symbol-elf.c, branch to exit_close label if open file.
- In trace_event_python.c, correct indentation. set_sym_in_dict
call parameter "map_pgoff" renamed as "addr_map_pgoff" to
match local naming.
Changes in V4:
- In trace-event-python.c, fixed perf-tools-next merge problem.
Changes in V3:
- Rebased to linux-perf-tools branch.
- Squash symbol-elf.c and symbol.h into same commit.
- In map.c, merge dso__is_pie() call into existing if statement.
- In arm-cs-trace-disasm.py, remove debug artifacts.
Changes in V2:
- In dso__is_pie() (symbol-elf.c), Decrease indentation, add null pointer
checks per Leo Yan review.
- Updated mailing list distribution
Steve Clevenger (4):
Add dso__is_pie call to identify ELF PIE
Force MAPPING_TYPE__IDENTIY for PIE
Add map pgoff to python dictionary based on MAPPING_TYPE
Adjust objdump start/end range per map pgoff parameter
.../scripts/python/arm-cs-trace-disasm.py | 9 ++-
tools/perf/util/map.c | 4 +-
.../scripting-engines/trace-event-python.c | 13 +++-
tools/perf/util/symbol-elf.c | 61 +++++++++++++++++++
tools/perf/util/symbol.h | 1 +
5 files changed, 80 insertions(+), 8 deletions(-)
--
2.25.1
On 27/08/2024 5:44 pm, Leo Yan wrote:
> This commit dumps metadata with version 2. It uses two string arrays
> metadata_hdr_fmts and metadata_per_cpu_fmts as string formats for the
> header and per CPU data respectively, and the arm_spe_print_info()
> function is enhanced to support dumping metadata with the version 2
> format.
>
> After:
>
> 0 0 0x4a8 [0x170]: PERF_RECORD_AUXTRACE_INFO type: 4
> PMU Type :13
> Version :2
> Num of CPUs :8
> CPU # :0
> MIDR :0x410fd801
> Bound PMU Type :-1
> Min Interval :0
> Load Data Source :0
> CPU # :1
> MIDR :0x410fd801
> Bound PMU Type :-1
> Min Interval :0
> Load Data Source :0
> CPU # :2
> MIDR :0x410fd870
> Bound PMU Type :13
> Min Interval :1024
> Load Data Source :1
> CPU # :3
> MIDR :0x410fd870
> Bound PMU Type :13
> Min Interval :1024
> Load Data Source :1
> CPU # :4
> MIDR :0x410fd870
> Bound PMU Type :13
> Min Interval :1024
> Load Data Source :1
> CPU # :5
> MIDR :0x410fd870
> Bound PMU Type :13
> Min Interval :1024
> Load Data Source :1
> CPU # :6
> MIDR :0x410fd850
> Bound PMU Type :14
> Min Interval :1024
> Load Data Source :1
> CPU # :7
> MIDR :0x410fd850
> Bound PMU Type :14
> Min Interval :1024
> Load Data Source :1
>
> Signed-off-by: Leo Yan <leo.yan(a)arm.com>
> ---
> tools/perf/util/arm-spe.c | 43 ++++++++++++++++++++++++++++++++++-----
> 1 file changed, 38 insertions(+), 5 deletions(-)
>
> diff --git a/tools/perf/util/arm-spe.c b/tools/perf/util/arm-spe.c
> index 87cf06db765b..be34d4c4306a 100644
> --- a/tools/perf/util/arm-spe.c
> +++ b/tools/perf/util/arm-spe.c
> @@ -1067,16 +1067,49 @@ static bool arm_spe_evsel_is_auxtrace(struct perf_session *session __maybe_unuse
> return strstarts(evsel->name, ARM_SPE_PMU_NAME);
> }
>
> -static const char * const arm_spe_info_fmts[] = {
> - [ARM_SPE_PMU_TYPE] = " PMU Type %"PRId64"\n",
> +static const char * const metadata_hdr_fmts[] = {
> + [ARM_SPE_PMU_TYPE] = " PMU Type :%"PRId64"\n",
> + [ARM_SPE_HEADER_VERSION] = " Version :%"PRId64"\n",
> + [ARM_SPE_CPU_NUM] = " Num of CPUs :%"PRId64"\n",
> };
>
> -static void arm_spe_print_info(__u64 *arr)
> +static const char * const metadata_per_cpu_fmts[] = {
> + [ARM_SPE_CPU] = " CPU # :%"PRId64"\n",
> + [ARM_SPE_CPU_MIDR] = " MIDR :0x%"PRIx64"\n",
> + [ARM_SPE_CPU_PMU_TYPE] = " Bound PMU Type :%"PRId64"\n",
> + [ARM_SPE_CAP_MIN_IVAL] = " Min Interval :%"PRId64"\n",
> + [ARM_SPE_CAP_LDS] = " Load Data Source :%"PRId64"\n",
> +};
> +
> +static void arm_spe_print_info(struct arm_spe *spe, __u64 *arr)
> {
> + unsigned int i, cpu, header_size, cpu_num, per_cpu_size;
> +
> if (!dump_trace)
> return;
>
> - fprintf(stdout, arm_spe_info_fmts[ARM_SPE_PMU_TYPE], arr[ARM_SPE_PMU_TYPE]);
> + if (spe->metadata_ver == 1) {
> + cpu_num = 0;
> + header_size = ARM_SPE_AUXTRACE_V1_PRIV_MAX;
> + per_cpu_size = 0;
> + } else if (spe->metadata_ver == 2) {
Assuming future version updates are backwards compatible and only add
new info this should be spe->metadata_ver >= 2, otherwise version bumps
end up causing errors when files get passed around.
I know there are arguments about what should and shouldn't be supported
when opening new files on old perfs, but in this case it's easy to only
add new info to the aux header and leave the old stuff intact.
> + cpu_num = arr[ARM_SPE_CPU_NUM];
> + header_size = ARM_SPE_AUXTRACE_V2_PRIV_MAX;
> + per_cpu_size = ARM_SPE_AUXTRACE_V2_PRIV_PER_CPU_MAX;
I think for coresight we also save the size of each per-cpu block rather
than use a constant, that way new items can be appended without breaking
readers.
That kind of leads to another point that this mechanism is mostly
duplicated from coresight. It saves a main header version, then per-cpu
groups of variable size with named elements. I'm not saying we should
definitely try to share the code, but it's worth keeping in mind.
> + } else {
> + pr_err("Cannot support metadata ver: %ld\n", spe->metadata_ver);
> + return;
> + }
> +
> + for (i = 0; i < header_size; i++)
> + fprintf(stdout, metadata_hdr_fmts[i], arr[i]);
> +
> + arr += header_size;
> + for (cpu = 0; cpu < cpu_num; cpu++) {
> + for (i = 0; i < per_cpu_size; i++)
> + fprintf(stdout, metadata_per_cpu_fmts[i], arr[i]);
> + arr += per_cpu_size;
> + }
> }
>
> static void arm_spe_set_event_name(struct evlist *evlist, u64 id,
> @@ -1383,7 +1416,7 @@ int arm_spe_process_auxtrace_info(union perf_event *event,
> spe->auxtrace.evsel_is_auxtrace = arm_spe_evsel_is_auxtrace;
> session->auxtrace = &spe->auxtrace;
>
> - arm_spe_print_info(&auxtrace_info->priv[0]);
> + arm_spe_print_info(spe, &auxtrace_info->priv[0]);
>
> if (dump_trace)
> return 0;
Changes in V4:
- In trace-event-python.c, fixed perf-tools-next merge problem.
Changes in V3:
- Rebased to linux-perf-tools branch.
- Squash symbol-elf.c and symbol.h into same commit.
- In map.c, merge dso__is_pie() call into existing if statement.
- In arm-cs-trace-disasm.py, remove debug artifacts.
Changes in V2:
- In dso__is_pie() (symbol-elf.c), Decrease indentation, add null pointer
checks per Leo Yan review.
- Updated mailing list distribution
Steve Clevenger (4):
Add dso__is_pie call to identify ELF PIE
Force MAPPING_TYPE__IDENTIY for PIE
Add map pgoff to python dictionary based on MAPPING_TYPE
Adjust objdump start/end range per map pgoff parameter
.../scripts/python/arm-cs-trace-disasm.py | 9 ++-
tools/perf/util/map.c | 4 +-
.../scripting-engines/trace-event-python.c | 13 +++-
tools/perf/util/symbol-elf.c | 60 +++++++++++++++++++
tools/perf/util/symbol.h | 1 +
5 files changed, 79 insertions(+), 8 deletions(-)
--
2.25.1