mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-08 12:58:12 -04:00
msm: pci : Avoid deadlock with recovery and enemurate lock
Avoid deadlock scenario when wake interrupt arrives at enumeration time and holds recovery lock and wake handler workqueue tries to acquire enumeration lock. In parallel client driver can call msm_pcie_pm_control for suspend where enumeration lock could be successfully acquired by msm_pcie_pm_control instead by wake handler and waiting for recovery lock which is currently acquired by wake handler (which is currently waiting for enumertion lock) which could leads to deadlock scenario. msm_pcie_enumerate wake handler pm_control | | (suspend thread) | | | | x acquired | x acquired | recovery lock | | enumerate lock | | | o waiting for | | enumerate lock | x released x acquired | enumerate lock | enumerate lock | o waiting for recovery lock we have fixed the order of locking in msm_pcie_pm_control to avoid deadlock scenario. Change-Id: Ifc72c643f7c0793cfa10a953723e953ce73a82b6 Signed-off-by: Vivek Pernamitta <vpernami@codeaurora.org>
This commit is contained in:
parent
774e901388
commit
3bb65a0c8c
1 changed files with 7 additions and 4 deletions
|
|
@ -7898,6 +7898,7 @@ int msm_pcie_pm_control(enum msm_pcie_pm_opt pm_opt, u32 busnr, void *user,
|
|||
break;
|
||||
}
|
||||
|
||||
mutex_lock(&pcie_dev->recovery_lock);
|
||||
mutex_lock(&pcie_dev->enumerate_lock);
|
||||
|
||||
/*
|
||||
|
|
@ -7928,12 +7929,12 @@ int msm_pcie_pm_control(enum msm_pcie_pm_opt pm_opt, u32 busnr, void *user,
|
|||
"PCIe: RC%d: request to suspend the link is rejected\n",
|
||||
pcie_dev->rc_idx);
|
||||
mutex_unlock(&pcie_dev->enumerate_lock);
|
||||
mutex_unlock(&pcie_dev->recovery_lock);
|
||||
break;
|
||||
}
|
||||
|
||||
pcie_dev->user_suspend = true;
|
||||
|
||||
mutex_lock(&pcie_dev->recovery_lock);
|
||||
|
||||
ret = msm_pcie_pm_suspend(dev, user, data, options);
|
||||
if (ret) {
|
||||
|
|
@ -7949,9 +7950,9 @@ int msm_pcie_pm_control(enum msm_pcie_pm_opt pm_opt, u32 busnr, void *user,
|
|||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&pcie_dev->recovery_lock);
|
||||
|
||||
mutex_unlock(&pcie_dev->enumerate_lock);
|
||||
|
||||
mutex_unlock(&pcie_dev->recovery_lock);
|
||||
break;
|
||||
case MSM_PCIE_RESUME:
|
||||
PCIE_DBG(pcie_dev,
|
||||
|
|
@ -7964,6 +7965,8 @@ int msm_pcie_pm_control(enum msm_pcie_pm_opt pm_opt, u32 busnr, void *user,
|
|||
break;
|
||||
}
|
||||
|
||||
mutex_lock(&pcie_dev->recovery_lock);
|
||||
|
||||
/* when link was suspended and link resume is requested */
|
||||
mutex_lock(&pcie_dev->enumerate_lock);
|
||||
list_for_each_entry(dev_info_itr, &pcie_dev->susp_ep_list,
|
||||
|
|
@ -7990,10 +7993,10 @@ int msm_pcie_pm_control(enum msm_pcie_pm_opt pm_opt, u32 busnr, void *user,
|
|||
PCIE_ERR(pcie_dev,
|
||||
"PCIe: RC%d: requested to resume when link is already powered on.\n",
|
||||
pcie_dev->rc_idx);
|
||||
mutex_unlock(&pcie_dev->recovery_lock);
|
||||
break;
|
||||
}
|
||||
|
||||
mutex_lock(&pcie_dev->recovery_lock);
|
||||
ret = msm_pcie_pm_resume(dev, user, data, options);
|
||||
if (ret) {
|
||||
PCIE_ERR(pcie_dev,
|
||||
|
|
|
|||
Loading…
Reference in a new issue