[PATCH i-g-t v2 15/21] lib/igt_drm_clients: Record total cycles
Tvrtko Ursulin
tursulin at ursulin.net
Fri Apr 26 11:11:33 UTC 2024
On 24/04/2024 00:44, Lucas De Marchi wrote:
> If the fdinfo data indicates there's drm-total-cycles, use it to
> propagate the engine utilization. Also add an assert in intel_gpu_top
> since it only knows how to deal with with engine time busyness.
>
> Signed-off-by: Lucas De Marchi <lucas.demarchi at intel.com>
> ---
> lib/igt_drm_clients.c | 47 +++++++++++++++++++++++++++++++++++--------
> lib/igt_drm_clients.h | 7 +++++--
> lib/igt_drm_fdinfo.c | 2 ++
> tools/intel_gpu_top.c | 1 +
> 4 files changed, 47 insertions(+), 10 deletions(-)
>
> diff --git a/lib/igt_drm_clients.c b/lib/igt_drm_clients.c
> index 71a938b18..8b1959ae1 100644
> --- a/lib/igt_drm_clients.c
> +++ b/lib/igt_drm_clients.c
> @@ -106,16 +106,41 @@ igt_drm_client_update(struct igt_drm_client *c, unsigned int pid, char *name,
> c->last_runtime = 0;
> c->total_runtime = 0;
>
> + /*
> + * Make sure utilization type doesn't change between any 2 samples,
> + * otherwise the units don't match
> + */
> + assert(c->dcut | info->dcut);
> +
> for (i = 0; i <= c->engines->max_engine_id; i++) {
> assert(i < ARRAY_SIZE(info->busy));
> -
> - if (info->busy[i] < c->u[i].last_busy)
> - continue; /* It will catch up soon. */
> -
> - c->total_runtime += info->busy[i];
> - c->u[i].delta_busy = info->busy[i] - c->u[i].last_busy;
> - c->last_runtime += c->u[i].delta_busy;
> - c->u[i].last_busy = info->busy[i];
> + assert(i < ARRAY_SIZE(info->cycles));
> + assert(i < ARRAY_SIZE(info->total_cycles));
> +
> + switch (c->dcut) {
> + case DCUT_ENGINE_TIME:
> + if (info->busy[i] < c->u[i].last_busy)
> + continue; /* It will catch up soon. */
> +
> + c->total_runtime += info->busy[i];
> + c->u[i].delta_busy = info->busy[i] - c->u[i].last_busy;
> + c->last_runtime += c->u[i].delta_busy;
> + c->u[i].last_busy = info->busy[i];
> + break;
> + case DCUT_GPU_TOTAL_CYCLES:
> + if (info->cycles[i] < c->u[i].last_busy)
> + continue; /* It will catch up soon. */
> +
> + c->total_runtime += info->cycles[i];
> + c->u[i].delta_busy = info->cycles[i] - c->u[i].last_busy;
> + c->last_runtime += c->u[i].delta_busy;
> + c->u[i].last_busy = info->cycles[i];
> +
> + c->u[i].delta_total_cycles = info->total_cycles[i]
> + - c->u[i].last_total_cycles;
> + c->u[i].last_total_cycles = info->total_cycles[i];
> + break;
> + }
> }
>
> /* Memory regions */
> @@ -207,6 +232,12 @@ igt_drm_client_add(struct igt_drm_clients *clients,
> c->memory = calloc(c->regions->max_region_id + 1, sizeof(*c->memory));
> assert(c->memory);
>
> + /* Prefer using GPU_TOTAL_CYCLES if available */
> + if (info->dcut & DCUT_GPU_TOTAL_CYCLES)
> + c->dcut = DCUT_GPU_TOTAL_CYCLES;
> + else
> + c->dcut = DCUT_ENGINE_TIME;
Hmm I have a feeling igt_drm_client shouldn't be making this decision
but just tracking all available keys.
As such I would suggest making these flags instead of types.
(And with "dcut" naming spreading now I really think it is too obscure
to stay.)
Something like:
if (info->utilisation_type & DRM_FDINFO_UTILISATION_TOTAL_CYCLES)
c->utilisation_type |= DRM_CLIENT_TOTAL_CYCLES;
if (info->utilisation_type & DRM_FDINFO_UTILISATION_TIME)
c->utilisation_type |= DRM_CLIENT_ENGINE_TIME;
Intel_gpu_top and gputop then pick when they know to work with, with the
priority the application chooses.
Regards,
Tvrtko
> +
> igt_drm_client_update(c, pid, name, info);
> }
>
> diff --git a/lib/igt_drm_clients.h b/lib/igt_drm_clients.h
> index 5c6130ff1..5ab6f6e2e 100644
> --- a/lib/igt_drm_clients.h
> +++ b/lib/igt_drm_clients.h
> @@ -65,9 +65,12 @@ struct igt_drm_client {
> unsigned int samples; /* Count of times scanning updated this client. */
> unsigned long total_runtime; /* Aggregate busyness on all engines since client start. */
> unsigned long last_runtime; /* Aggregate busyness on all engines since previous scan. */
> + enum drm_client_utilization_type dcut; /* Select method to calculate engine utiliazation */
> struct igt_drm_client_utilization {
> - unsigned long delta_busy; /* Engine busyness data, relative to previous scan. */
> - uint64_t last_busy; /* Engine busyness data as parsed from fdinfo. */
> + unsigned long delta_busy; /* Engine busyness (either drm-cycles or drm-engine data), relative to previous scan. */
> + unsigned long delta_total_cycles; /* Total engine cycles, relative to previous scan. */
> + uint64_t last_busy; /* Engine busyness (either drm-cycles or drm-engine data) as parsed from fdinfo. */
> + uint64_t last_total_cycles; /* Total engin cycles as parsed from fdinfo */
> } *u; /* Array of engine utilization */
> struct drm_client_meminfo *memory; /* Array of region memory utilisation as parsed from fdinfo. */
> };
> diff --git a/lib/igt_drm_fdinfo.c b/lib/igt_drm_fdinfo.c
> index 7a1485c66..292c7e4d8 100644
> --- a/lib/igt_drm_fdinfo.c
> +++ b/lib/igt_drm_fdinfo.c
> @@ -270,10 +270,12 @@ __igt_parse_drm_fdinfo(int dir, const char *fd, struct drm_client_fdinfo *info,
> idx = parse_engine(l + keylen, info,
> name_map, map_entries, &val);
> UPDATE_ENGINE(idx, cycles, val);
> + has_cycles = true;
> } else if (strstartswith(l, "drm-total-cycles-", &keylen)) {
> idx = parse_engine(l + keylen, info,
> name_map, map_entries, &val);
> UPDATE_ENGINE(idx, total_cycles, val);
> + has_total_cycles = true;
> } else if (strstartswith(l, "drm-total-", &keylen)) {
> idx = parse_region(l + keylen, info,
> region_map, region_entries, &val);
> diff --git a/tools/intel_gpu_top.c b/tools/intel_gpu_top.c
> index a4aa8414b..abbc30006 100644
> --- a/tools/intel_gpu_top.c
> +++ b/tools/intel_gpu_top.c
> @@ -880,6 +880,7 @@ static struct igt_drm_clients *display_clients(struct igt_drm_clients *clients)
> break;
>
> assert(c->status == IGT_DRM_CLIENT_ALIVE);
> + assert(c->dcut == DCUT_ENGINE_TIME);
>
> if (!cp || c->pid != cp->pid) {
> ac = &aggregated->client[num++];
More information about the igt-dev
mailing list