From 4a1475142b6a1b48d8bd051a7d1d49a4f8ffd2d0 Mon Sep 17 00:00:00 2001 From: Rocker Zhang Date: Fri, 5 Jun 2026 15:28:47 +0800 Subject: [PATCH] Avoid division by zero and clock overflow in utilisation rate gpuinfo_refresh_utilisation_rate() derives GPU usage from drm-cycles and drm-maxfreq and is used by the panfrost and panthor backends. When a backend does not report drm-maxfreq, gpu_clock_speed_max stays 0, so max_freq_hz is 0 and the rate division has a zero denominator. The double division yields infinity and casting that to unsigned int is undefined behaviour. A zero sample delta or a reported engine_count of 0 produce the same zero denominator. Return early when the denominator would be zero, leaving gpu_util_rate unset so the UI shows N/A, matching the existing early return for a zero cycle count. gpu_clock_speed_max (MHz, unsigned int) was also multiplied by 1000000 in unsigned int arithmetic before being widened to the uint64_t max_freq_hz, which overflows above ~4295 MHz. Cast to uint64_t before multiplying. --- src/extract_gpuinfo.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/extract_gpuinfo.c b/src/extract_gpuinfo.c index 8e64bf93..f0f62ddf 100644 --- a/src/extract_gpuinfo.c +++ b/src/extract_gpuinfo.c @@ -399,7 +399,12 @@ void gpuinfo_refresh_utilisation_rate(struct gpu_info *gpu_info) { ec = 1; avg_delta_secs = ((double)total_delta / gpu_info->processes_count) / 1000000000.0; - max_freq_hz = gpu_info->dynamic_info.gpu_clock_speed_max * 1000000; + max_freq_hz = (uint64_t)gpu_info->dynamic_info.gpu_clock_speed_max * 1000000; + // Without a known maximum frequency or a positive time delta the utilisation + // cannot be derived; bail out instead of dividing by zero (which yields an + // infinite rate and undefined behaviour when cast to unsigned). + if (max_freq_hz == 0 || avg_delta_secs == 0.0 || ec == 0) + return; utilisation_rate = (unsigned int)((((double)gfx_total_process_cycles) / (((double)max_freq_hz) * avg_delta_secs * ec)) * 100); utilisation_rate = utilisation_rate > 100 ? 100 : utilisation_rate;