Skip to content

Commit

Permalink
Revert "drm/qxl: simplify qxl_fence_wait"
Browse files Browse the repository at this point in the history
[ Upstream commit 07ed11a ]

This reverts commit 5a838e5.

Changes from commit 5a838e5 ("drm/qxl: simplify qxl_fence_wait") would
result in a '[TTM] Buffer eviction failed' exception whenever it reached a
timeout.
Due to a dependency to DMA_FENCE_WARN this also restores some code deleted
by commit d72277b ("dma-buf: nuke DMA_FENCE_TRACE macros v2").

Fixes: 5a838e5 ("drm/qxl: simplify qxl_fence_wait")
Link: https://lore.kernel.org/regressions/ZTgydqRlK6WX_b29@eldamar.lan/
Reported-by: Timo Lindfors <timo.lindfors@iki.fi>
Closes: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1054514
Signed-off-by: Alex Constantino <dreaming.about.electric.sheep@gmail.com>
Signed-off-by: Maxime Ripard <mripard@kernel.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20240404181448.1643-2-dreaming.about.electric.sheep@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
alexconst authored and gregkh committed Apr 17, 2024
1 parent 9bd1891 commit 42cbe04
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 5 deletions.
50 changes: 45 additions & 5 deletions drivers/gpu/drm/qxl/qxl_release.c
Expand Up @@ -58,16 +58,56 @@ static long qxl_fence_wait(struct dma_fence *fence, bool intr,
signed long timeout)
{
struct qxl_device *qdev;
struct qxl_release *release;
int count = 0, sc = 0;
bool have_drawable_releases;
unsigned long cur, end = jiffies + timeout;

qdev = container_of(fence->lock, struct qxl_device, release_lock);
release = container_of(fence, struct qxl_release, base);
have_drawable_releases = release->type == QXL_RELEASE_DRAWABLE;

if (!wait_event_timeout(qdev->release_event,
(dma_fence_is_signaled(fence) ||
(qxl_io_notify_oom(qdev), 0)),
timeout))
return 0;
retry:
sc++;

if (dma_fence_is_signaled(fence))
goto signaled;

qxl_io_notify_oom(qdev);

for (count = 0; count < 11; count++) {
if (!qxl_queue_garbage_collect(qdev, true))
break;

if (dma_fence_is_signaled(fence))
goto signaled;
}

if (dma_fence_is_signaled(fence))
goto signaled;

if (have_drawable_releases || sc < 4) {
if (sc > 2)
/* back off */
usleep_range(500, 1000);

if (time_after(jiffies, end))
return 0;

if (have_drawable_releases && sc > 300) {
DMA_FENCE_WARN(fence,
"failed to wait on release %llu after spincount %d\n",
fence->context & ~0xf0000000, sc);
goto signaled;
}
goto retry;
}
/*
* yeah, original sync_obj_wait gave up after 3 spins when
* have_drawable_releases is not set.
*/

signaled:
cur = jiffies;
if (time_after(cur, end))
return 0;
Expand Down
7 changes: 7 additions & 0 deletions include/linux/dma-fence.h
Expand Up @@ -681,4 +681,11 @@ static inline bool dma_fence_is_container(struct dma_fence *fence)
return dma_fence_is_array(fence) || dma_fence_is_chain(fence);
}

#define DMA_FENCE_WARN(f, fmt, args...) \
do { \
struct dma_fence *__ff = (f); \
pr_warn("f %llu#%llu: " fmt, __ff->context, __ff->seqno,\
##args); \
} while (0)

#endif /* __LINUX_DMA_FENCE_H */

0 comments on commit 42cbe04

Please sign in to comment.