From 722dd942c4814261c9ae4487172e36e72d0778b7 Mon Sep 17 00:00:00 2001 From: Ricardo Pardini Date: Tue, 14 Jul 2026 20:46:03 +0200 Subject: [PATCH] video: rockchip: mpp: report zero load for idle devices The per-device statistics shown in /proc/mpp_service/load are only ever recomputed inside mpp_dev_load(), which is called exclusively from the task-completion paths (mpp_common.c task worker and the rkvdec2 link/ccu workers). Within that function the load and utilization figures are only refreshed when a task finishes *and* at least one load_interval has elapsed; the result is stored in mpp->load_info and reset for the next window. There is no timer, runtime-PM hook, or reader-side logic that ages the value out, so mpp->load_info.load is a snapshot of the last completed interval, not a live measurement. As a consequence, once a device stops receiving tasks its stored load is never updated again and /proc/mpp_service/load keeps reporting the last busy interval indefinitely (until load_interval is toggled, which clears the stats via mpp_dev_load_clear()). This is most visible on the standalone AV1 decoder (fdc70000.av1d). It is driven one task at a time by the default worker, so when playback stops the final frame's completion is genuinely the last event that will ever call mpp_dev_load() for that core, and its load freezes at the busy value. Multi-core rkvdec2 decoders in link/ccu mode keep draining their queued task list after playback ends, which happens to log a further, near-idle interval and pulls the figure back down, so the staleness goes unnoticed there. The underlying defect is common to every device. Rather than introduce a periodic recompute (a per-core timer with the associated runtime-PM interactions), detect the idle case in the reader. A device whose load_info has not been updated for more than one full load_interval has, by definition, completed no task in that window and is idle; report zero for it instead of the stale snapshot. Devices that never started load tracking (!load_en) are likewise reported as zero. Signed-off-by: Ricardo Pardini Co-Authored-By: Claude Opus 4.8 --- drivers/video/rockchip/mpp/mpp_service.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/drivers/video/rockchip/mpp/mpp_service.c b/drivers/video/rockchip/mpp/mpp_service.c index 882002e20097b..73cbc46452f5c 100644 --- a/drivers/video/rockchip/mpp/mpp_service.c +++ b/drivers/video/rockchip/mpp/mpp_service.c @@ -329,13 +329,33 @@ static int mpp_show_device_load(struct seq_file *file, void *v) for (j = 0; j < MPP_MAX_CORE_NUM; j++) { struct mpp_dev *mpp = queue->cores[j]; + struct mpp_load_info *load_info; + u32 load, load_frac, util, util_frac; if (!mpp) continue; + + load_info = &mpp->load_info; + load = load_info->load; + load_frac = load_info->load_frac; + util = load_info->utilization; + util_frac = load_info->utilization_frac; + + /* + * load_info is only refreshed by mpp_dev_load() on task + * completion, so an idle device keeps reporting the last + * busy interval forever. If no task has updated the stats + * for more than one load_interval, the device has gone + * idle: report zero instead of the stale snapshot. + */ + if (!mpp->load_en || + ktime_us_delta(ktime_get(), load_info->load_time) > + (s64)srv->load_interval * 1000 * 2) + load = load_frac = util = util_frac = 0; + seq_printf(file, "%-25s load: %3d.%02d%% utilization: %3d.%02d%%\n", dev_name(mpp->dev), - mpp->load_info.load, mpp->load_info.load_frac, - mpp->load_info.utilization, mpp->load_info.utilization_frac); + load, load_frac, util, util_frac); } }