From 60a34715cfb23c90137cbdf6e278345e074cf070 Mon Sep 17 00:00:00 2001 From: Rajeev Kumar Date: Wed, 10 Apr 2019 19:12:20 -0700 Subject: [PATCH] qcacld-3.0: Move os_if psoc locking inside when doing psoc trans wait Since os_if_psoc_trans_wait may sleep on a wait event if there is any active ongoing transition on driver, psoc or vdevs. Hence move the os_if_psoc_sync_lock(a spin lock bh) inside sync calback API for psoc look up such that spin lock is not held before starting the wait on event. os_if_psoc_sync lock is for psoc look up and not for wait and hence this fix makes locking fine granular as well. Change-Id: I0537604337a6b594be3e7dc34dc97b79d5987ad4 CRs-Fixed: 2433409 --- os_if/sync/src/osif_psoc_sync.c | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/os_if/sync/src/osif_psoc_sync.c b/os_if/sync/src/osif_psoc_sync.c index e2a0e2707cb8..71ca1eb12a1b 100644 --- a/os_if/sync/src/osif_psoc_sync.c +++ b/os_if/sync/src/osif_psoc_sync.c @@ -220,6 +220,32 @@ __osif_psoc_sync_start_callback(struct device *dev, return 0; } +static int +__osif_psoc_sync_start_wait_callback(struct device *dev, + struct osif_psoc_sync **out_psoc_sync, + const char *desc, + psoc_start_func psoc_start_cb) +{ + QDF_STATUS status; + struct osif_psoc_sync *psoc_sync; + + *out_psoc_sync = NULL; + + osif_psoc_sync_lock(); + psoc_sync = osif_psoc_sync_lookup(dev); + osif_psoc_sync_unlock(); + if (!psoc_sync) + return -EAGAIN; + + status = psoc_start_cb(psoc_sync->dsc_psoc, desc); + if (QDF_IS_STATUS_ERROR(status)) + return qdf_status_to_os_return(status); + + *out_psoc_sync = psoc_sync; + + return 0; +} + int __osif_psoc_sync_trans_start(struct device *dev, struct osif_psoc_sync **out_psoc_sync, const char *desc) @@ -240,10 +266,9 @@ int __osif_psoc_sync_trans_start_wait(struct device *dev, { int errno; - osif_psoc_sync_lock(); - errno = __osif_psoc_sync_start_callback(dev, out_psoc_sync, desc, - dsc_psoc_trans_start_wait); - osif_psoc_sync_unlock(); + /* since dsc_psoc_trans_start_wait may sleep do not take lock here */ + errno = __osif_psoc_sync_start_wait_callback(dev, out_psoc_sync, desc, + dsc_psoc_trans_start_wait); return errno; }