On 11/4/26 23:18, Kirtikumar Anandrao Ramchandani wrote:
> The last dma_fence_put() can drop a sync point's reference count to
> zero before timeline_fence_release() acquires the timeline lock to
> remove it from pt_list. If sync_timeline_signal() acquires the lock in
> that window, dma_fence_get() attempts to increment a zero reference
> count and triggers a refcount warning.
> 
> Use dma_fence_get_rcu() to acquire the temporary signaling reference
> only if the fence is still referenced, as sync_pt_create() already
> does when looking up an existing point. Skip a point whose reference
> count has reached zero: its release callback will remove it from the
> list and tree once the timeline lock is released.
> 

> The timeline lock prevents the release callback from removing or
> freeing a listed point during this check. For a live point, retain the
> temporary reference until after dropping the lock, preserving the
> protection against recursive locking from signaling callbacks.

Please add this explanation as code comment to the patch.

> 
> Fixes: e531fdb5cd5e ("dma-buf/sw_sync: Avoid recursive lock during fence 
> signal")

Drop that here. SW_SYNC is a unit testing functionality which can intentionally 
crash the kernel.

You get literally tons of warnings and a tainted kernel when it is 
enabled/used. So bugs like those are generally not backported.

Apart from that the patch looks good to me,
Christian.

> Reported-by: [email protected] 
> <mailto:syzbot%[email protected]>
> Closes: https://syzkaller.appspot.com/bug?extid=cba1a1f459230395a076 
> <https://syzkaller.appspot.com/bug?extid=cba1a1f459230395a076>
> Signed-off-by: Kirtikumar Anandrao Ramchandani <[email protected] 
> <mailto:[email protected]>>
> ---
> 
>  drivers/dma-buf/sw_sync.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/dma-buf/sw_sync.c b/drivers/dma-buf/sw_sync.c
> index 8df20b0218a9..7f1eadee4cdf 100644
> --- a/drivers/dma-buf/sw_sync.c
> +++ b/drivers/dma-buf/sw_sync.c
> @@ -221,7 +221,8 @@
>                 if (!timeline_fence_signaled(&pt->base))
>                         break;
> 
> -               dma_fence_get(&pt->base);
> +               if (!dma_fence_get_rcu(&pt->base))
> +                       continue;
> 
>                 list_move_tail(&pt->link, &signalled);
>                 rb_erase(&pt->node, &obj->pt_tree);
> 
> base-commit: 05441d697f7f9a927264f4058cbbc6a03dfcac9d

Reply via email to