Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Reapply "drm/qxl: simplify qxl_fence_wait"

This reverts commit 07ed11afb68d94eadd4ffc082b97c2331307c5ea.

Stephen Rostedt reports:
"I went to run my tests on my VMs and the tests hung on boot up.
Unfortunately, the most I ever got out was:

[ 93.607888] Testing event system initcall: OK
[ 93.667730] Running tests on all trace events:
[ 93.669757] Testing all events: OK
[ 95.631064] ------------[ cut here ]------------
Timed out after 60 seconds"

and further debugging points to a possible circular locking dependency
between the console_owner locking and the worker pool locking.

Reverting the commit allows Steve's VM to boot to completion again.

[ This may obviously result in the "[TTM] Buffer eviction failed"
messages again, which was the reason for that original revert. But at
this point this seems preferable to a non-booting system... ]

Reported-and-bisected-by: Steven Rostedt <rostedt@goodmis.org>
Link: https://lore.kernel.org/all/20240502081641.457aa25f@gandalf.local.home/
Acked-by: Maxime Ripard <mripard@kernel.org>
Cc: Alex Constantino <dreaming.about.electric.sheep@gmail.com>
Cc: Maxime Ripard <mripard@kernel.org>
Cc: Timo Lindfors <timo.lindfors@iki.fi>
Cc: Dave Airlie <airlied@redhat.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: Daniel Vetter <daniel@ffwll.ch>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

+5 -52
+5 -45
drivers/gpu/drm/qxl/qxl_release.c
··· 58 58 signed long timeout) 59 59 { 60 60 struct qxl_device *qdev; 61 - struct qxl_release *release; 62 - int count = 0, sc = 0; 63 - bool have_drawable_releases; 64 61 unsigned long cur, end = jiffies + timeout; 65 62 66 63 qdev = container_of(fence->lock, struct qxl_device, release_lock); 67 - release = container_of(fence, struct qxl_release, base); 68 - have_drawable_releases = release->type == QXL_RELEASE_DRAWABLE; 69 64 70 - retry: 71 - sc++; 65 + if (!wait_event_timeout(qdev->release_event, 66 + (dma_fence_is_signaled(fence) || 67 + (qxl_io_notify_oom(qdev), 0)), 68 + timeout)) 69 + return 0; 72 70 73 - if (dma_fence_is_signaled(fence)) 74 - goto signaled; 75 - 76 - qxl_io_notify_oom(qdev); 77 - 78 - for (count = 0; count < 11; count++) { 79 - if (!qxl_queue_garbage_collect(qdev, true)) 80 - break; 81 - 82 - if (dma_fence_is_signaled(fence)) 83 - goto signaled; 84 - } 85 - 86 - if (dma_fence_is_signaled(fence)) 87 - goto signaled; 88 - 89 - if (have_drawable_releases || sc < 4) { 90 - if (sc > 2) 91 - /* back off */ 92 - usleep_range(500, 1000); 93 - 94 - if (time_after(jiffies, end)) 95 - return 0; 96 - 97 - if (have_drawable_releases && sc > 300) { 98 - DMA_FENCE_WARN(fence, 99 - "failed to wait on release %llu after spincount %d\n", 100 - fence->context & ~0xf0000000, sc); 101 - goto signaled; 102 - } 103 - goto retry; 104 - } 105 - /* 106 - * yeah, original sync_obj_wait gave up after 3 spins when 107 - * have_drawable_releases is not set. 108 - */ 109 - 110 - signaled: 111 71 cur = jiffies; 112 72 if (time_after(cur, end)) 113 73 return 0;
-7
include/linux/dma-fence.h
··· 682 682 return dma_fence_is_array(fence) || dma_fence_is_chain(fence); 683 683 } 684 684 685 - #define DMA_FENCE_WARN(f, fmt, args...) \ 686 - do { \ 687 - struct dma_fence *__ff = (f); \ 688 - pr_warn("f %llu#%llu: " fmt, __ff->context, __ff->seqno,\ 689 - ##args); \ 690 - } while (0) 691 - 692 685 #endif /* __LINUX_DMA_FENCE_H */