mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-08 06:58:05 +02:00
pan/kmod: Implement panfrost kmod perf counter methods
This is mostly a copy of the logic from pan_perf.c and hooking it up to the kmod api.
This commit is contained in:
parent
dcc0dc10d7
commit
901dd8dc6c
1 changed files with 110 additions and 0 deletions
|
|
@ -42,6 +42,10 @@ struct panfrost_kmod_bo {
|
|||
uint64_t offset;
|
||||
};
|
||||
|
||||
struct panfrost_kmod_perf_session {
|
||||
struct pan_kmod_perf_session base;
|
||||
};
|
||||
|
||||
/* Abstraction over the raw drm_panfrost_get_param ioctl for fetching
|
||||
* information about devices.
|
||||
*/
|
||||
|
|
@ -607,6 +611,106 @@ panfrost_kmod_bo_label(struct pan_kmod_dev *dev, struct pan_kmod_bo *bo, const c
|
|||
mesa_loge("DRM_IOCTL_PANFROST_SET_LABEL_BO failed (err=%d)", errno);
|
||||
}
|
||||
|
||||
static inline struct pan_kmod_perf_session *
|
||||
panfrost_kmod_perf_init(struct pan_kmod_dev *dev)
|
||||
{
|
||||
UNUSED struct panfrost_kmod_dev *panfrost_dev =
|
||||
container_of(dev, struct panfrost_kmod_dev, base);
|
||||
|
||||
struct panfrost_kmod_perf_session *sess =
|
||||
pan_kmod_dev_alloc(dev, sizeof(*sess));
|
||||
if (!sess) {
|
||||
mesa_loge("failed to allocate a panfrost_kmod_perf_session object");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sess->base.dev = dev;
|
||||
|
||||
struct pan_kmod_perf_buffer_layout layout;
|
||||
pan_kmod_perf_query_layout(&sess->base, &layout);
|
||||
|
||||
uint32_t n_counters = 0;
|
||||
for (uint32_t cat = 0; cat < PAN_KMOD_PERF_CAT_COUNT; ++cat)
|
||||
n_counters += layout.category[cat].n_blocks * layout.counters_per_category;
|
||||
|
||||
uint32_t* counter_values = pan_kmod_dev_alloc(dev, sizeof(uint32_t) * n_counters);
|
||||
sess->base.data = counter_values;
|
||||
sess->base.data_ts_supported = false;
|
||||
|
||||
mesa_logd("perf session created");
|
||||
|
||||
return &(sess->base);
|
||||
}
|
||||
|
||||
static int
|
||||
panfrost_kmod_perf_query(struct pan_kmod_perf_session *session, uint32_t enable)
|
||||
{
|
||||
struct drm_panfrost_perfcnt_enable perfcnt_enable = {enable, 0};
|
||||
return pan_kmod_ioctl(session->dev->fd, DRM_IOCTL_PANFROST_PERFCNT_ENABLE,
|
||||
&perfcnt_enable);
|
||||
}
|
||||
|
||||
static int
|
||||
panfrost_kmod_perf_enable(struct pan_kmod_perf_session *session)
|
||||
{
|
||||
return panfrost_kmod_perf_query(session, 1 /* enable */);
|
||||
}
|
||||
|
||||
static int
|
||||
panfrost_kmod_perf_disable(struct pan_kmod_perf_session *session)
|
||||
{
|
||||
return panfrost_kmod_perf_query(session, 0 /* disable */);
|
||||
}
|
||||
|
||||
static int
|
||||
panfrost_kmod_perf_dump(struct pan_kmod_perf_session *session)
|
||||
{
|
||||
struct drm_panfrost_perfcnt_dump perfcnt_dump = {
|
||||
(uint64_t)(uintptr_t)session->data};
|
||||
return pan_kmod_ioctl(session->dev->fd, DRM_IOCTL_PANFROST_PERFCNT_DUMP,
|
||||
&perfcnt_dump);
|
||||
}
|
||||
|
||||
static void
|
||||
panfrost_kmod_perf_query_layout(const struct pan_kmod_perf_session *session,
|
||||
struct pan_kmod_perf_buffer_layout *layout)
|
||||
{
|
||||
/* Generally counter blocks are laid out in the following order:
|
||||
* Job manager, tiler, one or more L2 caches, and one or more shader cores.
|
||||
*/
|
||||
unsigned l2_slices = pan_query_l2_slices(&session->dev->props);
|
||||
unsigned core_id_range;
|
||||
pan_query_core_count(&session->dev->props, &core_id_range);
|
||||
|
||||
/* On all Bifrost architectures this is 64. */
|
||||
const unsigned counters_per_cat = 64;
|
||||
layout->counters_per_category = counters_per_cat;
|
||||
layout->counter_stride = sizeof(uint32_t);
|
||||
layout->block_stride = counters_per_cat * sizeof(uint32_t);
|
||||
|
||||
/* Setup the layout */
|
||||
layout->category[PAN_KMOD_PERF_CAT_FRONTEND].n_blocks = 1;
|
||||
layout->category[PAN_KMOD_PERF_CAT_TILER].n_blocks = 1;
|
||||
layout->category[PAN_KMOD_PERF_CAT_MEMSYS].n_blocks = l2_slices;
|
||||
layout->category[PAN_KMOD_PERF_CAT_SHADER].n_blocks = core_id_range;
|
||||
|
||||
layout->category[0].offset = 0;
|
||||
for (unsigned cat_idx = 1; cat_idx < PAN_KMOD_PERF_CAT_COUNT; ++cat_idx) {
|
||||
layout->category[cat_idx].offset =
|
||||
layout->category[cat_idx - 1].offset +
|
||||
layout->category[cat_idx - 1].n_blocks * counters_per_cat;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
panfrost_kmod_perf_destroy(struct pan_kmod_perf_session *session)
|
||||
{
|
||||
if (session->data)
|
||||
pan_kmod_dev_free(session->dev, session->data);
|
||||
pan_kmod_dev_free(session->dev, session);
|
||||
mesa_logd("perf session destroyed");
|
||||
}
|
||||
|
||||
const struct pan_kmod_ops panfrost_kmod_ops = {
|
||||
.dev_create = panfrost_kmod_dev_create,
|
||||
.dev_destroy = panfrost_kmod_dev_destroy,
|
||||
|
|
@ -624,4 +728,10 @@ const struct pan_kmod_ops panfrost_kmod_ops = {
|
|||
.vm_bind = panfrost_kmod_vm_bind,
|
||||
.query_timestamp = panfrost_kmod_query_timestamp,
|
||||
.bo_set_label = panfrost_kmod_bo_label,
|
||||
.perf_create = panfrost_kmod_perf_init,
|
||||
.perf_enable = panfrost_kmod_perf_enable,
|
||||
.perf_disable = panfrost_kmod_perf_disable,
|
||||
.perf_dump = panfrost_kmod_perf_dump,
|
||||
.perf_query_layout = panfrost_kmod_perf_query_layout,
|
||||
.perf_destroy = panfrost_kmod_perf_destroy,
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue