diff options
author | Dave Airlie <airlied@redhat.com> | 2024-12-04 09:13:03 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2024-12-04 09:13:09 +1000 |
commit | defc06f7ef163b64cff11990e8847bc225bcdd46 (patch) | |
tree | 00bf3ba8d87c6720ba1f7de62ce6ef4dd0c5c371 /drivers/dma-buf | |
parent | 8cc4d0f0f2b1c59f7dd1738deb246da9de1ada0f (diff) | |
parent | 86e8f94789dd6f3e705bfa821e1e416f97a2f863 (diff) |
Merge tag 'drm-misc-fixes-2024-11-28' of https://gitlab.freedesktop.org/drm/misc/kernel into drm-fixes
Short summary of fixes pull:
dma-buf:
- Fix dma_fence_array_signaled() to ensure forward progress
dp_mst:
- Fix MST sideband message body length check
sti:
- Add __iomem for mixer_dbg_mxn()'s parameter
Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patchwork.freedesktop.org/patch/msgid/20241128135958.GA244627@linux.fritz.box
Diffstat (limited to 'drivers/dma-buf')
-rw-r--r-- | drivers/dma-buf/dma-fence-array.c | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/drivers/dma-buf/dma-fence-array.c b/drivers/dma-buf/dma-fence-array.c index 8a08ffde31e7..6657d4b30af9 100644 --- a/drivers/dma-buf/dma-fence-array.c +++ b/drivers/dma-buf/dma-fence-array.c @@ -103,10 +103,36 @@ static bool dma_fence_array_enable_signaling(struct dma_fence *fence) static bool dma_fence_array_signaled(struct dma_fence *fence) { struct dma_fence_array *array = to_dma_fence_array(fence); + int num_pending; + unsigned int i; - if (atomic_read(&array->num_pending) > 0) + /* + * We need to read num_pending before checking the enable_signal bit + * to avoid racing with the enable_signaling() implementation, which + * might decrement the counter, and cause a partial check. + * atomic_read_acquire() pairs with atomic_dec_and_test() in + * dma_fence_array_enable_signaling() + * + * The !--num_pending check is here to account for the any_signaled case + * if we race with enable_signaling(), that means the !num_pending check + * in the is_signalling_enabled branch might be outdated (num_pending + * might have been decremented), but that's fine. The user will get the + * right value when testing again later. + */ + num_pending = atomic_read_acquire(&array->num_pending); + if (test_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, &array->base.flags)) { + if (num_pending <= 0) + goto signal; return false; + } + + for (i = 0; i < array->num_fences; ++i) { + if (dma_fence_is_signaled(array->fences[i]) && !--num_pending) + goto signal; + } + return false; +signal: dma_fence_array_clear_pending_error(array); return true; } |