summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDARAM SUDHA <dsudha@qti.qualcomm.com>2014-06-19 17:04:01 +0530
committerAkash Patel <c_akashp@qca.qualcomm.com>2014-06-23 18:20:05 -0700
commita5a7941df798b16ae2aefe74aa0f48cdb3879ae9 (patch)
treec801faa5da3ad413637aedb72b6c5da9fa8d6ba4
parent1fccbda5cba8db929cf316c173a94d5368ff8b9a (diff)
fix to avoid Deadlock for between CE and HDD
in TXFlow control path, there is a deadlock between copy engine context and hdd_hard_start_xmit context for fc_lock and pdev->tx_mutex. Fixed by avoiding the lock. Change-Id: I33653f8aa6d02dc8262a918d56f6be3426d606e3 CRs-FIXED: 681646
-rw-r--r--CORE/CLD_TXRX/TLSHIM/tl_shim.c11
-rw-r--r--CORE/CLD_TXRX/TXRX/ol_tx_send.c5
2 files changed, 10 insertions, 6 deletions
diff --git a/CORE/CLD_TXRX/TLSHIM/tl_shim.c b/CORE/CLD_TXRX/TLSHIM/tl_shim.c
index 04662e79e801..210f37e34510 100644
--- a/CORE/CLD_TXRX/TLSHIM/tl_shim.c
+++ b/CORE/CLD_TXRX/TLSHIM/tl_shim.c
@@ -1943,6 +1943,7 @@ v_BOOL_t WLANTL_GetTxResource
{
struct txrx_tl_shim_ctx *tl_shim;
v_BOOL_t enough_resource = VOS_TRUE;
+ struct ol_txrx_vdev_t *vdev;
/* If low watermark is zero, TX flow control is not enabled at all
* return TRUE by default */
@@ -1965,13 +1966,13 @@ v_BOOL_t WLANTL_GetTxResource
adf_os_spin_unlock_bh(&tl_shim->session_flow_control[sessionId].fc_lock);
return VOS_TRUE;
}
-
- enough_resource = (v_BOOL_t)wdi_in_get_tx_resource(
- (struct ol_txrx_vdev_t *)tl_shim->session_flow_control[sessionId].vdev,
- low_watermark,
- high_watermark_offset);
+ vdev = (struct ol_txrx_vdev_t *)tl_shim->session_flow_control[sessionId].vdev;
adf_os_spin_unlock_bh(&tl_shim->session_flow_control[sessionId].fc_lock);
+ enough_resource = (v_BOOL_t)wdi_in_get_tx_resource(vdev,
+ low_watermark,
+ high_watermark_offset);
+
return enough_resource;
}
diff --git a/CORE/CLD_TXRX/TXRX/ol_tx_send.c b/CORE/CLD_TXRX/TXRX/ol_tx_send.c
index d0a3632c289c..7c8d02ef1f52 100644
--- a/CORE/CLD_TXRX/TXRX/ol_tx_send.c
+++ b/CORE/CLD_TXRX/TXRX/ol_tx_send.c
@@ -117,11 +117,14 @@ do {
if (adf_os_atomic_read(&vdev->os_q_paused)) { \
adf_os_spin_lock(&pdev->tx_mutex); \
if (pdev->tx_desc.num_free > vdev->tx_fl_hwm) { \
+ adf_os_spin_unlock(&pdev->tx_mutex); \
vdev->osif_flow_control_cb(vdev->osif_dev, \
vdev->vdev_id, A_TRUE); \
adf_os_atomic_set(&vdev->os_q_paused, 0); \
} \
- adf_os_spin_unlock(&pdev->tx_mutex); \
+ else { \
+ adf_os_spin_unlock(&pdev->tx_mutex); \
+ } \
} \
} \
} while(0)