--- /dev/null
+From d8e53e0b83c947123c38c81d2fb5162c86d26fb5 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Thu, 4 Jan 2024 12:39:33 +0000
+Subject: [PATCH 1247/1295] drm/vc4: Optimise vc4_hvs_dlist_free_work to only
+ read frcnt and active once
+
+vc4_hvs_dlist_free_work was iterating through the list of stale
+dlist entries and reading the frame count and active flags from
+the hardware for each one.
+
+Read the frame count and active flags once, and then use the
+cached value in the loop.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ drivers/gpu/drm/vc4/vc4_hvs.c | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_hvs.c
++++ b/drivers/gpu/drm/vc4/vc4_hvs.c
+@@ -796,14 +796,19 @@ static void vc4_hvs_dlist_free_work(stru
+ struct vc4_hvs *hvs = container_of(work, struct vc4_hvs, free_dlist_work);
+ struct vc4_hvs_dlist_allocation *cur, *next;
+ unsigned long flags;
++ bool active[3];
++ u8 frcnt[3];
++ int i;
++
+
+ spin_lock_irqsave(&hvs->mm_lock, flags);
++ for (i = 0; i < 3; i++) {
++ frcnt[i] = vc4_hvs_get_fifo_frame_count(hvs, i);
++ active[i] = vc4_hvs_check_channel_active(hvs, i);
++ }
+ list_for_each_entry_safe(cur, next, &hvs->stale_dlist_entries, node) {
+- u8 frcnt;
+-
+- frcnt = vc4_hvs_get_fifo_frame_count(hvs, cur->channel);
+- if (vc4_hvs_check_channel_active(hvs, cur->channel) &&
+- !vc4_hvs_frcnt_lte(cur->target_frame_count, frcnt))
++ if (active[cur->channel] &&
++ !vc4_hvs_frcnt_lte(cur->target_frame_count, frcnt[cur->channel]))
+ continue;
+
+ vc4_hvs_free_dlist_entry_locked(hvs, cur);