mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-24 02:01:36 +03:00
platform: dce: fix wait race condition
It is possible that we received the ACK from DCE even before we start waiting. But currently we are clearing the "complete" state before start waiting, which may result in missed interrupt. This patch removes the clearing of complete state before wait. Also Adds few comments for better understanding. Bug 3941557 Change-Id: I7d2efb1a64eb6f2d4df1876add07a8f019b449f5 Signed-off-by: Mahesh Kumar <mahkumar@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2845498 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: svc_kernel_abi <svc_kernel_abi@nvidia.com> Reviewed-by: Arun Swain <arswain@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com>
This commit is contained in:
committed by
Laxman Dewangan
parent
387a379024
commit
1258e71941
@@ -36,14 +36,23 @@ int dce_wait_interruptible(struct tegra_dce *d, u32 msg_id)
|
||||
}
|
||||
|
||||
wait = &d->ipc_waits[msg_id];
|
||||
atomic_set(&wait->complete, 0);
|
||||
|
||||
/*
|
||||
* It is possible that we received the ACK from DCE even before we
|
||||
* start waiting. But that should not be an issue as wait->complete
|
||||
* Will be "1" and we immediately exit from the wait.
|
||||
*/
|
||||
DCE_COND_WAIT_INTERRUPTIBLE(&wait->cond_wait,
|
||||
atomic_read(&wait->complete) == 1);
|
||||
|
||||
if (atomic_read(&wait->complete) != 1)
|
||||
return -EINTR;
|
||||
|
||||
/*
|
||||
* Clear wait->complete as soon as we exit from wait (consume the wake call)
|
||||
* So that when the next dce_wait_interruptible is called, it doesn't see old
|
||||
* wait->complete state.
|
||||
*/
|
||||
atomic_set(&wait->complete, 0);
|
||||
return 0;
|
||||
}
|
||||
@@ -67,6 +76,11 @@ void dce_wakeup_interruptible(struct tegra_dce *d, u32 msg_id)
|
||||
|
||||
wait = &d->ipc_waits[msg_id];
|
||||
|
||||
/*
|
||||
* Set wait->complete to "1", so if the wait is called even after
|
||||
* "dce_cond_signal_interruptible", it'll see the complete variable
|
||||
* as "1" and exit the wait immediately.
|
||||
*/
|
||||
atomic_set(&wait->complete, 1);
|
||||
dce_cond_signal_interruptible(&wait->cond_wait);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user