Re: [RFC PATCH 2/3] perf tools: Add support for "report" for some spe events

From: Tan Xiaojun
Date: Fri Aug 09 2019 - 02:13:02 EST


On 2019/8/9 5:00, Jeremy Linton wrote:
> Hi,
>
> First thanks for posting this!
>
> I ran this on our DAWN platform and it does what it says. Its a pretty reasonable start, but I get -1's in the command row rather than "dd" (or similar) and this also results in [unknown] for the shared object and most userspace addresses. This is quite possibly something I'm not doing right, but I didn't spend a lot of time testing/debugging it.
>
> I did a quick glance at the code to, and had a couple comments, although I'm not a perf tool expert.
>

Hi,

Thank you for your reply.

I have only recently started working on this aspect of the perf tool, so your reply is very important to me.

I need to be sorry, my example here is not complete, until you said that I found that I only posted a part of the example. The complete example is as follows:

Example usage:

# perf record -e arm_spe/ts_enable=1,pa_enable=1/ dd if=/dev/zero of=/dev/null count=10000
# perf report

--------------------------------------------------------------------
...
# Samples: 37 of event 'llc-miss'
# Event count (approx.): 37
#
# Children Self Command Shared Object Symbol
# ........ ........ ....... ................. ....................................
#
37.84% 37.84% dd [kernel.kallsyms] [k] perf_iterate_ctx.constprop.64
16.22% 16.22% dd [kernel.kallsyms] [k] copy_page
5.41% 5.41% dd [kernel.kallsyms] [k] find_vma
5.41% 5.41% dd [kernel.kallsyms] [k] perf_event_mmap
5.41% 5.41% dd [kernel.kallsyms] [k] zap_pte_range
5.41% 5.41% dd ld-2.28.so [.] _dl_lookup_symbol_x
5.41% 5.41% dd libc-2.28.so [.] _nl_intern_locale_data
2.70% 2.70% dd [kernel.kallsyms] [k] __remove_shared_vm_struct.isra.1
2.70% 2.70% dd [kernel.kallsyms] [k] kmem_cache_free
2.70% 2.70% dd [kernel.kallsyms] [k] ttwu_do_wakeup.isra.19
2.70% 2.70% dd dd [.] 0x000000000000d9d8
2.70% 2.70% dd ld-2.28.so [.] _dl_relocate_object
2.70% 2.70% dd libc-2.28.so [.] __unregister_atfork
2.70% 2.70% dd libc-2.28.so [.] _dl_addr


# Samples: 8 of event 'tlb-miss'
# Event count (approx.): 8
#
# Children Self Command Shared Object Symbol
# ........ ........ ....... ................. .................................
#
12.50% 12.50% dd [kernel.kallsyms] [k] __audit_syscall_entry
12.50% 12.50% dd [kernel.kallsyms] [k] kmem_cache_free
12.50% 12.50% dd [kernel.kallsyms] [k] perf_iterate_ctx.constprop.64
12.50% 12.50% dd [kernel.kallsyms] [k] ttwu_do_wakeup.isra.19
12.50% 12.50% dd dd [.] 0x000000000000d9d8
12.50% 12.50% dd libc-2.28.so [.] __unregister_atfork
12.50% 12.50% dd libc-2.28.so [.] _nl_intern_locale_data
12.50% 12.50% dd libc-2.28.so [.] vfprintf


# Samples: 12 of event 'branch-miss'
# Event count (approx.): 12
#
# Children Self Command Shared Object Symbol
# ........ ........ ....... ................. ..........................
#
16.67% 16.67% dd libc-2.28.so [.] read_alias_file
8.33% 8.33% dd [kernel.kallsyms] [k] __arch_copy_from_user
8.33% 8.33% dd [kernel.kallsyms] [k] __arch_copy_to_user
8.33% 8.33% dd [kernel.kallsyms] [k] lookup_fast
8.33% 8.33% dd [kernel.kallsyms] [k] strncpy_from_user
8.33% 8.33% dd ld-2.28.so [.] _dl_lookup_symbol_x
8.33% 8.33% dd ld-2.28.so [.] check_match
8.33% 8.33% dd libc-2.28.so [.] __GI___printf_fp_l
8.33% 8.33% dd libc-2.28.so [.] _dl_addr
8.33% 8.33% dd libc-2.28.so [.] _int_malloc
8.33% 8.33% dd libc-2.28.so [.] _nl_intern_locale_data



