mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-08 06:58:05 +02:00
pan/kmod: Add perf counter api
The kernel module is responsible for starting/stopping the counter collection. It decides the layout of the counters in memory. The commit adds an API to reflect this. The counter collection can be started and stopped through the kmod. Counters are dumped into a buffer also provided by the kmod. This is so that later for panthor the buffer can be an mmapped bo. It also allows for having a larger buffer where multiple samples are located internally but pointing data at the most recent one. The memory layout of whatever the data pointer points to can be queried so that the counters can be extracted from it without going through the kmod vtable.
This commit is contained in:
parent
dfca417db8
commit
dcc0dc10d7
1 changed files with 127 additions and 0 deletions
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright © 2023 Collabora, Ltd.
|
||||
* Copyright © 2026 Arm Ltd.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
|
|
@ -37,6 +38,7 @@
|
|||
#include "util/u_dynarray.h"
|
||||
|
||||
#include "kmod/panthor_kmod.h"
|
||||
#include "pan_props.h"
|
||||
#include "pan_trace.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
|
|
@ -384,6 +386,54 @@ struct pan_kmod_va_range {
|
|||
uint64_t size;
|
||||
};
|
||||
|
||||
struct pan_kmod_perf_session {
|
||||
/* Device this perf session was created from. */
|
||||
struct pan_kmod_dev *dev;
|
||||
|
||||
/* Sample data pointer. */
|
||||
void* data;
|
||||
|
||||
/* If pan_kmod_perf_session::data_ts is supported. */
|
||||
bool data_ts_supported;
|
||||
|
||||
/* The timestamp of the sample data. */
|
||||
uint64_t data_ts;
|
||||
};
|
||||
|
||||
enum pan_kmod_perf_category {
|
||||
PAN_KMOD_PERF_CAT_FRONTEND,
|
||||
PAN_KMOD_PERF_CAT_TILER,
|
||||
PAN_KMOD_PERF_CAT_MEMSYS,
|
||||
PAN_KMOD_PERF_CAT_SHADER,
|
||||
/* Must be last. */
|
||||
PAN_KMOD_PERF_CAT_COUNT,
|
||||
};
|
||||
|
||||
/* Describes the memory layout of a buffer containing performance counters.
|
||||
* The buffer is structured like this:
|
||||
* sample {
|
||||
* header
|
||||
* categories [ category {
|
||||
* blocks [ block {
|
||||
* header
|
||||
* samples
|
||||
* }]
|
||||
* }]
|
||||
* }
|
||||
*/
|
||||
struct pan_kmod_perf_buffer_layout {
|
||||
struct {
|
||||
/* Offset from the start of the buffer in bytes. */
|
||||
uint32_t offset;
|
||||
/* Number of blocks for this category. */
|
||||
uint8_t n_blocks;
|
||||
} category[PAN_KMOD_PERF_CAT_COUNT];
|
||||
|
||||
uint32_t block_stride;
|
||||
uint32_t counter_stride;
|
||||
uint32_t counters_per_category;
|
||||
};
|
||||
|
||||
/* KMD backend vtable.
|
||||
*
|
||||
* All methods described there are mandatory, unless explicitly flagged as
|
||||
|
|
@ -474,6 +524,25 @@ struct pan_kmod_ops {
|
|||
|
||||
/* Label the BO */
|
||||
void (*bo_set_label)(struct pan_kmod_dev *dev, struct pan_kmod_bo *bo, const char *label);
|
||||
|
||||
/* Initialize a perf session. */
|
||||
struct pan_kmod_perf_session *(*perf_create)(struct pan_kmod_dev *dev);
|
||||
|
||||
/* Enable perf counters. */
|
||||
int (*perf_enable)(struct pan_kmod_perf_session *session);
|
||||
|
||||
/* Disable perf counters. */
|
||||
int (*perf_disable)(struct pan_kmod_perf_session *session);
|
||||
|
||||
/* Dump collected perf counters. */
|
||||
int (*perf_dump)(struct pan_kmod_perf_session *session);
|
||||
|
||||
/* Destroy a perf session. */
|
||||
void (*perf_destroy)(struct pan_kmod_perf_session *session);
|
||||
|
||||
/* Query the memory layout for a counter buffer. */
|
||||
void (*perf_query_layout)(const struct pan_kmod_perf_session *session,
|
||||
struct pan_kmod_perf_buffer_layout *layout);
|
||||
};
|
||||
|
||||
/* KMD information. */
|
||||
|
|
@ -783,6 +852,64 @@ pan_kmod_query_timestamp(const struct pan_kmod_dev *dev)
|
|||
return dev->ops->query_timestamp(dev);
|
||||
}
|
||||
|
||||
static inline struct pan_kmod_perf_session *
|
||||
pan_kmod_perf_create(struct pan_kmod_dev *dev)
|
||||
{
|
||||
return dev->ops->perf_create(dev);
|
||||
}
|
||||
|
||||
static inline int
|
||||
pan_kmod_perf_enable(struct pan_kmod_perf_session *session)
|
||||
{
|
||||
return session->dev->ops->perf_enable(session);
|
||||
}
|
||||
|
||||
static inline int
|
||||
pan_kmod_perf_disable(struct pan_kmod_perf_session *session)
|
||||
{
|
||||
return session->dev->ops->perf_disable(session);
|
||||
}
|
||||
|
||||
static inline int
|
||||
pan_kmod_perf_dump(struct pan_kmod_perf_session *session)
|
||||
{
|
||||
return session->dev->ops->perf_dump(session);
|
||||
}
|
||||
|
||||
static inline void
|
||||
pan_kmod_perf_destroy(struct pan_kmod_perf_session *session)
|
||||
{
|
||||
session->dev->ops->perf_destroy(session);
|
||||
}
|
||||
|
||||
static inline void
|
||||
pan_kmod_perf_query_layout(const struct pan_kmod_perf_session *session,
|
||||
struct pan_kmod_perf_buffer_layout *layout)
|
||||
{
|
||||
session->dev->ops->perf_query_layout(session, layout);
|
||||
}
|
||||
|
||||
/* Load a counter value from the given address. */
|
||||
static inline int64_t
|
||||
pan_kmod_perf_load_counter(const struct pan_kmod_perf_session *session,
|
||||
const void *ptr)
|
||||
{
|
||||
if (pan_arch(session->dev->props.gpu_id) < 10)
|
||||
return *((const uint32_t*)ptr);
|
||||
else {
|
||||
const uint64_t val = *((const uint64_t*)ptr);
|
||||
#ifndef NDEBUG
|
||||
/*
|
||||
* Even though the uAPI permits 64-bit unsigned counters, the counter
|
||||
* values realistically never exceed INT64_MAX.
|
||||
*/
|
||||
return (val > INT64_MAX) ? -EINVAL : val;
|
||||
#else
|
||||
return val;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue