From 5bdb69bd913a83fb57b9d4af03a7ed2ac6bdd0c5 Mon Sep 17 00:00:00 2001 From: Srinivas Pitla Date: Wed, 24 May 2017 18:10:07 +0530 Subject: [PATCH] qcacmn: Avoid deadlock with pdev lock The locks have to be taken by the caller. Handling inside inline APIs are causing deadlock in few paths due to order of the locks. With these locks the order is missing. PDEV lock should be taken prior to vdev lock, and psoc lock should be taken before taking pdev lock, same for peer and vdev locks also. taking the locks other order would cause deadlock Change-Id: I23d83329a0752981974726454d9e1bc1cfd1398f CRs-Fixed: 2022458 --- umac/cmn_services/obj_mgr/inc/wlan_objmgr_cmn.h | 4 ++-- umac/cmn_services/obj_mgr/inc/wlan_objmgr_pdev_obj.h | 8 ++++++-- umac/cmn_services/obj_mgr/inc/wlan_objmgr_peer_obj.h | 3 +++ umac/cmn_services/obj_mgr/inc/wlan_objmgr_psoc_obj.h | 3 +++ umac/cmn_services/obj_mgr/inc/wlan_objmgr_vdev_obj.h | 5 +++-- 5 files changed, 17 insertions(+), 6 deletions(-) diff --git a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_cmn.h b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_cmn.h index df4a0a30d2a3..37315a69098b 100644 --- a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_cmn.h +++ b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_cmn.h @@ -226,7 +226,7 @@ typedef enum { */ static inline char *string_from_dbgid(wlan_objmgr_ref_dbgid id) { - static const char *strings[] = { "WLAN_OBJMGR_ID", + static const char *strings[] = { "WLAN_OBJMGR_ID", "WLAN_MLME_SB_ID", "WLAN_MLME_NB_ID", "WLAN_MGMT_SB_ID", @@ -253,7 +253,7 @@ static inline char *string_from_dbgid(wlan_objmgr_ref_dbgid id) "WLAN_SPECTRAL_ID", "WLAN_REF_ID_MAX" }; - return (char *)strings[id]; + return (char *)strings[id]; } #ifdef WLAN_OBJMGR_DEBUG diff --git a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_pdev_obj.h b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_pdev_obj.h index dfa0cc16047b..fe9df38593bd 100644 --- a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_pdev_obj.h +++ b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_pdev_obj.h @@ -195,7 +195,7 @@ struct wlan_objmgr_pdev { * Failure) */ struct wlan_objmgr_pdev *wlan_objmgr_pdev_obj_create( - struct wlan_objmgr_psoc *psoc, struct pdev_osif_priv *osif_priv); + struct wlan_objmgr_psoc *psoc, struct pdev_osif_priv *osif_priv); /** * wlan_objmgr_pdev_obj_delete() - pdev delete @@ -394,6 +394,9 @@ void *wlan_objmgr_pdev_get_comp_private_obj( * @pdev: PDEV object * * API to acquire PDEV lock + * Parent lock should not be taken in child lock context + * but child lock can be taken in parent lock context + * (for ex: psoc lock can't be invoked in pdev/vdev/peer lock context) * * Return: void */ @@ -608,7 +611,8 @@ static inline void wlan_pdev_set_hw_macaddr(struct wlan_objmgr_pdev *pdev, * * Return: ospriv - private pointer */ -static inline struct pdev_osif_priv *wlan_pdev_get_ospriv(struct wlan_objmgr_pdev *pdev) +static inline struct pdev_osif_priv *wlan_pdev_get_ospriv( + struct wlan_objmgr_pdev *pdev) { /* This API is invoked with lock acquired, do not add log prints */ return pdev->pdev_nif.pdev_ospriv; diff --git a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_peer_obj.h b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_peer_obj.h index 8a52c6fa1300..e052bcdb1b05 100644 --- a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_peer_obj.h +++ b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_peer_obj.h @@ -310,6 +310,9 @@ void *wlan_objmgr_peer_get_comp_private_obj( * @psoc: PEER object * * API to acquire PEER spin lock + * Parent lock should not be taken in child lock context + * but child lock can be taken in parent lock context + * (for ex: psoc lock can't be invoked in pdev/vdev/peer lock context) * * Return: void */ diff --git a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_psoc_obj.h b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_psoc_obj.h index 2d2061884850..3e038d45bef3 100644 --- a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_psoc_obj.h +++ b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_psoc_obj.h @@ -728,6 +728,9 @@ struct wlan_objmgr_vdev *wlan_objmgr_get_vdev_by_macaddr_from_psoc_no_state( * @psoc: PSOC object * * API to acquire PSOC lock + * Parent lock should not be taken in child lock context + * but child lock can be taken in parent lock context + * (for ex: psoc lock can't be invoked in pdev/vdev/peer lock context) * * Return: void */ diff --git a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_vdev_obj.h b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_vdev_obj.h index 8168e4178928..11b998451476 100644 --- a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_vdev_obj.h +++ b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_vdev_obj.h @@ -604,9 +604,7 @@ static inline struct wlan_objmgr_psoc *wlan_vdev_get_psoc( if (pdev == NULL) return NULL; - wlan_pdev_obj_lock(pdev); psoc = wlan_pdev_get_psoc(pdev); - wlan_pdev_obj_unlock(pdev); return psoc; } @@ -820,6 +818,9 @@ static inline QDF_STATUS wlan_vdev_mlme_get_ssid( * @vdev: VDEV object * * API to acquire VDEV lock + * Parent lock should not be taken in child lock context + * but child lock can be taken in parent lock context + * (for ex: psoc lock can't be invoked in pdev/vdev/peer lock context) * * Return: void */