>
> On 8/2/19 4:40 AM, Tan Xiaojun wrote:
>> After the commit ffd3d18c20b8 ("perf tools: Add ARM Statistical
>> Profiling Extensions (SPE) support") is merged, "perf record" and
>> "perf report --dump-raw-trace" have been supported. However, the
>> raw data that is dumped cannot be used without parsing.
>>
>> This patch is to improve the "perf report" support for spe, and
>> further process the data. Currently, support for the three events
>> of llc-miss, tlb-miss, and branch-miss is added.
>>
>> Example usage:
>>
>> --------------------------------------------------------------------
>> ...
>> ÂÂÂÂ 37.84%ÂÂÂ 37.84%Â ddÂÂÂÂÂÂ [kernel.kallsyms]Â [k] perf_iterate_ctx.constprop.64
>> ÂÂÂÂ 16.22%ÂÂÂ 16.22%Â ddÂÂÂÂÂÂ [kernel.kallsyms]Â [k] copy_page
>> ÂÂÂÂÂ 5.41%ÂÂÂÂ 5.41%Â ddÂÂÂÂÂÂ [kernel.kallsyms]Â [k] find_vma
>> ÂÂÂÂÂ 5.41%ÂÂÂÂ 5.41%Â ddÂÂÂÂÂÂ [kernel.kallsyms]Â [k] perf_event_mmap
>> ÂÂÂÂÂ 5.41%ÂÂÂÂ 5.41%Â ddÂÂÂÂÂÂ [kernel.kallsyms]Â [k] zap_pte_range
>> ÂÂÂÂÂ 5.41%ÂÂÂÂ 5.41%Â ddÂÂÂÂÂÂ ld-2.28.soÂÂÂÂÂÂÂÂ [.] _dl_lookup_symbol_x
>> ÂÂÂÂÂ 5.41%ÂÂÂÂ 5.41%Â ddÂÂÂÂÂÂ libc-2.28.soÂÂÂÂÂÂ [.] _nl_intern_locale_data
>> ÂÂÂÂÂ 2.70%ÂÂÂÂ 2.70%Â ddÂÂÂÂÂÂ [kernel.kallsyms]Â [k] __remove_shared_vm_struct.isra.1
>> ÂÂÂÂÂ 2.70%ÂÂÂÂ 2.70%Â ddÂÂÂÂÂÂ [kernel.kallsyms]Â [k] kmem_cache_free
>> ÂÂÂÂÂ 2.70%ÂÂÂÂ 2.70%Â ddÂÂÂÂÂÂ [kernel.kallsyms]Â [k] ttwu_do_wakeup.isra.19
>> ÂÂÂÂÂ 2.70%ÂÂÂÂ 2.70%Â ddÂÂÂÂÂÂ ddÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ [.] 0x000000000000d9d8
>> ÂÂÂÂÂ 2.70%ÂÂÂÂ 2.70%Â ddÂÂÂÂÂÂ ld-2.28.soÂÂÂÂÂÂÂÂ [.] _dl_relocate_object
>> ÂÂÂÂÂ 2.70%ÂÂÂÂ 2.70%Â ddÂÂÂÂÂÂ libc-2.28.soÂÂÂÂÂÂ [.] __unregister_atfork
>> ÂÂÂÂÂ 2.70%ÂÂÂÂ 2.70%Â ddÂÂÂÂÂÂ libc-2.28.soÂÂÂÂÂÂ [.] _dl_addr
>>
>> ÂÂÂÂ 12.50%ÂÂÂ 12.50%Â ddÂÂÂÂÂÂ [kernel.kallsyms]Â [k] __audit_syscall_entry
>> ÂÂÂÂ 12.50%ÂÂÂ 12.50%Â ddÂÂÂÂÂÂ [kernel.kallsyms]Â [k] kmem_cache_free
>> ÂÂÂÂ 12.50%ÂÂÂ 12.50%Â ddÂÂÂÂÂÂ [kernel.kallsyms]Â [k] perf_iterate_ctx.constprop.64
>> ÂÂÂÂ 12.50%ÂÂÂ 12.50%Â ddÂÂÂÂÂÂ [kernel.kallsyms]Â [k] ttwu_do_wakeup.isra.19
>> ÂÂÂÂ 12.50%ÂÂÂ 12.50%Â ddÂÂÂÂÂÂ ddÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ [.] 0x000000000000d9d8
>> ÂÂÂÂ 12.50%ÂÂÂ 12.50%Â ddÂÂÂÂÂÂ libc-2.28.soÂÂÂÂÂÂ [.] __unregister_atfork
>> ÂÂÂÂ 12.50%ÂÂÂ 12.50%Â ddÂÂÂÂÂÂ libc-2.28.soÂÂÂÂÂÂ [.] _nl_intern_locale_data
>> ÂÂÂÂ 12.50%ÂÂÂ 12.50%Â ddÂÂÂÂÂÂ libc-2.28.soÂÂÂÂÂÂ [.] vfprintf
>>
>> ÂÂÂÂ 16.67%ÂÂÂ 16.67%Â ddÂÂÂÂÂÂ libc-2.28.soÂÂÂÂÂÂ [.] read_alias_file
>> ÂÂÂÂÂ 8.33%ÂÂÂÂ 8.33%Â ddÂÂÂÂÂÂ [kernel.kallsyms]Â [k] __arch_copy_from_user
>> ÂÂÂÂÂ 8.33%ÂÂÂÂ 8.33%Â ddÂÂÂÂÂÂ [kernel.kallsyms]Â [k] __arch_copy_to_user
>> ÂÂÂÂÂ 8.33%ÂÂÂÂ 8.33%Â ddÂÂÂÂÂÂ [kernel.kallsyms]Â [k] lookup_fast
>> ÂÂÂÂÂ 8.33%ÂÂÂÂ 8.33%Â ddÂÂÂÂÂÂ [kernel.kallsyms]Â [k] strncpy_from_user
>> ÂÂÂÂÂ 8.33%ÂÂÂÂ 8.33%Â ddÂÂÂÂÂÂ ld-2.28.soÂÂÂÂÂÂÂÂ [.] _dl_lookup_symbol_x
>> ÂÂÂÂÂ 8.33%ÂÂÂÂ 8.33%Â ddÂÂÂÂÂÂ ld-2.28.soÂÂÂÂÂÂÂÂ [.] check_match
>> ÂÂÂÂÂ 8.33%ÂÂÂÂ 8.33%Â ddÂÂÂÂÂÂ libc-2.28.soÂÂÂÂÂÂ [.] __GI___printf_fp_l
>> ÂÂÂÂÂ 8.33%ÂÂÂÂ 8.33%Â ddÂÂÂÂÂÂ libc-2.28.soÂÂÂÂÂÂ [.] _dl_addr
>> ÂÂÂÂÂ 8.33%ÂÂÂÂ 8.33%Â ddÂÂÂÂÂÂ libc-2.28.soÂÂÂÂÂÂ [.] _int_malloc
>> ÂÂÂÂÂ 8.33%ÂÂÂÂ 8.33%Â ddÂÂÂÂÂÂ libc-2.28.soÂÂÂÂÂÂ [.] _nl_intern_locale_data
>>
>> --------------------------------------------------------------------
>>
>> After that, more analysis and processing of the raw data of spe
>> will be done.
>>
>> Signed-off-by: Tan Xiaojun <tanxiaojun@xxxxxxxxxx>
>> ---
>> Â tools/perf/builtin-report.cÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ |ÂÂ 5 +
>> Â tools/perf/util/arm-spe-decoder/BuildÂÂÂÂÂÂÂÂÂÂÂÂÂ |ÂÂ 2 +-
>>  tools/perf/util/arm-spe-decoder/arm-spe-decoder.c | 214 ++++++
>>  tools/perf/util/arm-spe-decoder/arm-spe-decoder.h | 51 ++
>> Â .../util/arm-spe-decoder/arm-spe-pkt-decoder.hÂÂÂÂ |ÂÂ 2 +
>> Â tools/perf/util/arm-spe.cÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ | 715 ++++++++++++++++++++-
>> Â tools/perf/util/auxtrace.cÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ |Â 45 ++
>> Â tools/perf/util/auxtrace.hÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ |Â 27 +
>> Â tools/perf/util/session.hÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ |ÂÂ 2 +
>> Â 9 files changed, 1028 insertions(+), 35 deletions(-)
>> Â create mode 100644 tools/perf/util/arm-spe-decoder/arm-spe-decoder.c
>> Â create mode 100644 tools/perf/util/arm-spe-decoder/arm-spe-decoder.h
>>
>> diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
>> index abf0b9b..fadc8eb 100644
>> --- a/tools/perf/builtin-report.c
>> +++ b/tools/perf/builtin-report.c
>> @@ -1007,6 +1007,7 @@ int cmd_report(int argc, const char **argv)
>> Â {
>> ÂÂÂÂÂ struct perf_session *session;
>> ÂÂÂÂÂ struct itrace_synth_opts itrace_synth_opts = { .set = 0, };
>> +ÂÂÂ struct arm_spe_synth_opts arm_spe_synth_opts;
>> ÂÂÂÂÂ struct stat st;
>> ÂÂÂÂÂ bool has_br_stack = false;
>> ÂÂÂÂÂ int branch_mode = -1;
>> @@ -1165,6 +1166,9 @@ int cmd_report(int argc, const char **argv)
>> ÂÂÂÂÂ OPT_CALLBACK_OPTARG(0, "itrace", &itrace_synth_opts, NULL, "opts",
>> ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ "Instruction Tracing options\n" ITRACE_HELP,
>> ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ itrace_parse_synth_opts),
>> +ÂÂÂ OPT_CALLBACK_OPTARG(0, "spe", &arm_spe_synth_opts, NULL, "spe opts",
>> +ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ "ARM SPE Tracing options",
>> +ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ arm_spe_parse_synth_opts),
>> ÂÂÂÂÂ OPT_BOOLEAN(0, "full-source-path", &srcline_full_filename,
>> ÂÂÂÂÂÂÂÂÂÂÂÂÂ "Show full source file name path for source lines"),
>> ÂÂÂÂÂ OPT_BOOLEAN(0, "show-ref-call-graph", &symbol_conf.show_ref_callgraph,
>> @@ -1266,6 +1270,7 @@ int cmd_report(int argc, const char **argv)
>> ÂÂÂÂÂ }
>> Â ÂÂÂÂÂ session->itrace_synth_opts = &itrace_synth_opts;
>> +ÂÂÂ session->arm_spe_synth_opts = &arm_spe_synth_opts;
>> Â ÂÂÂÂÂ report.session = session;
>> Â diff --git a/tools/perf/util/arm-spe-decoder/Build b/tools/perf/util/arm-spe-decoder/Build
>> index 16efbc2..f8dae13 100644
>> --- a/tools/perf/util/arm-spe-decoder/Build
>> +++ b/tools/perf/util/arm-spe-decoder/Build
>> @@ -1 +1 @@
>> -perf-$(CONFIG_AUXTRACE) += arm-spe-pkt-decoder.o
>> +perf-$(CONFIG_AUXTRACE) += arm-spe-pkt-decoder.o arm-spe-decoder.o
>> diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-decoder.c
>> new file mode 100644
>> index 0000000..8008375
>> --- /dev/null
>> +++ b/tools/perf/util/arm-spe-decoder/arm-spe-decoder.c
>> @@ -0,0 +1,214 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * arm_spe_decoder.c: ARM SPE support
>> + */
>> +
>> +#ifndef _GNU_SOURCE
>> +#define _GNU_SOURCE
>> +#endif
>> +#include <stdlib.h>
>> +#include <stdbool.h>
>> +#include <string.h>
>> +#include <errno.h>
>> +#include <stdint.h>
>> +#include <inttypes.h>
>> +#include <linux/compiler.h>
>> +#include <linux/zalloc.h>
>> +
>> +#include "../util.h"
>> +#include "../auxtrace.h"
>> +
>> +#include "arm-spe-pkt-decoder.h"
>> +#include "arm-spe-decoder.h"
>> +
>> +struct arm_spe_decoder {
>> +ÂÂÂ int (*get_trace)(struct arm_spe_buffer *buffer, void *data);
>> +ÂÂÂ void *data;
>> +ÂÂÂ struct arm_spe_state state;
>> +ÂÂÂ const unsigned char *buf;
>> +ÂÂÂ size_t len;
>> +ÂÂÂ uint64_t pos;
>> +ÂÂÂ struct arm_spe_pkt packet;
>> +ÂÂÂ int pkt_step;
>> +ÂÂÂ int pkt_len;
>> +ÂÂÂ int last_packet_type;
>> +
>> +ÂÂÂ uint64_t last_ip;
>> +ÂÂÂ uint64_t ip;
>> +ÂÂÂ uint64_t timestamp;
>> +ÂÂÂ uint64_t sample_timestamp;
>> +ÂÂÂ const unsigned char *next_buf;
>> +ÂÂÂ size_t next_len;
>> +ÂÂÂ unsigned char temp_buf[ARM_SPE_PKT_MAX_SZ];
>> +};
>> +
>> +static uint64_t arm_spe_calc_ip(uint64_t payload)
>> +{
>> +ÂÂÂ uint64_t ip = (payload & ~(0xffULL << 56));
>> +
>> +ÂÂÂ /* fill high 8 bits for kernel virtual address */
>> +ÂÂÂ if (ip & 0x1000000000000ULL)
>
> It might be better to use VA_START here if possible.
>

Yes, it's better, but I don't know how to use VA_START in user mode code. So I wrote it directly.

>> +ÂÂÂÂÂÂÂ ip |= (uint64_t)0xff00000000000000ULL;
>> +
>> +ÂÂÂ return ip;
>> +}
>> +
>> +struct arm_spe_decoder *arm_spe_decoder_new(struct arm_spe_params *params)
>> +{
>> +ÂÂÂ struct arm_spe_decoder *decoder;
>> +
>> +ÂÂÂ if (!params->get_trace)
>> +ÂÂÂÂÂÂÂ return NULL;
>> +
>> +ÂÂÂ decoder = zalloc(sizeof(struct arm_spe_decoder));
>> +ÂÂÂ if (!decoder)
>> +ÂÂÂÂÂÂÂ return NULL;
>> +
>> +ÂÂÂ decoder->get_traceÂÂÂÂÂÂÂÂÂ = params->get_trace;
>> +ÂÂÂ decoder->dataÂÂÂÂÂÂÂÂÂÂÂÂÂÂ = params->data;
>> +
>> +ÂÂÂ return decoder;
>> +}
>> +
>> +void arm_spe_decoder_free(struct arm_spe_decoder *decoder)
>> +{
>> +ÂÂÂ free(decoder);
>> +}
>> +
>> +static int arm_spe_bad_packet(struct arm_spe_decoder *decoder)
>> +{
>> +ÂÂÂ decoder->pkt_len = 1;
>> +ÂÂÂ decoder->pkt_step = 1;
>> +ÂÂÂ pr_debug("ERROR: Bad packet\n");
>> +
>> +ÂÂÂ return -EBADMSG;
>> +}
>> +
>> +
>> +static int arm_spe_get_data(struct arm_spe_decoder *decoder)
>> +{
>> +ÂÂÂ struct arm_spe_buffer buffer = { .buf = 0, };
>> +ÂÂÂ int ret;
>> +
>> +ÂÂÂ decoder->pkt_step = 0;
>> +
>> +ÂÂÂ pr_debug("Getting more data\n");
>> +ÂÂÂ ret = decoder->get_trace(&buffer, decoder->data);
>> +ÂÂÂ if (ret)
>> +ÂÂÂÂÂÂÂ return ret;
>> +
>> +ÂÂÂ decoder->buf = buffer.buf;
>> +ÂÂÂ decoder->len = buffer.len;
>> +ÂÂÂ if (!decoder->len) {
>> +ÂÂÂÂÂÂÂ pr_debug("No more data\n");
>> +ÂÂÂÂÂÂÂ return -ENODATA;
>> +ÂÂÂ }
>> +
>> +ÂÂÂ return 0;
>> +}
>> +
>> +static int arm_spe_get_next_data(struct arm_spe_decoder *decoder)
>> +{
>> +ÂÂÂ return arm_spe_get_data(decoder);
>> +}
>> +
>> +static int arm_spe_get_next_packet(struct arm_spe_decoder *decoder)
>> +{
>> +ÂÂÂ int ret;
>> +
>> +ÂÂÂ decoder->last_packet_type = decoder->packet.type;
>> +
>> +ÂÂÂ do {
>> +ÂÂÂÂÂÂÂ decoder->pos += decoder->pkt_step;
>> +ÂÂÂÂÂÂÂ decoder->buf += decoder->pkt_step;
>> +ÂÂÂÂÂÂÂ decoder->len -= decoder->pkt_step;
>> +
>> +
>> +ÂÂÂÂÂÂÂ if (!decoder->len) {
>> +ÂÂÂÂÂÂÂÂÂÂÂ ret = arm_spe_get_next_data(decoder);
>> +ÂÂÂÂÂÂÂÂÂÂÂ if (ret)
>> +ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ return ret;
>> +ÂÂÂÂÂÂÂ }
>> +
>> +ÂÂÂÂÂÂÂ ret = arm_spe_get_packet(decoder->buf, decoder->len,
>> +ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ &decoder->packet);
>> +ÂÂÂÂÂÂÂ if (ret <= 0)
>> +ÂÂÂÂÂÂÂÂÂÂÂ return arm_spe_bad_packet(decoder);
>> +
>> +ÂÂÂÂÂÂÂ decoder->pkt_len = ret;
>> +ÂÂÂÂÂÂÂ decoder->pkt_step = ret;
>> +ÂÂÂ } while (decoder->packet.type == ARM_SPE_PAD);
>> +
>> +ÂÂÂ return 0;
>> +}
>> +
>> +static int arm_spe_walk_trace(struct arm_spe_decoder *decoder)
>> +{
>> +ÂÂÂ int err;
>> +ÂÂÂ int idx;
>> +ÂÂÂ uint64_t payload;
>> +
>> +ÂÂÂ while (1) {
>> +ÂÂÂÂÂÂÂ err = arm_spe_get_next_packet(decoder);
>> +ÂÂÂÂÂÂÂ if (err)
>> +ÂÂÂÂÂÂÂÂÂÂÂ return err;
>> +
>> +ÂÂÂÂÂÂÂ idx = decoder->packet.index;
>> +ÂÂÂÂÂÂÂ payload = decoder->packet.payload;
>> +
>> +ÂÂÂÂÂÂÂ switch (decoder->packet.type) {
>> +ÂÂÂÂÂÂÂ case ARM_SPE_TIMESTAMP:
>> +ÂÂÂÂÂÂÂÂÂÂÂ decoder->sample_timestamp = payload;
>> +ÂÂÂÂÂÂÂÂÂÂÂ return 0;
>> +ÂÂÂÂÂÂÂ case ARM_SPE_END:
>> +ÂÂÂÂÂÂÂÂÂÂÂ decoder->sample_timestamp = 0;
>> +ÂÂÂÂÂÂÂÂÂÂÂ return 0;
>> +ÂÂÂÂÂÂÂ case ARM_SPE_ADDRESS:
>> +ÂÂÂÂÂÂÂÂÂÂÂ decoder->ip = arm_spe_calc_ip(payload);
>> +ÂÂÂÂÂÂÂÂÂÂÂ if (idx == 0)
>> +ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ decoder->state.from_ip = decoder->ip;
>> +ÂÂÂÂÂÂÂÂÂÂÂ else if (idx == 1)
>> +ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ decoder->state.to_ip = decoder->ip;
>> +ÂÂÂÂÂÂÂÂÂÂÂ break;
>> +ÂÂÂÂÂÂÂ case ARM_SPE_COUNTER:
>> +ÂÂÂÂÂÂÂÂÂÂÂ break;
>> +ÂÂÂÂÂÂÂ case ARM_SPE_CONTEXT:
>> +ÂÂÂÂÂÂÂÂÂÂÂ break;
>> +ÂÂÂÂÂÂÂ case ARM_SPE_OP_TYPE:
>> +ÂÂÂÂÂÂÂÂÂÂÂ break;
>> +ÂÂÂÂÂÂÂ case ARM_SPE_EVENTS:
>> +ÂÂÂÂÂÂÂÂÂÂÂ if (payload & 0x20)
>> +ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ decoder->state.type |= ARM_SPE_TLB_MISS;
>> +ÂÂÂÂÂÂÂÂÂÂÂ if (payload & 0x80)
>> +ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ decoder->state.type |= ARM_SPE_BRANCH_MISS;
>> +ÂÂÂÂÂÂÂÂÂÂÂ if (idx > 1 && (payload & 0x200))
>> +ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ decoder->state.type |= ARM_SPE_LLC_MISS;
>> +
>> +ÂÂÂÂÂÂÂÂÂÂÂ break;
>> +ÂÂÂÂÂÂÂ case ARM_SPE_DATA_SOURCE:
>> +ÂÂÂÂÂÂÂÂÂÂÂ break;
>> +ÂÂÂÂÂÂÂ case ARM_SPE_BAD:
>> +ÂÂÂÂÂÂÂÂÂÂÂ break;
>> +ÂÂÂÂÂÂÂ case ARM_SPE_PAD:
>> +ÂÂÂÂÂÂÂÂÂÂÂ break;
>> +ÂÂÂÂÂÂÂ default:
>> +ÂÂÂÂÂÂÂÂÂÂÂ pr_err("Get Packet Error!\n");
>> +ÂÂÂÂÂÂÂÂÂÂÂ return -ENOSYS;
>> +ÂÂÂÂÂÂÂ }
>> +ÂÂÂ }
>> +}
>
> This code looks very similar to arm_spe_pkt_desc(), I can't help but think they should be consolidated in some way. If nothing else the magic 0x20, 0x80, etc ARM_SPE_EVENTS should be defined somewhere and shared.
>

Yes, I wrote it with reference to it. What you said makes sense. I will try to modify it later.

Xiaojun.

>
>> +
>> +const struct arm_spe_state *arm_spe_decode(struct arm_spe_decoder *decoder)
>> +{
>> +ÂÂÂ int err;
>> +
>> +ÂÂÂ decoder->state.type = 0;
>> +
>> +ÂÂÂ err = arm_spe_walk_trace(decoder);
>> +ÂÂÂ if (err)
>> +ÂÂÂÂÂÂÂ decoder->state.err = err;
>> +
>> +ÂÂÂ decoder->state.timestamp = decoder->sample_timestamp;
>> +
>> +ÂÂÂ return &decoder->state;
>
> (trimming remainder)
>
>
> .
>