From 2e0103145d1137939171a95a58c13c1e541d3c86 Mon Sep 17 00:00:00 2001 From: Hemant Kumar Date: Mon, 9 Nov 2020 16:59:28 -0800 Subject: [PATCH] pci: msm: Move rpmsg lock after command completion If multiple rpmsg are sent, it is possible there will be a mismatch of completions. If requester sends rpmsg A and B, it is possible the completer sees only rpmsg B. Once completer sends ACK/NACK for rpmsg B, the requester may interpret, it is for rpmsg A if the timeout for it has not expired. Therefore, serialize the send of rpmsg and its completion to avoid this possible race by moving rpmsg lock after command completion. Change-Id: Id2ac8a03da2dd941ac9ea9d5c556a108af5faecd Signed-off-by: Hemant Kumar --- drivers/pci/controller/pci-msm.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/pci/controller/pci-msm.c b/drivers/pci/controller/pci-msm.c index 3a4059d69da0..57f71641abb2 100644 --- a/drivers/pci/controller/pci-msm.c +++ b/drivers/pci/controller/pci-msm.c @@ -6741,8 +6741,8 @@ static int msm_pcie_drv_send_rpmsg(struct msm_pcie_dev_t *pcie_dev, mutex_lock(&pcie_drv.rpmsg_lock); if (!pcie_drv.rpdev) { - mutex_unlock(&pcie_drv.rpmsg_lock); - return -EIO; + ret = -EIO; + goto out; } reinit_completion(&drv_info->completion); @@ -6760,10 +6760,8 @@ static int msm_pcie_drv_send_rpmsg(struct msm_pcie_dev_t *pcie_dev, if (ret) { PCIE_ERR(pcie_dev, "PCIe: RC%d: DRV: failed to send rpmsg\n", pcie_dev->rc_idx); - mutex_unlock(&pcie_drv.rpmsg_lock); - return ret; + goto out; } - mutex_unlock(&pcie_drv.rpmsg_lock); ret = wait_for_completion_timeout(&drv_info->completion, msecs_to_jiffies(drv_info->timeout_ms)); @@ -6771,13 +6769,19 @@ static int msm_pcie_drv_send_rpmsg(struct msm_pcie_dev_t *pcie_dev, PCIE_ERR(pcie_dev, "PCIe: RC%d: DRV: completion timeout for rpmsg\n", pcie_dev->rc_idx); - return -ETIMEDOUT; + ret = -ETIMEDOUT; + goto out; } + ret = 0; + PCIE_DBG(pcie_dev, "PCIe: RC%d: DRV: rpmsg successfully sent\n", pcie_dev->rc_idx); - return 0; +out: + mutex_unlock(&pcie_drv.rpmsg_lock); + + return ret; } static int msm_pcie_drv_resume(struct msm_pcie_dev_t *pcie_dev)