Re: [PATCH v2] drm/radeon: restore hardware polling in fence_is_signaled to fix performance regression
Christian König <[email protected]> Wed, 5 Aug 2026 13:43:06 +0200
| Newsgroups | gmane.comp.freedesktop.amd-gfx,gmane.comp.video.dri.devel,gmane.linux.kernel |
|---|---|
| Message-ID | <[email protected]> |
On 7/30/26 03:56, [email protected] wrote: > From: Wang Jiang <jiangwang-UOlijcLmZ/[email protected]> > > Commit 9eb00b5f5697b ("drm/radeon: delete radeon_fence_process in > is_signaled, no deadlock") removed the hardware status check from > radeon_fence_is_signaled() to fix a self-deadlock caused by > wake_up_all(&rdev->fence_queue) being called with the fence queue > lock held. > > However, removing the hardware poll entirely causes significant > performance regression (e.g. glxgears FPS drop) because the signaled > check becomes purely passive — it only reads the cached last_seq > without probing the GPU, so completed GPU work is not detected in > time, causing unnecessary CPU stalls in sync-heavy workloads. > > Fix this by calling radeon_fence_read() directly in > radeon_fence_is_signaled() to poll the hardware fence counter > without updating last_seq or calling wake_up_all(). This restores > timely fence detection while avoiding the original deadlock, since > last_seq update and waiter wakeup remain solely in the interrupt > handler's responsibility. > > Fixes: 9eb00b5f5697b ("drm/radeon: delete radeon_fence_process in is_signaled, no deadlock") > Signed-off-by: Wang Jiang <jiangwang-UOlijcLmZ/[email protected]> > --- > drivers/gpu/drm/radeon/radeon_fence.c | 12 ++++++++++++ > 1 file changed, 12 insertions(+) > > diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c > index 02a40e4750c7..047ec5a1d194 100644 > --- a/drivers/gpu/drm/radeon/radeon_fence.c > +++ b/drivers/gpu/drm/radeon/radeon_fence.c > @@ -360,6 +360,18 @@ static bool radeon_fence_is_signaled(struct dma_fence *f) > if (atomic64_read(&rdev->fence_drv[ring].last_seq) >= seq) > return true; > > + /* > + * Poll hardware directly without updating last_seq. > + * This allows immediate detection of signaled fences (performance) > + * while leaving last_seq update and wake_up_all() to the interrupt > + * handler, avoiding: > + * 1. Deadlock from calling wake_up_all() with fence lock held > + * 2. Wake event stealing by advancing last_seq without waking waiters > + * 3. rw_semaphore usage in atomic/irq context (unsafe on PREEMPT_RT) > + */ > + if (radeon_fence_read(rdev, ring) >= (u32)seq) > + return true; > + That check is not correct, you need to take wrap around into account. Try using __dma_fence_is_later() instead. Regards, Christian. > return false; > } >