In nvavp_pushbuffer_update(), we acquire channel_info->pushbuffer_lock first
then nvavp->open_lock. While in clock_disable_handler(), open_lock is acquired
before pushbuffer_lock, causing the deadlock if clock_disable_work happens to
be executing while running nvavp_pushbuffer_update().
This change reorder the locks in clock_disable_handler to avoid deadlock issue.
And also in tegra_nvavp_release(), need to release nvavp->open_lock first before
calling nvavp_uninit(), since nvavp_uninit() need to cancel clock_disable_work
in a synchronous manner.
Bug
200013513
Change-Id: I42082a97cc4e311a4141559f8a56c7c1eeb97eb2
Signed-off-by: Allen Yu <alleny@nvidia.com>
Reviewed-on: http://git-master/r/433523
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Reviewed-by: Soumenkumar Dey <sdey@nvidia.com>
Reviewed-by: Mandar Potdar <mpotdar@nvidia.com>
Tested-by: Yogesh Solanke <ysolanke@nvidia.com>
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
Reviewed-by: Somu Sundaram <somasundarams@nvidia.com>
clock_disable_work);
channel_info = nvavp_get_channel_info(nvavp, NVAVP_VIDEO_CHANNEL);
- mutex_lock(&nvavp->open_lock);
mutex_lock(&channel_info->pushbuffer_lock);
+ mutex_lock(&nvavp->open_lock);
if (nvavp_check_idle(nvavp, NVAVP_VIDEO_CHANNEL) && nvavp->pending) {
nvavp->pending = false;
nvavp_clks_disable(nvavp);
if (nvavp->refcount > 0)
nvavp->refcount--;
- if (!nvavp->refcount)
+ if (!nvavp->refcount) {
+ mutex_unlock(&nvavp->open_lock);
nvavp_uninit(nvavp);
+ mutex_lock(&nvavp->open_lock);
+ }
if (IS_VIDEO_CHANNEL_ID(channel_id))
nvavp->video_refcnt--;