2018-01-14 13:28:50 -06:00
|
|
|
// SPDX-License-Identifier: GPL-2.0
|
|
|
|
/*
|
|
|
|
* Arm Statistical Profiling Extensions (SPE) support
|
|
|
|
* Copyright (c) 2017-2018, Arm Ltd.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <endian.h>
|
|
|
|
#include <byteswap.h>
|
2020-11-11 15:11:28 +08:00
|
|
|
#include <linux/bitops.h>
|
perf arm-spe: Refactor printing string to buffer
When outputs strings to the decoding buffer with function snprintf(),
SPE decoder needs to detects if any error returns from snprintf() and if
so needs to directly bail out. If snprintf() returns success, it needs
to update buffer pointer and reduce the buffer length so can continue to
output the next string into the consequent memory space.
This complex logics are spreading in the function arm_spe_pkt_desc() so
there has many duplicate codes for handling error detecting, increment
buffer pointer and decrement buffer size.
To avoid the duplicate code, this patch introduces a new helper function
arm_spe_pkt_out_string() which is used to wrap up the complex logics,
and it's used by the caller arm_spe_pkt_desc(). This patch moves the
variable 'blen' as the function's local variable so allows to remove
the unnecessary braces and improve the readability.
This patch simplifies the return value for arm_spe_pkt_desc(): '0' means
success and other values mean an error has occurred. To realize this,
it relies on arm_spe_pkt_out_string()'s parameter 'err', the 'err' is a
cumulative value, returns its final value if printing buffer is called
for one time or multiple times. Finally, the error is handled in a
central place, rather than directly bailing out in switch-cases, it
returns error at the end of arm_spe_pkt_desc().
This patch changes the caller arm_spe_dump() to respect the updated
return value semantics of arm_spe_pkt_desc().
Suggested-by: Dave Martin <Dave.Martin@arm.com>
Signed-off-by: Leo Yan <leo.yan@linaro.org>
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Dave Martin <Dave.Martin@arm.com>
Acked-by: Will Deacon <will@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Al Grant <Al.Grant@arm.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@arm.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: John Garry <john.garry@huawei.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Wei Li <liwei391@huawei.com>
Link: https://lore.kernel.org/r/20201119152441.6972-2-leo.yan@linaro.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2020-11-19 23:24:26 +08:00
|
|
|
#include <stdarg.h>
|
2024-05-13 22:24:02 -07:00
|
|
|
#include <linux/kernel.h>
|
2024-10-01 15:35:57 -04:00
|
|
|
#include <linux/unaligned.h>
|
2018-01-14 13:28:50 -06:00
|
|
|
|
|
|
|
#include "arm-spe-pkt-decoder.h"
|
|
|
|
|
|
|
|
static const char * const arm_spe_packet_name[] = {
|
|
|
|
[ARM_SPE_PAD] = "PAD",
|
|
|
|
[ARM_SPE_END] = "END",
|
|
|
|
[ARM_SPE_TIMESTAMP] = "TS",
|
|
|
|
[ARM_SPE_ADDRESS] = "ADDR",
|
|
|
|
[ARM_SPE_COUNTER] = "LAT",
|
|
|
|
[ARM_SPE_CONTEXT] = "CONTEXT",
|
|
|
|
[ARM_SPE_OP_TYPE] = "OP-TYPE",
|
|
|
|
[ARM_SPE_EVENTS] = "EVENTS",
|
|
|
|
[ARM_SPE_DATA_SOURCE] = "DATA-SOURCE",
|
|
|
|
};
|
|
|
|
|
|
|
|
const char *arm_spe_pkt_name(enum arm_spe_pkt_type type)
|
|
|
|
{
|
|
|
|
return arm_spe_packet_name[type];
|
|
|
|
}
|
|
|
|
|
2020-11-11 15:11:30 +08:00
|
|
|
/*
|
|
|
|
* Extracts the field "sz" from header bits and converts to bytes:
|
|
|
|
* 00 : byte (1)
|
|
|
|
* 01 : halfword (2)
|
|
|
|
* 10 : word (4)
|
|
|
|
* 11 : doubleword (8)
|
2018-01-14 13:28:50 -06:00
|
|
|
*/
|
2020-11-11 15:11:30 +08:00
|
|
|
static unsigned int arm_spe_payload_len(unsigned char hdr)
|
2018-01-14 13:28:50 -06:00
|
|
|
{
|
2020-11-11 15:11:30 +08:00
|
|
|
return 1U << ((hdr & GENMASK_ULL(5, 4)) >> 4);
|
2018-01-14 13:28:50 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
static int arm_spe_get_payload(const unsigned char *buf, size_t len,
|
2020-11-11 15:11:32 +08:00
|
|
|
unsigned char ext_hdr,
|
2018-01-14 13:28:50 -06:00
|
|
|
struct arm_spe_pkt *packet)
|
|
|
|
{
|
2020-11-11 15:11:32 +08:00
|
|
|
size_t payload_len = arm_spe_payload_len(buf[ext_hdr]);
|
2018-01-14 13:28:50 -06:00
|
|
|
|
2020-11-11 15:11:32 +08:00
|
|
|
if (len < 1 + ext_hdr + payload_len)
|
2018-01-14 13:28:50 -06:00
|
|
|
return ARM_SPE_NEED_MORE_BYTES;
|
|
|
|
|
2020-11-11 15:11:32 +08:00
|
|
|
buf += 1 + ext_hdr;
|
2018-01-14 13:28:50 -06:00
|
|
|
|
|
|
|
switch (payload_len) {
|
|
|
|
case 1: packet->payload = *(uint8_t *)buf; break;
|
2024-05-13 22:24:02 -07:00
|
|
|
case 2: packet->payload = get_unaligned_le16(buf); break;
|
|
|
|
case 4: packet->payload = get_unaligned_le32(buf); break;
|
|
|
|
case 8: packet->payload = get_unaligned_le64(buf); break;
|
2018-01-14 13:28:50 -06:00
|
|
|
default: return ARM_SPE_BAD_PACKET;
|
|
|
|
}
|
|
|
|
|
2020-11-11 15:11:32 +08:00
|
|
|
return 1 + ext_hdr + payload_len;
|
2018-01-14 13:28:50 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
static int arm_spe_get_pad(struct arm_spe_pkt *packet)
|
|
|
|
{
|
|
|
|
packet->type = ARM_SPE_PAD;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int arm_spe_get_alignment(const unsigned char *buf, size_t len,
|
|
|
|
struct arm_spe_pkt *packet)
|
|
|
|
{
|
|
|
|
unsigned int alignment = 1 << ((buf[0] & 0xf) + 1);
|
|
|
|
|
|
|
|
if (len < alignment)
|
|
|
|
return ARM_SPE_NEED_MORE_BYTES;
|
|
|
|
|
|
|
|
packet->type = ARM_SPE_PAD;
|
|
|
|
return alignment - (((uintptr_t)buf) & (alignment - 1));
|
|
|
|
}
|
|
|
|
|
|
|
|
static int arm_spe_get_end(struct arm_spe_pkt *packet)
|
|
|
|
{
|
|
|
|
packet->type = ARM_SPE_END;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int arm_spe_get_timestamp(const unsigned char *buf, size_t len,
|
|
|
|
struct arm_spe_pkt *packet)
|
|
|
|
{
|
|
|
|
packet->type = ARM_SPE_TIMESTAMP;
|
2020-11-11 15:11:32 +08:00
|
|
|
return arm_spe_get_payload(buf, len, 0, packet);
|
2018-01-14 13:28:50 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
static int arm_spe_get_events(const unsigned char *buf, size_t len,
|
|
|
|
struct arm_spe_pkt *packet)
|
|
|
|
{
|
|
|
|
packet->type = ARM_SPE_EVENTS;
|
|
|
|
|
|
|
|
/* we use index to identify Events with a less number of
|
|
|
|
* comparisons in arm_spe_pkt_desc(): E.g., the LLC-ACCESS,
|
2020-11-11 15:11:29 +08:00
|
|
|
* LLC-REFILL, and REMOTE-ACCESS events are identified if
|
2018-01-14 13:28:50 -06:00
|
|
|
* index > 1.
|
|
|
|
*/
|
2020-11-11 15:11:31 +08:00
|
|
|
packet->index = arm_spe_payload_len(buf[0]);
|
2018-01-14 13:28:50 -06:00
|
|
|
|
2020-11-11 15:11:32 +08:00
|
|
|
return arm_spe_get_payload(buf, len, 0, packet);
|
2018-01-14 13:28:50 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
static int arm_spe_get_data_source(const unsigned char *buf, size_t len,
|
|
|
|
struct arm_spe_pkt *packet)
|
|
|
|
{
|
|
|
|
packet->type = ARM_SPE_DATA_SOURCE;
|
2020-11-11 15:11:32 +08:00
|
|
|
return arm_spe_get_payload(buf, len, 0, packet);
|
2018-01-14 13:28:50 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
static int arm_spe_get_context(const unsigned char *buf, size_t len,
|
|
|
|
struct arm_spe_pkt *packet)
|
|
|
|
{
|
|
|
|
packet->type = ARM_SPE_CONTEXT;
|
2020-11-19 23:24:31 +08:00
|
|
|
packet->index = SPE_CTX_PKT_HDR_INDEX(buf[0]);
|
2020-11-11 15:11:32 +08:00
|
|
|
return arm_spe_get_payload(buf, len, 0, packet);
|
2018-01-14 13:28:50 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
static int arm_spe_get_op_type(const unsigned char *buf, size_t len,
|
|
|
|
struct arm_spe_pkt *packet)
|
|
|
|
{
|
|
|
|
packet->type = ARM_SPE_OP_TYPE;
|
2020-11-19 23:24:38 +08:00
|
|
|
packet->index = SPE_OP_PKT_HDR_CLASS(buf[0]);
|
2020-11-11 15:11:32 +08:00
|
|
|
return arm_spe_get_payload(buf, len, 0, packet);
|
2018-01-14 13:28:50 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
static int arm_spe_get_counter(const unsigned char *buf, size_t len,
|
|
|
|
const unsigned char ext_hdr, struct arm_spe_pkt *packet)
|
|
|
|
{
|
|
|
|
packet->type = ARM_SPE_COUNTER;
|
2020-11-19 23:24:33 +08:00
|
|
|
|
2018-01-14 13:28:50 -06:00
|
|
|
if (ext_hdr)
|
2020-11-19 23:24:33 +08:00
|
|
|
packet->index = SPE_HDR_EXTENDED_INDEX(buf[0], buf[1]);
|
2018-01-14 13:28:50 -06:00
|
|
|
else
|
2020-11-19 23:24:33 +08:00
|
|
|
packet->index = SPE_HDR_SHORT_INDEX(buf[0]);
|
2018-01-14 13:28:50 -06:00
|
|
|
|
2020-11-11 15:11:32 +08:00
|
|
|
return arm_spe_get_payload(buf, len, ext_hdr, packet);
|
2018-01-14 13:28:50 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
static int arm_spe_get_addr(const unsigned char *buf, size_t len,
|
|
|
|
const unsigned char ext_hdr, struct arm_spe_pkt *packet)
|
|
|
|
{
|
|
|
|
packet->type = ARM_SPE_ADDRESS;
|
2020-11-19 23:24:29 +08:00
|
|
|
|
2018-01-14 13:28:50 -06:00
|
|
|
if (ext_hdr)
|
2020-11-19 23:24:29 +08:00
|
|
|
packet->index = SPE_HDR_EXTENDED_INDEX(buf[0], buf[1]);
|
2018-01-14 13:28:50 -06:00
|
|
|
else
|
2020-11-19 23:24:29 +08:00
|
|
|
packet->index = SPE_HDR_SHORT_INDEX(buf[0]);
|
2018-01-14 13:28:50 -06:00
|
|
|
|
2020-11-11 15:11:32 +08:00
|
|
|
return arm_spe_get_payload(buf, len, ext_hdr, packet);
|
2018-01-14 13:28:50 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
static int arm_spe_do_get_packet(const unsigned char *buf, size_t len,
|
|
|
|
struct arm_spe_pkt *packet)
|
|
|
|
{
|
2020-11-19 23:24:27 +08:00
|
|
|
unsigned int hdr;
|
|
|
|
unsigned char ext_hdr = 0;
|
2018-01-14 13:28:50 -06:00
|
|
|
|
|
|
|
memset(packet, 0, sizeof(struct arm_spe_pkt));
|
|
|
|
|
|
|
|
if (!len)
|
|
|
|
return ARM_SPE_NEED_MORE_BYTES;
|
|
|
|
|
2020-11-19 23:24:27 +08:00
|
|
|
hdr = buf[0];
|
|
|
|
|
|
|
|
if (hdr == SPE_HEADER0_PAD)
|
2018-01-14 13:28:50 -06:00
|
|
|
return arm_spe_get_pad(packet);
|
2020-11-19 23:24:27 +08:00
|
|
|
|
|
|
|
if (hdr == SPE_HEADER0_END) /* no timestamp at end of record */
|
2018-01-14 13:28:50 -06:00
|
|
|
return arm_spe_get_end(packet);
|
2020-11-19 23:24:27 +08:00
|
|
|
|
|
|
|
if (hdr == SPE_HEADER0_TIMESTAMP)
|
|
|
|
return arm_spe_get_timestamp(buf, len, packet);
|
|
|
|
|
|
|
|
if ((hdr & SPE_HEADER0_MASK1) == SPE_HEADER0_EVENTS)
|
|
|
|
return arm_spe_get_events(buf, len, packet);
|
|
|
|
|
|
|
|
if ((hdr & SPE_HEADER0_MASK1) == SPE_HEADER0_SOURCE)
|
|
|
|
return arm_spe_get_data_source(buf, len, packet);
|
|
|
|
|
|
|
|
if ((hdr & SPE_HEADER0_MASK2) == SPE_HEADER0_CONTEXT)
|
|
|
|
return arm_spe_get_context(buf, len, packet);
|
|
|
|
|
|
|
|
if ((hdr & SPE_HEADER0_MASK2) == SPE_HEADER0_OP_TYPE)
|
|
|
|
return arm_spe_get_op_type(buf, len, packet);
|
|
|
|
|
|
|
|
if ((hdr & SPE_HEADER0_MASK2) == SPE_HEADER0_EXTENDED) {
|
|
|
|
/* 16-bit extended format header */
|
2021-04-07 08:39:55 -07:00
|
|
|
if (len == 1)
|
|
|
|
return ARM_SPE_BAD_PACKET;
|
2020-11-19 23:24:27 +08:00
|
|
|
|
2021-04-07 08:39:55 -07:00
|
|
|
ext_hdr = 1;
|
2020-11-19 23:24:27 +08:00
|
|
|
hdr = buf[1];
|
|
|
|
if (hdr == SPE_HEADER1_ALIGNMENT)
|
2018-01-14 13:28:50 -06:00
|
|
|
return arm_spe_get_alignment(buf, len, packet);
|
|
|
|
}
|
|
|
|
|
2020-11-19 23:24:27 +08:00
|
|
|
/*
|
|
|
|
* The short format header's byte 0 or the extended format header's
|
|
|
|
* byte 1 has been assigned to 'hdr', which uses the same encoding for
|
|
|
|
* address packet and counter packet, so don't need to distinguish if
|
|
|
|
* it's short format or extended format and handle in once.
|
|
|
|
*/
|
|
|
|
if ((hdr & SPE_HEADER0_MASK3) == SPE_HEADER0_ADDRESS)
|
|
|
|
return arm_spe_get_addr(buf, len, ext_hdr, packet);
|
|
|
|
|
|
|
|
if ((hdr & SPE_HEADER0_MASK3) == SPE_HEADER0_COUNTER)
|
|
|
|
return arm_spe_get_counter(buf, len, ext_hdr, packet);
|
|
|
|
|
2018-01-14 13:28:50 -06:00
|
|
|
return ARM_SPE_BAD_PACKET;
|
|
|
|
}
|
|
|
|
|
|
|
|
int arm_spe_get_packet(const unsigned char *buf, size_t len,
|
|
|
|
struct arm_spe_pkt *packet)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = arm_spe_do_get_packet(buf, len, packet);
|
|
|
|
/* put multiple consecutive PADs on the same line, up to
|
|
|
|
* the fixed-width output format of 16 bytes per line.
|
|
|
|
*/
|
|
|
|
if (ret > 0 && packet->type == ARM_SPE_PAD) {
|
|
|
|
while (ret < 16 && len > (size_t)ret && !buf[ret])
|
|
|
|
ret += 1;
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
perf arm-spe: Refactor printing string to buffer
When outputs strings to the decoding buffer with function snprintf(),
SPE decoder needs to detects if any error returns from snprintf() and if
so needs to directly bail out. If snprintf() returns success, it needs
to update buffer pointer and reduce the buffer length so can continue to
output the next string into the consequent memory space.
This complex logics are spreading in the function arm_spe_pkt_desc() so
there has many duplicate codes for handling error detecting, increment
buffer pointer and decrement buffer size.
To avoid the duplicate code, this patch introduces a new helper function
arm_spe_pkt_out_string() which is used to wrap up the complex logics,
and it's used by the caller arm_spe_pkt_desc(). This patch moves the
variable 'blen' as the function's local variable so allows to remove
the unnecessary braces and improve the readability.
This patch simplifies the return value for arm_spe_pkt_desc(): '0' means
success and other values mean an error has occurred. To realize this,
it relies on arm_spe_pkt_out_string()'s parameter 'err', the 'err' is a
cumulative value, returns its final value if printing buffer is called
for one time or multiple times. Finally, the error is handled in a
central place, rather than directly bailing out in switch-cases, it
returns error at the end of arm_spe_pkt_desc().
This patch changes the caller arm_spe_dump() to respect the updated
return value semantics of arm_spe_pkt_desc().
Suggested-by: Dave Martin <Dave.Martin@arm.com>
Signed-off-by: Leo Yan <leo.yan@linaro.org>
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Dave Martin <Dave.Martin@arm.com>
Acked-by: Will Deacon <will@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Al Grant <Al.Grant@arm.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@arm.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: John Garry <john.garry@huawei.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Wei Li <liwei391@huawei.com>
Link: https://lore.kernel.org/r/20201119152441.6972-2-leo.yan@linaro.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2020-11-19 23:24:26 +08:00
|
|
|
static int arm_spe_pkt_out_string(int *err, char **buf_p, size_t *blen,
|
|
|
|
const char *fmt, ...)
|
|
|
|
{
|
|
|
|
va_list ap;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
/* Bail out if any error occurred */
|
|
|
|
if (err && *err)
|
|
|
|
return *err;
|
|
|
|
|
|
|
|
va_start(ap, fmt);
|
|
|
|
ret = vsnprintf(*buf_p, *blen, fmt, ap);
|
|
|
|
va_end(ap);
|
|
|
|
|
|
|
|
if (ret < 0) {
|
|
|
|
if (err && !*err)
|
|
|
|
*err = ret;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* A return value of *blen or more means that the output was
|
|
|
|
* truncated and the buffer is overrun.
|
|
|
|
*/
|
|
|
|
} else if ((size_t)ret >= *blen) {
|
|
|
|
(*buf_p)[*blen - 1] = '\0';
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Set *err to 'ret' to avoid overflow if tries to
|
|
|
|
* fill this buffer sequentially.
|
|
|
|
*/
|
|
|
|
if (err && !*err)
|
|
|
|
*err = ret;
|
|
|
|
} else {
|
|
|
|
*buf_p += ret;
|
|
|
|
*blen -= ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2020-11-19 23:24:34 +08:00
|
|
|
static int arm_spe_pkt_desc_event(const struct arm_spe_pkt *packet,
|
|
|
|
char *buf, size_t buf_len)
|
|
|
|
{
|
|
|
|
u64 payload = packet->payload;
|
|
|
|
int err = 0;
|
|
|
|
|
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len, "EV");
|
|
|
|
|
2020-11-19 23:24:35 +08:00
|
|
|
if (payload & BIT(EV_EXCEPTION_GEN))
|
2020-11-19 23:24:34 +08:00
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len, " EXCEPTION-GEN");
|
2020-11-19 23:24:35 +08:00
|
|
|
if (payload & BIT(EV_RETIRED))
|
2020-11-19 23:24:34 +08:00
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len, " RETIRED");
|
2020-11-19 23:24:35 +08:00
|
|
|
if (payload & BIT(EV_L1D_ACCESS))
|
2020-11-19 23:24:34 +08:00
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len, " L1D-ACCESS");
|
2020-11-19 23:24:35 +08:00
|
|
|
if (payload & BIT(EV_L1D_REFILL))
|
2020-11-19 23:24:34 +08:00
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len, " L1D-REFILL");
|
2020-11-19 23:24:35 +08:00
|
|
|
if (payload & BIT(EV_TLB_ACCESS))
|
2020-11-19 23:24:34 +08:00
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len, " TLB-ACCESS");
|
2020-11-19 23:24:35 +08:00
|
|
|
if (payload & BIT(EV_TLB_WALK))
|
2020-11-19 23:24:34 +08:00
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len, " TLB-REFILL");
|
2020-11-19 23:24:35 +08:00
|
|
|
if (payload & BIT(EV_NOT_TAKEN))
|
2020-11-19 23:24:34 +08:00
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len, " NOT-TAKEN");
|
2020-11-19 23:24:35 +08:00
|
|
|
if (payload & BIT(EV_MISPRED))
|
2020-11-19 23:24:34 +08:00
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len, " MISPRED");
|
perf arm-spe: Remove size condition checking for events
In the Armv8 ARM (ARM DDI 0487F.c), chapter "D10.2.6 Events packet", it
describes the event bit is valid with specific payload requirement. For
example, the Last Level cache access event, the bit is defined as:
E[8], byte 1 bit [0], when SZ == 0b01 , when SZ == 0b10 ,
or when SZ == 0b11
It requires the payload size is at least 2 bytes, when byte 1 (start
counting from 0) is valid, E[8] (bit 0 in byte 1) can be used for LLC
access event type. For safety, the code checks the condition for
payload size firstly, if meet the requirement for payload size, then
continue to parse event type.
If review function arm_spe_get_payload(), it has used cast, so any bytes
beyond the valid size have been set to zeros.
For this reason, we don't need to check payload size anymore afterwards
when parse events, thus this patch removes payload size conditions.
Suggested-by: Andre Przywara <andre.przywara@arm.com>
Signed-off-by: Leo Yan <leo.yan@linaro.org>
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Acked-by: Will Deacon <will@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Al Grant <Al.Grant@arm.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Dave Martin <Dave.Martin@arm.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@arm.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: John Garry <john.garry@huawei.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Wei Li <liwei391@huawei.com>
Link: https://lore.kernel.org/r/20201119152441.6972-12-leo.yan@linaro.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2020-11-19 23:24:36 +08:00
|
|
|
if (payload & BIT(EV_LLC_ACCESS))
|
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len, " LLC-ACCESS");
|
|
|
|
if (payload & BIT(EV_LLC_MISS))
|
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len, " LLC-REFILL");
|
|
|
|
if (payload & BIT(EV_REMOTE_ACCESS))
|
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len, " REMOTE-ACCESS");
|
2020-11-19 23:24:41 +08:00
|
|
|
if (payload & BIT(EV_ALIGNMENT))
|
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len, " ALIGNMENT");
|
2025-03-04 11:12:36 +00:00
|
|
|
if (payload & BIT(EV_TRANSACTIONAL))
|
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len, " TXN");
|
2020-11-19 23:24:41 +08:00
|
|
|
if (payload & BIT(EV_PARTIAL_PREDICATE))
|
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len, " SVE-PARTIAL-PRED");
|
|
|
|
if (payload & BIT(EV_EMPTY_PREDICATE))
|
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len, " SVE-EMPTY-PRED");
|
2020-11-19 23:24:34 +08:00
|
|
|
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
2020-11-19 23:24:37 +08:00
|
|
|
static int arm_spe_pkt_desc_op_type(const struct arm_spe_pkt *packet,
|
|
|
|
char *buf, size_t buf_len)
|
|
|
|
{
|
|
|
|
u64 payload = packet->payload;
|
|
|
|
int err = 0;
|
|
|
|
|
|
|
|
switch (packet->index) {
|
2020-11-19 23:24:38 +08:00
|
|
|
case SPE_OP_PKT_HDR_CLASS_OTHER:
|
2020-11-19 23:24:41 +08:00
|
|
|
if (SPE_OP_PKT_IS_OTHER_SVE_OP(payload)) {
|
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len, "SVE-OTHER");
|
|
|
|
|
|
|
|
/* SVE effective vector length */
|
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len, " EVLEN %d",
|
|
|
|
SPE_OP_PKG_SVE_EVL(payload));
|
|
|
|
|
|
|
|
if (payload & SPE_OP_PKT_SVE_FP)
|
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len, " FP");
|
|
|
|
if (payload & SPE_OP_PKT_SVE_PRED)
|
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len, " PRED");
|
|
|
|
} else {
|
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len, "OTHER");
|
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len, " %s",
|
|
|
|
payload & SPE_OP_PKT_COND ?
|
|
|
|
"COND-SELECT" : "INSN-OTHER");
|
|
|
|
}
|
2020-11-19 23:24:37 +08:00
|
|
|
break;
|
2020-11-19 23:24:38 +08:00
|
|
|
case SPE_OP_PKT_HDR_CLASS_LD_ST_ATOMIC:
|
2020-11-19 23:24:37 +08:00
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len,
|
|
|
|
payload & 0x1 ? "ST" : "LD");
|
|
|
|
|
2020-11-19 23:24:38 +08:00
|
|
|
if (SPE_OP_PKT_IS_LDST_ATOMIC(payload)) {
|
|
|
|
if (payload & SPE_OP_PKT_AT)
|
2020-11-19 23:24:37 +08:00
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len, " AT");
|
2020-11-19 23:24:38 +08:00
|
|
|
if (payload & SPE_OP_PKT_EXCL)
|
2020-11-19 23:24:37 +08:00
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len, " EXCL");
|
2020-11-19 23:24:38 +08:00
|
|
|
if (payload & SPE_OP_PKT_AR)
|
2020-11-19 23:24:37 +08:00
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len, " AR");
|
2020-11-19 23:24:39 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
switch (SPE_OP_PKT_LDST_SUBCLASS_GET(payload)) {
|
|
|
|
case SPE_OP_PKT_LDST_SUBCLASS_SIMD_FP:
|
2020-11-19 23:24:37 +08:00
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len, " SIMD-FP");
|
2020-11-19 23:24:39 +08:00
|
|
|
break;
|
|
|
|
case SPE_OP_PKT_LDST_SUBCLASS_GP_REG:
|
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len, " GP-REG");
|
|
|
|
break;
|
|
|
|
case SPE_OP_PKT_LDST_SUBCLASS_UNSPEC_REG:
|
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len, " UNSPEC-REG");
|
|
|
|
break;
|
|
|
|
case SPE_OP_PKT_LDST_SUBCLASS_NV_SYSREG:
|
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len, " NV-SYSREG");
|
|
|
|
break;
|
2023-03-27 11:20:57 -05:00
|
|
|
case SPE_OP_PKT_LDST_SUBCLASS_MTE_TAG:
|
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len, " MTE-TAG");
|
|
|
|
break;
|
|
|
|
case SPE_OP_PKT_LDST_SUBCLASS_MEMCPY:
|
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len, " MEMCPY");
|
|
|
|
break;
|
|
|
|
case SPE_OP_PKT_LDST_SUBCLASS_MEMSET:
|
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len, " MEMSET");
|
|
|
|
break;
|
2020-11-19 23:24:39 +08:00
|
|
|
default:
|
|
|
|
break;
|
2020-11-19 23:24:37 +08:00
|
|
|
}
|
2020-11-19 23:24:41 +08:00
|
|
|
|
|
|
|
if (SPE_OP_PKT_IS_LDST_SVE(payload)) {
|
|
|
|
/* SVE effective vector length */
|
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len, " EVLEN %d",
|
|
|
|
SPE_OP_PKG_SVE_EVL(payload));
|
|
|
|
|
|
|
|
if (payload & SPE_OP_PKT_SVE_PRED)
|
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len, " PRED");
|
|
|
|
if (payload & SPE_OP_PKT_SVE_SG)
|
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len, " SG");
|
|
|
|
}
|
2020-11-19 23:24:37 +08:00
|
|
|
break;
|
2020-11-19 23:24:38 +08:00
|
|
|
case SPE_OP_PKT_HDR_CLASS_BR_ERET:
|
2020-11-19 23:24:37 +08:00
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len, "B");
|
|
|
|
|
2020-11-19 23:24:38 +08:00
|
|
|
if (payload & SPE_OP_PKT_COND)
|
2020-11-19 23:24:37 +08:00
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len, " COND");
|
2025-03-04 11:12:35 +00:00
|
|
|
if (payload & SPE_OP_PKT_INDIRECT_BRANCH)
|
2020-11-19 23:24:37 +08:00
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len, " IND");
|
2025-03-04 11:12:35 +00:00
|
|
|
if (payload & SPE_OP_PKT_GCS)
|
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len, " GCS");
|
|
|
|
if (SPE_OP_PKT_CR_BL(payload))
|
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len, " CR-BL");
|
|
|
|
if (SPE_OP_PKT_CR_RET(payload))
|
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len, " CR-RET");
|
|
|
|
if (SPE_OP_PKT_CR_NON_BL_RET(payload))
|
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len, " CR-NON-BL-RET");
|
2020-11-19 23:24:37 +08:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
/* Unknown index */
|
|
|
|
err = -1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
2020-11-19 23:24:28 +08:00
|
|
|
static int arm_spe_pkt_desc_addr(const struct arm_spe_pkt *packet,
|
|
|
|
char *buf, size_t buf_len)
|
|
|
|
{
|
|
|
|
int ns, el, idx = packet->index;
|
2020-11-19 23:24:40 +08:00
|
|
|
int ch, pat;
|
2020-11-19 23:24:28 +08:00
|
|
|
u64 payload = packet->payload;
|
|
|
|
int err = 0;
|
2023-02-03 10:24:01 -06:00
|
|
|
static const char *idx_name[] = {"PC", "TGT", "VA", "PA", "PBT"};
|
2020-11-19 23:24:28 +08:00
|
|
|
|
|
|
|
switch (idx) {
|
2020-11-19 23:24:29 +08:00
|
|
|
case SPE_ADDR_PKT_HDR_INDEX_INS:
|
|
|
|
case SPE_ADDR_PKT_HDR_INDEX_BRANCH:
|
2023-02-03 10:24:01 -06:00
|
|
|
case SPE_ADDR_PKT_HDR_INDEX_PREV_BRANCH:
|
2020-11-19 23:24:29 +08:00
|
|
|
ns = !!SPE_ADDR_PKT_GET_NS(payload);
|
|
|
|
el = SPE_ADDR_PKT_GET_EL(payload);
|
|
|
|
payload = SPE_ADDR_PKT_ADDR_GET_BYTES_0_6(payload);
|
2020-11-19 23:24:28 +08:00
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len,
|
|
|
|
"%s 0x%llx el%d ns=%d",
|
2023-02-03 10:24:01 -06:00
|
|
|
idx_name[idx], payload, el, ns);
|
2020-11-19 23:24:28 +08:00
|
|
|
break;
|
2020-11-19 23:24:29 +08:00
|
|
|
case SPE_ADDR_PKT_HDR_INDEX_DATA_VIRT:
|
2020-11-19 23:24:28 +08:00
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len,
|
|
|
|
"VA 0x%llx", payload);
|
|
|
|
break;
|
2020-11-19 23:24:29 +08:00
|
|
|
case SPE_ADDR_PKT_HDR_INDEX_DATA_PHYS:
|
|
|
|
ns = !!SPE_ADDR_PKT_GET_NS(payload);
|
2020-11-19 23:24:40 +08:00
|
|
|
ch = !!SPE_ADDR_PKT_GET_CH(payload);
|
|
|
|
pat = SPE_ADDR_PKT_GET_PAT(payload);
|
2020-11-19 23:24:29 +08:00
|
|
|
payload = SPE_ADDR_PKT_ADDR_GET_BYTES_0_6(payload);
|
2020-11-19 23:24:28 +08:00
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len,
|
2020-11-19 23:24:40 +08:00
|
|
|
"PA 0x%llx ns=%d ch=%d pat=%x",
|
|
|
|
payload, ns, ch, pat);
|
2020-11-19 23:24:28 +08:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
/* Unknown index */
|
|
|
|
err = -1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
2020-11-19 23:24:32 +08:00
|
|
|
static int arm_spe_pkt_desc_counter(const struct arm_spe_pkt *packet,
|
|
|
|
char *buf, size_t buf_len)
|
|
|
|
{
|
|
|
|
u64 payload = packet->payload;
|
|
|
|
const char *name = arm_spe_pkt_name(packet->type);
|
|
|
|
int err = 0;
|
|
|
|
|
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len, "%s %d ", name,
|
|
|
|
(unsigned short)payload);
|
|
|
|
|
|
|
|
switch (packet->index) {
|
2020-11-19 23:24:33 +08:00
|
|
|
case SPE_CNT_PKT_HDR_INDEX_TOTAL_LAT:
|
2020-11-19 23:24:32 +08:00
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len, "TOT");
|
|
|
|
break;
|
2020-11-19 23:24:33 +08:00
|
|
|
case SPE_CNT_PKT_HDR_INDEX_ISSUE_LAT:
|
2020-11-19 23:24:32 +08:00
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len, "ISSUE");
|
|
|
|
break;
|
2020-11-19 23:24:33 +08:00
|
|
|
case SPE_CNT_PKT_HDR_INDEX_TRANS_LAT:
|
2020-11-19 23:24:32 +08:00
|
|
|
arm_spe_pkt_out_string(&err, &buf, &buf_len, "XLAT");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
2018-01-14 13:28:50 -06:00
|
|
|
int arm_spe_pkt_desc(const struct arm_spe_pkt *packet, char *buf,
|
|
|
|
size_t buf_len)
|
|
|
|
{
|
2020-11-19 23:24:28 +08:00
|
|
|
int idx = packet->index;
|
2018-01-14 13:28:50 -06:00
|
|
|
unsigned long long payload = packet->payload;
|
|
|
|
const char *name = arm_spe_pkt_name(packet->type);
|
perf arm-spe: Refactor printing string to buffer
When outputs strings to the decoding buffer with function snprintf(),
SPE decoder needs to detects if any error returns from snprintf() and if
so needs to directly bail out. If snprintf() returns success, it needs
to update buffer pointer and reduce the buffer length so can continue to
output the next string into the consequent memory space.
This complex logics are spreading in the function arm_spe_pkt_desc() so
there has many duplicate codes for handling error detecting, increment
buffer pointer and decrement buffer size.
To avoid the duplicate code, this patch introduces a new helper function
arm_spe_pkt_out_string() which is used to wrap up the complex logics,
and it's used by the caller arm_spe_pkt_desc(). This patch moves the
variable 'blen' as the function's local variable so allows to remove
the unnecessary braces and improve the readability.
This patch simplifies the return value for arm_spe_pkt_desc(): '0' means
success and other values mean an error has occurred. To realize this,
it relies on arm_spe_pkt_out_string()'s parameter 'err', the 'err' is a
cumulative value, returns its final value if printing buffer is called
for one time or multiple times. Finally, the error is handled in a
central place, rather than directly bailing out in switch-cases, it
returns error at the end of arm_spe_pkt_desc().
This patch changes the caller arm_spe_dump() to respect the updated
return value semantics of arm_spe_pkt_desc().
Suggested-by: Dave Martin <Dave.Martin@arm.com>
Signed-off-by: Leo Yan <leo.yan@linaro.org>
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Dave Martin <Dave.Martin@arm.com>
Acked-by: Will Deacon <will@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Al Grant <Al.Grant@arm.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@arm.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: John Garry <john.garry@huawei.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Wei Li <liwei391@huawei.com>
Link: https://lore.kernel.org/r/20201119152441.6972-2-leo.yan@linaro.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2020-11-19 23:24:26 +08:00
|
|
|
char *buf_orig = buf;
|
|
|
|
size_t blen = buf_len;
|
|
|
|
int err = 0;
|
2018-01-14 13:28:50 -06:00
|
|
|
|
|
|
|
switch (packet->type) {
|
|
|
|
case ARM_SPE_BAD:
|
|
|
|
case ARM_SPE_PAD:
|
|
|
|
case ARM_SPE_END:
|
perf arm-spe: Refactor printing string to buffer
When outputs strings to the decoding buffer with function snprintf(),
SPE decoder needs to detects if any error returns from snprintf() and if
so needs to directly bail out. If snprintf() returns success, it needs
to update buffer pointer and reduce the buffer length so can continue to
output the next string into the consequent memory space.
This complex logics are spreading in the function arm_spe_pkt_desc() so
there has many duplicate codes for handling error detecting, increment
buffer pointer and decrement buffer size.
To avoid the duplicate code, this patch introduces a new helper function
arm_spe_pkt_out_string() which is used to wrap up the complex logics,
and it's used by the caller arm_spe_pkt_desc(). This patch moves the
variable 'blen' as the function's local variable so allows to remove
the unnecessary braces and improve the readability.
This patch simplifies the return value for arm_spe_pkt_desc(): '0' means
success and other values mean an error has occurred. To realize this,
it relies on arm_spe_pkt_out_string()'s parameter 'err', the 'err' is a
cumulative value, returns its final value if printing buffer is called
for one time or multiple times. Finally, the error is handled in a
central place, rather than directly bailing out in switch-cases, it
returns error at the end of arm_spe_pkt_desc().
This patch changes the caller arm_spe_dump() to respect the updated
return value semantics of arm_spe_pkt_desc().
Suggested-by: Dave Martin <Dave.Martin@arm.com>
Signed-off-by: Leo Yan <leo.yan@linaro.org>
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Dave Martin <Dave.Martin@arm.com>
Acked-by: Will Deacon <will@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Al Grant <Al.Grant@arm.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@arm.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: John Garry <john.garry@huawei.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Wei Li <liwei391@huawei.com>
Link: https://lore.kernel.org/r/20201119152441.6972-2-leo.yan@linaro.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2020-11-19 23:24:26 +08:00
|
|
|
arm_spe_pkt_out_string(&err, &buf, &blen, "%s", name);
|
|
|
|
break;
|
|
|
|
case ARM_SPE_EVENTS:
|
2020-11-19 23:24:34 +08:00
|
|
|
err = arm_spe_pkt_desc_event(packet, buf, buf_len);
|
perf arm-spe: Refactor printing string to buffer
When outputs strings to the decoding buffer with function snprintf(),
SPE decoder needs to detects if any error returns from snprintf() and if
so needs to directly bail out. If snprintf() returns success, it needs
to update buffer pointer and reduce the buffer length so can continue to
output the next string into the consequent memory space.
This complex logics are spreading in the function arm_spe_pkt_desc() so
there has many duplicate codes for handling error detecting, increment
buffer pointer and decrement buffer size.
To avoid the duplicate code, this patch introduces a new helper function
arm_spe_pkt_out_string() which is used to wrap up the complex logics,
and it's used by the caller arm_spe_pkt_desc(). This patch moves the
variable 'blen' as the function's local variable so allows to remove
the unnecessary braces and improve the readability.
This patch simplifies the return value for arm_spe_pkt_desc(): '0' means
success and other values mean an error has occurred. To realize this,
it relies on arm_spe_pkt_out_string()'s parameter 'err', the 'err' is a
cumulative value, returns its final value if printing buffer is called
for one time or multiple times. Finally, the error is handled in a
central place, rather than directly bailing out in switch-cases, it
returns error at the end of arm_spe_pkt_desc().
This patch changes the caller arm_spe_dump() to respect the updated
return value semantics of arm_spe_pkt_desc().
Suggested-by: Dave Martin <Dave.Martin@arm.com>
Signed-off-by: Leo Yan <leo.yan@linaro.org>
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Dave Martin <Dave.Martin@arm.com>
Acked-by: Will Deacon <will@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Al Grant <Al.Grant@arm.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@arm.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: John Garry <john.garry@huawei.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Wei Li <liwei391@huawei.com>
Link: https://lore.kernel.org/r/20201119152441.6972-2-leo.yan@linaro.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2020-11-19 23:24:26 +08:00
|
|
|
break;
|
2018-01-14 13:28:50 -06:00
|
|
|
case ARM_SPE_OP_TYPE:
|
2020-11-19 23:24:37 +08:00
|
|
|
err = arm_spe_pkt_desc_op_type(packet, buf, buf_len);
|
perf arm-spe: Refactor printing string to buffer
When outputs strings to the decoding buffer with function snprintf(),
SPE decoder needs to detects if any error returns from snprintf() and if
so needs to directly bail out. If snprintf() returns success, it needs
to update buffer pointer and reduce the buffer length so can continue to
output the next string into the consequent memory space.
This complex logics are spreading in the function arm_spe_pkt_desc() so
there has many duplicate codes for handling error detecting, increment
buffer pointer and decrement buffer size.
To avoid the duplicate code, this patch introduces a new helper function
arm_spe_pkt_out_string() which is used to wrap up the complex logics,
and it's used by the caller arm_spe_pkt_desc(). This patch moves the
variable 'blen' as the function's local variable so allows to remove
the unnecessary braces and improve the readability.
This patch simplifies the return value for arm_spe_pkt_desc(): '0' means
success and other values mean an error has occurred. To realize this,
it relies on arm_spe_pkt_out_string()'s parameter 'err', the 'err' is a
cumulative value, returns its final value if printing buffer is called
for one time or multiple times. Finally, the error is handled in a
central place, rather than directly bailing out in switch-cases, it
returns error at the end of arm_spe_pkt_desc().
This patch changes the caller arm_spe_dump() to respect the updated
return value semantics of arm_spe_pkt_desc().
Suggested-by: Dave Martin <Dave.Martin@arm.com>
Signed-off-by: Leo Yan <leo.yan@linaro.org>
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Dave Martin <Dave.Martin@arm.com>
Acked-by: Will Deacon <will@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Al Grant <Al.Grant@arm.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@arm.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: John Garry <john.garry@huawei.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Wei Li <liwei391@huawei.com>
Link: https://lore.kernel.org/r/20201119152441.6972-2-leo.yan@linaro.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2020-11-19 23:24:26 +08:00
|
|
|
break;
|
2018-01-14 13:28:50 -06:00
|
|
|
case ARM_SPE_DATA_SOURCE:
|
|
|
|
case ARM_SPE_TIMESTAMP:
|
perf arm-spe: Refactor printing string to buffer
When outputs strings to the decoding buffer with function snprintf(),
SPE decoder needs to detects if any error returns from snprintf() and if
so needs to directly bail out. If snprintf() returns success, it needs
to update buffer pointer and reduce the buffer length so can continue to
output the next string into the consequent memory space.
This complex logics are spreading in the function arm_spe_pkt_desc() so
there has many duplicate codes for handling error detecting, increment
buffer pointer and decrement buffer size.
To avoid the duplicate code, this patch introduces a new helper function
arm_spe_pkt_out_string() which is used to wrap up the complex logics,
and it's used by the caller arm_spe_pkt_desc(). This patch moves the
variable 'blen' as the function's local variable so allows to remove
the unnecessary braces and improve the readability.
This patch simplifies the return value for arm_spe_pkt_desc(): '0' means
success and other values mean an error has occurred. To realize this,
it relies on arm_spe_pkt_out_string()'s parameter 'err', the 'err' is a
cumulative value, returns its final value if printing buffer is called
for one time or multiple times. Finally, the error is handled in a
central place, rather than directly bailing out in switch-cases, it
returns error at the end of arm_spe_pkt_desc().
This patch changes the caller arm_spe_dump() to respect the updated
return value semantics of arm_spe_pkt_desc().
Suggested-by: Dave Martin <Dave.Martin@arm.com>
Signed-off-by: Leo Yan <leo.yan@linaro.org>
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Dave Martin <Dave.Martin@arm.com>
Acked-by: Will Deacon <will@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Al Grant <Al.Grant@arm.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@arm.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: John Garry <john.garry@huawei.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Wei Li <liwei391@huawei.com>
Link: https://lore.kernel.org/r/20201119152441.6972-2-leo.yan@linaro.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2020-11-19 23:24:26 +08:00
|
|
|
arm_spe_pkt_out_string(&err, &buf, &blen, "%s %lld", name, payload);
|
|
|
|
break;
|
2018-01-14 13:28:50 -06:00
|
|
|
case ARM_SPE_ADDRESS:
|
2020-11-19 23:24:28 +08:00
|
|
|
err = arm_spe_pkt_desc_addr(packet, buf, buf_len);
|
perf arm-spe: Refactor printing string to buffer
When outputs strings to the decoding buffer with function snprintf(),
SPE decoder needs to detects if any error returns from snprintf() and if
so needs to directly bail out. If snprintf() returns success, it needs
to update buffer pointer and reduce the buffer length so can continue to
output the next string into the consequent memory space.
This complex logics are spreading in the function arm_spe_pkt_desc() so
there has many duplicate codes for handling error detecting, increment
buffer pointer and decrement buffer size.
To avoid the duplicate code, this patch introduces a new helper function
arm_spe_pkt_out_string() which is used to wrap up the complex logics,
and it's used by the caller arm_spe_pkt_desc(). This patch moves the
variable 'blen' as the function's local variable so allows to remove
the unnecessary braces and improve the readability.
This patch simplifies the return value for arm_spe_pkt_desc(): '0' means
success and other values mean an error has occurred. To realize this,
it relies on arm_spe_pkt_out_string()'s parameter 'err', the 'err' is a
cumulative value, returns its final value if printing buffer is called
for one time or multiple times. Finally, the error is handled in a
central place, rather than directly bailing out in switch-cases, it
returns error at the end of arm_spe_pkt_desc().
This patch changes the caller arm_spe_dump() to respect the updated
return value semantics of arm_spe_pkt_desc().
Suggested-by: Dave Martin <Dave.Martin@arm.com>
Signed-off-by: Leo Yan <leo.yan@linaro.org>
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Dave Martin <Dave.Martin@arm.com>
Acked-by: Will Deacon <will@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Al Grant <Al.Grant@arm.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@arm.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: John Garry <john.garry@huawei.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Wei Li <liwei391@huawei.com>
Link: https://lore.kernel.org/r/20201119152441.6972-2-leo.yan@linaro.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2020-11-19 23:24:26 +08:00
|
|
|
break;
|
2018-01-14 13:28:50 -06:00
|
|
|
case ARM_SPE_CONTEXT:
|
perf arm-spe: Refactor printing string to buffer
When outputs strings to the decoding buffer with function snprintf(),
SPE decoder needs to detects if any error returns from snprintf() and if
so needs to directly bail out. If snprintf() returns success, it needs
to update buffer pointer and reduce the buffer length so can continue to
output the next string into the consequent memory space.
This complex logics are spreading in the function arm_spe_pkt_desc() so
there has many duplicate codes for handling error detecting, increment
buffer pointer and decrement buffer size.
To avoid the duplicate code, this patch introduces a new helper function
arm_spe_pkt_out_string() which is used to wrap up the complex logics,
and it's used by the caller arm_spe_pkt_desc(). This patch moves the
variable 'blen' as the function's local variable so allows to remove
the unnecessary braces and improve the readability.
This patch simplifies the return value for arm_spe_pkt_desc(): '0' means
success and other values mean an error has occurred. To realize this,
it relies on arm_spe_pkt_out_string()'s parameter 'err', the 'err' is a
cumulative value, returns its final value if printing buffer is called
for one time or multiple times. Finally, the error is handled in a
central place, rather than directly bailing out in switch-cases, it
returns error at the end of arm_spe_pkt_desc().
This patch changes the caller arm_spe_dump() to respect the updated
return value semantics of arm_spe_pkt_desc().
Suggested-by: Dave Martin <Dave.Martin@arm.com>
Signed-off-by: Leo Yan <leo.yan@linaro.org>
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Dave Martin <Dave.Martin@arm.com>
Acked-by: Will Deacon <will@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Al Grant <Al.Grant@arm.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@arm.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: John Garry <john.garry@huawei.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Wei Li <liwei391@huawei.com>
Link: https://lore.kernel.org/r/20201119152441.6972-2-leo.yan@linaro.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2020-11-19 23:24:26 +08:00
|
|
|
arm_spe_pkt_out_string(&err, &buf, &blen, "%s 0x%lx el%d",
|
|
|
|
name, (unsigned long)payload, idx + 1);
|
|
|
|
break;
|
|
|
|
case ARM_SPE_COUNTER:
|
2020-11-19 23:24:32 +08:00
|
|
|
err = arm_spe_pkt_desc_counter(packet, buf, buf_len);
|
perf arm-spe: Refactor printing string to buffer
When outputs strings to the decoding buffer with function snprintf(),
SPE decoder needs to detects if any error returns from snprintf() and if
so needs to directly bail out. If snprintf() returns success, it needs
to update buffer pointer and reduce the buffer length so can continue to
output the next string into the consequent memory space.
This complex logics are spreading in the function arm_spe_pkt_desc() so
there has many duplicate codes for handling error detecting, increment
buffer pointer and decrement buffer size.
To avoid the duplicate code, this patch introduces a new helper function
arm_spe_pkt_out_string() which is used to wrap up the complex logics,
and it's used by the caller arm_spe_pkt_desc(). This patch moves the
variable 'blen' as the function's local variable so allows to remove
the unnecessary braces and improve the readability.
This patch simplifies the return value for arm_spe_pkt_desc(): '0' means
success and other values mean an error has occurred. To realize this,
it relies on arm_spe_pkt_out_string()'s parameter 'err', the 'err' is a
cumulative value, returns its final value if printing buffer is called
for one time or multiple times. Finally, the error is handled in a
central place, rather than directly bailing out in switch-cases, it
returns error at the end of arm_spe_pkt_desc().
This patch changes the caller arm_spe_dump() to respect the updated
return value semantics of arm_spe_pkt_desc().
Suggested-by: Dave Martin <Dave.Martin@arm.com>
Signed-off-by: Leo Yan <leo.yan@linaro.org>
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Dave Martin <Dave.Martin@arm.com>
Acked-by: Will Deacon <will@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Al Grant <Al.Grant@arm.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@arm.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: John Garry <john.garry@huawei.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Wei Li <liwei391@huawei.com>
Link: https://lore.kernel.org/r/20201119152441.6972-2-leo.yan@linaro.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2020-11-19 23:24:26 +08:00
|
|
|
break;
|
2018-01-14 13:28:50 -06:00
|
|
|
default:
|
perf arm-spe: Refactor printing string to buffer
When outputs strings to the decoding buffer with function snprintf(),
SPE decoder needs to detects if any error returns from snprintf() and if
so needs to directly bail out. If snprintf() returns success, it needs
to update buffer pointer and reduce the buffer length so can continue to
output the next string into the consequent memory space.
This complex logics are spreading in the function arm_spe_pkt_desc() so
there has many duplicate codes for handling error detecting, increment
buffer pointer and decrement buffer size.
To avoid the duplicate code, this patch introduces a new helper function
arm_spe_pkt_out_string() which is used to wrap up the complex logics,
and it's used by the caller arm_spe_pkt_desc(). This patch moves the
variable 'blen' as the function's local variable so allows to remove
the unnecessary braces and improve the readability.
This patch simplifies the return value for arm_spe_pkt_desc(): '0' means
success and other values mean an error has occurred. To realize this,
it relies on arm_spe_pkt_out_string()'s parameter 'err', the 'err' is a
cumulative value, returns its final value if printing buffer is called
for one time or multiple times. Finally, the error is handled in a
central place, rather than directly bailing out in switch-cases, it
returns error at the end of arm_spe_pkt_desc().
This patch changes the caller arm_spe_dump() to respect the updated
return value semantics of arm_spe_pkt_desc().
Suggested-by: Dave Martin <Dave.Martin@arm.com>
Signed-off-by: Leo Yan <leo.yan@linaro.org>
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Dave Martin <Dave.Martin@arm.com>
Acked-by: Will Deacon <will@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Al Grant <Al.Grant@arm.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@arm.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: John Garry <john.garry@huawei.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Wei Li <liwei391@huawei.com>
Link: https://lore.kernel.org/r/20201119152441.6972-2-leo.yan@linaro.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2020-11-19 23:24:26 +08:00
|
|
|
/* Unknown packet type */
|
|
|
|
err = -1;
|
2018-01-14 13:28:50 -06:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
perf arm-spe: Refactor printing string to buffer
When outputs strings to the decoding buffer with function snprintf(),
SPE decoder needs to detects if any error returns from snprintf() and if
so needs to directly bail out. If snprintf() returns success, it needs
to update buffer pointer and reduce the buffer length so can continue to
output the next string into the consequent memory space.
This complex logics are spreading in the function arm_spe_pkt_desc() so
there has many duplicate codes for handling error detecting, increment
buffer pointer and decrement buffer size.
To avoid the duplicate code, this patch introduces a new helper function
arm_spe_pkt_out_string() which is used to wrap up the complex logics,
and it's used by the caller arm_spe_pkt_desc(). This patch moves the
variable 'blen' as the function's local variable so allows to remove
the unnecessary braces and improve the readability.
This patch simplifies the return value for arm_spe_pkt_desc(): '0' means
success and other values mean an error has occurred. To realize this,
it relies on arm_spe_pkt_out_string()'s parameter 'err', the 'err' is a
cumulative value, returns its final value if printing buffer is called
for one time or multiple times. Finally, the error is handled in a
central place, rather than directly bailing out in switch-cases, it
returns error at the end of arm_spe_pkt_desc().
This patch changes the caller arm_spe_dump() to respect the updated
return value semantics of arm_spe_pkt_desc().
Suggested-by: Dave Martin <Dave.Martin@arm.com>
Signed-off-by: Leo Yan <leo.yan@linaro.org>
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Dave Martin <Dave.Martin@arm.com>
Acked-by: Will Deacon <will@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Al Grant <Al.Grant@arm.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@arm.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: John Garry <john.garry@huawei.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Wei Li <liwei391@huawei.com>
Link: https://lore.kernel.org/r/20201119152441.6972-2-leo.yan@linaro.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2020-11-19 23:24:26 +08:00
|
|
|
/* Output raw data if detect any error */
|
|
|
|
if (err) {
|
|
|
|
err = 0;
|
|
|
|
arm_spe_pkt_out_string(&err, &buf_orig, &buf_len, "%s 0x%llx (%d)",
|
|
|
|
name, payload, packet->index);
|
|
|
|
}
|
|
|
|
|
|
|
|
return err;
|
2018-01-14 13:28:50 -06:00
|
|
|
}
|