From 4b436bcbc3c0ac10bc5f8b41709c0c460f5da1cf Mon Sep 17 00:00:00 2001 From: Ashish Kumar Dhanotiya Date: Thu, 16 Jul 2020 00:46:41 +0530 Subject: [PATCH] qcacld-3.0: Do not block vdev trans if recovery in progress Currently if SSR happens and at the same time if driver gets del virtual interface which is a vdev transition, it bloks this vdev transition and queues into dsc queue assuming that it will execute once SSR completes. There is an issue with above assumption, del virtual interface comes with rtnl lock held which may lead for other processes to misbehave which are waiting for rtnl lock. in current case kernel is waiting for rtnl lock to send shutdown to driver as part of the SSR and this rtnl lock is held by del virtual interface which is waiting inside dsc queue for SSR to complete, this leads to the deadlock. To address above issue, do not insert the vdev transintion in dsc queue in case of SSR and return the failure instead. Change-Id: I19c897d68086d885f340d35c686badb70601076a CRs-Fixed: 2730903 --- components/dsc/src/wlan_dsc_vdev.c | 2 +- components/dsc/test/wlan_dsc_test.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/components/dsc/src/wlan_dsc_vdev.c b/components/dsc/src/wlan_dsc_vdev.c index afd3c2c0c66e..b045ffd53334 100644 --- a/components/dsc/src/wlan_dsc_vdev.c +++ b/components/dsc/src/wlan_dsc_vdev.c @@ -139,7 +139,7 @@ static QDF_STATUS __dsc_vdev_can_trans(struct dsc_vdev *vdev) return QDF_STATUS_E_INVAL; if (qdf_is_recovering()) - return QDF_STATUS_E_AGAIN; + return QDF_STATUS_E_INVAL; if (__dsc_trans_active_or_queued(&vdev->psoc->trans)) { /* psoc idle shutdown(wifi off) needs to be added in DSC queue diff --git a/components/dsc/test/wlan_dsc_test.c b/components/dsc/test/wlan_dsc_test.c index 20c74d04618f..3354e0d1c1eb 100644 --- a/components/dsc/test/wlan_dsc_test.c +++ b/components/dsc/test/wlan_dsc_test.c @@ -284,8 +284,8 @@ static uint32_t dsc_test_psoc_trans_blocks(void) */ cds_set_recovery_in_progress(true); dsc_for_each_psoc_vdev(psoc, vdev) { - action_expect(vdev, trans, QDF_STATUS_E_AGAIN, errors); - action_expect(vdev, op, QDF_STATUS_E_AGAIN, errors); + action_expect(vdev, trans, QDF_STATUS_E_INVAL, errors); + action_expect(vdev, op, QDF_STATUS_E_INVAL, errors); } cds_set_recovery_in_progress(false);