drm/msm/sde: avoid spinlock recursion in sde fence

The sde fence driver signals the fence with spinlock
acquired because it wants to protect the linked list
containing all fence objects. The dma fence_array
driver always calls the fence_put once fence is signaled
in the caller context itself. This fence_put call may
be translated into fence_release if no other client
has registered for the current fence object. The release
call will again trigger the sde_fence_release and tries
to acquired the same spinlock to protect the list. This
change separates the "timeline + fence" lock and list lock
to avoid holding it during fence_signal call. Just refer
below callstack for recursion case.

spin_bug+0x90/0xb4
do_raw_spin_lock+0xcc/0x1bc
_raw_spin_lock_irqsave+0x34/0x44
sde_fence_release+0x30/0x104
fence_release+0x54/0xf8
fence_array_release+0x80/0xb4
fence_release+0x54/0xf8
fence_array_cb_func+0x68/0x80
fence_signal_locked+0x80/0x170
sde_fence_signal+0x1ac/0x2a8
sde_crtc_complete_commit+0x64/0xb8
sde_kms_complete_commit+0x74/0xd0
complete_commit+0x324/0x404
_msm_drm_commit_work_cb+0x24/0x5c
kthread_worker_fn+0xc4/0x1e8
kthread+0xfc/0x110
ret_from_fork+0x10/0x40

Change-Id: I87ab33214e5828dda0b89e8d5c339f54917cfc0f
Signed-off-by: Dhaval Patel <pdhaval@codeaurora.org>
2 files changed