From 70d2e56aaee89ca8bea92e42a917e272eb7ad471 Mon Sep 17 00:00:00 2001 From: Rajeev Kumar Date: Thu, 11 Apr 2019 12:07:51 -0700 Subject: [PATCH] qcacld-3.0: Move os_if driver lock inside when doing driver trans wait Since os_if_driver_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_driver_sync_lock(a spin lock bh) inside sync calback API for driver look up such that spin lock is not held before starting the wait on event. os_if_driver_sync lock is for driver look up and not for wait and hence this fix makes locking fine granular as well. Change-Id: I32c582bedbbee81d3a5b171666fc3009c3dc7e5a CRs-Fixed: 2433825 --- os_if/sync/src/osif_driver_sync.c | 32 +++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/os_if/sync/src/osif_driver_sync.c b/os_if/sync/src/osif_driver_sync.c index 6207d8e5d361..d28bf64fcddb 100644 --- a/os_if/sync/src/osif_driver_sync.c +++ b/os_if/sync/src/osif_driver_sync.c @@ -199,6 +199,31 @@ __osif_driver_sync_start_callback(struct osif_driver_sync **out_driver_sync, return 0; } +static int +__osif_driver_sync_start_wait_callback( + struct osif_driver_sync **out_driver_sync, + const char *desc, + driver_start_func driver_start_cb) +{ + QDF_STATUS status; + struct osif_driver_sync *driver_sync; + + *out_driver_sync = NULL; + + osif_driver_sync_lock(); + driver_sync = osif_driver_sync_lookup(); + osif_driver_sync_unlock(); + if (!driver_sync) + return -EAGAIN; + + status = driver_start_cb(driver_sync->dsc_driver, desc); + if (QDF_IS_STATUS_ERROR(status)) + return qdf_status_to_os_return(status); + + *out_driver_sync = driver_sync; + + return 0; +} int __osif_driver_sync_trans_start(struct osif_driver_sync **out_driver_sync, const char *desc) { @@ -218,10 +243,9 @@ __osif_driver_sync_trans_start_wait(struct osif_driver_sync **out_driver_sync, { int errno; - osif_driver_sync_lock(); - errno = __osif_driver_sync_start_callback(out_driver_sync, desc, - dsc_driver_trans_start_wait); - osif_driver_sync_unlock(); + /* since dsc_driver_trans_start_wait may sleep do not take lock here */ + errno = __osif_driver_sync_start_wait_callback(out_driver_sync, desc, + dsc_driver_trans_start_wait); return errno; }