From 9b0df8d2f0da7d7436e57cdaab055975581a1937 Mon Sep 17 00:00:00 2001 From: Vladimir Kondratyev Date: Sat, 24 Feb 2024 12:22:37 +0300 Subject: [PATCH] dma-fence-chain: Get previous fence in RCU-safe way Sponsored by: Serenity Cyber Security, LLC (cherry picked from commit fe1b787235d651612be3203d1c048ec9d308ddb1) --- drivers/dma-buf/dma-fence-chain.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/dma-buf/dma-fence-chain.c b/drivers/dma-buf/dma-fence-chain.c index 98ed08b3ec5..74ddfe197fb 100644 --- a/drivers/dma-buf/dma-fence-chain.c +++ b/drivers/dma-buf/dma-fence-chain.c @@ -158,7 +158,7 @@ dma_fence_chain_init(struct dma_fence_chain *chain, spin_lock_init(&chain->lock); chain->fence = fence; - chain->prev = prev; + rcu_assign_pointer(chain->prev, prev); prev_chain = to_dma_fence_chain(prev); if (prev_chain != NULL && __dma_fence_is_later(seqno, prev->seqno, prev->ops)) { @@ -195,6 +195,18 @@ dma_fence_chain_find_seqno(struct dma_fence **fence, uint64_t seqno) return (0); } +static struct dma_fence * +dma_fence_chain_get_prev(struct dma_fence_chain *chain) +{ + struct dma_fence *prev; + + rcu_read_lock(); + prev = dma_fence_get_rcu_safe(&chain->prev); + rcu_read_unlock(); + + return (prev); +} + struct dma_fence * dma_fence_chain_walk(struct dma_fence *fence) { @@ -206,11 +218,11 @@ dma_fence_chain_walk(struct dma_fence *fence) return (NULL); } - while ((prev = dma_fence_get(chain->prev)) != NULL) { + while ((prev = dma_fence_chain_get_prev(chain)) != NULL) { if ((prev_chain = to_dma_fence_chain(prev)) != NULL) { if (dma_fence_is_signaled(prev_chain->fence) == false) break; - new_prev = dma_fence_get(prev_chain->prev); + new_prev = dma_fence_chain_get_prev(prev_chain); } else { if (dma_fence_is_signaled(prev) == false) break;